Junior
What design patterns are you familiar with?
sobes.tech AI
Answer from AI
- Creational: Create objects.
- Factory Method
- Abstract Factory
- Builder
- Prototype
- Singleton
- Structural: Form structures of classes and objects.
- Adapter
- Bridge
- Composite
- Decorator
- Facade
- Flyweight
- Proxy
- Behavioral: Define algorithms and ways objects interact.
- Chain of Responsibility
- Command
- Iterator
- Mediator
- Memento
- Observer
- State
- Strategy
- Template Method
- Visitor
In my practice, I often use Factory Method for creating objects based on criteria, Builder for step-by-step construction of complex objects, Singleton for unique instances, Adapter for interface compatibility, Decorator for extending functionality, Facade for simplifying subsystem interfaces, Observer for reactive systems, and Strategy for algorithm selection.
Example of the "Factory Method" pattern in Golang:
package main
import "fmt"
type Vehicle interface {
Drive()
}
type Car struct{}
func (c Car) Drive() {
fmt.Println("Driving a car")
}
type Bike struct{}
func (b Bike) Drive() {
fmt.Println("Riding a bike")
}
func NewVehicle(vehicleType string) Vehicle {
switch vehicleType {
case "car":
return Car{}
case "bike":
return Bike{}
default:
return nil
}
}
func main() {
car := NewVehicle("car")
bike := NewVehicle("bike")
car.Drive()
bike.Drive()
}
Example of the "Decorator" pattern in Golang:
package main
import "fmt"
type Coffee interface {
Cost() float64
Description() string
}
type SimpleCoffee struct{}
func (s SimpleCoffee) Cost() float64 {
return 1.0
}
func (s SimpleCoffee) Description() string {
return "Simple Coffee"
}
type MilkDecorator struct {
coffee Coffee
}
func (m MilkDecorator) Cost() float64 {
return m.coffee.Cost() + 0.5
}
func (m MilkDecorator) Description() string {
return m.coffee.Description() + ", Milk"
}
type SugarDecorator struct {
coffee Coffee
}
func (s SugarDecorator) Cost() float64 {
return s.coffee.Cost() + 0.2
}
func (s SugarDecorator) Description() string {
return s.coffee.Description() + ", Sugar"
}
func main() {
coffee := SimpleCoffee{}
milkCoffee := MilkDecorator{coffee: coffee}
milkSugarCoffee := SugarDecorator{coffee: milkCoffee}
fmt.Printf("Cost: %.2f, Description: %s\n", milkSugarCoffee.Cost(), milkSugarCoffee.Description())
}
It is important not only to know patterns but also to understand when to apply them so that the solution is optimal and maintainable.