Middle
Разкажете за патерна за проектиране 'Изграждател'.
sobes.tech AI
Отговор от AI
Патърнът за дизайн "Строител" (Builder) е създаващ патърн, който позволява създаването на сложни обекти стъпка по стъпка. Той отделя процеса на конструиране на сложен обект от неговото представяне, така че един и същ процес на строителство може да създава различни представяния.
Основни компоненти:
- Строител (Builder): Интерфейс или абстрактен клас, който определя методите за създаване на части от сложен обект.
- Конкретен Строител (Concrete Builder): Реализира интерфейса на Строителя и предоставя конкретна реализация за изграждане на части от обекта. Той съхранява междинния резултат и предоставя метод за получаване на готовия продукт.
- Директор (Director): Не е задължителен компонент. Определя реда на извикване на методите на строителя за създаване на обекта. Не знае за конкретните строители.
- Продукт (Product): Сложен обект, който се създава от строителя.
Приложение:
- Когато процесът на създаване на обект е сложен и включва множество опционални стъпки.
- Когато е необходимо да се създават различни представяния на един и същ обект, използвайки един и същ процес на строителство.
- Когато конструкторът на обекта има голям брой параметри.
Пример на Go:
// Product - сложен обект
type Product struct {
PartA string
PartB string
PartC string
}
// Builder - интерфейс
type Builder interface {
BuildPartA()
BuildPartB()
BuildPartC()
GetProduct() *Product
}
// ConcreteBuilder - конкретен строител
type ConcreteBuilder struct {
product *Product
}
func NewConcreteBuilder() *ConcreteBuilder {
return &ConcreteBuilder{product: &Product{}}
}
func (cb *ConcreteBuilder) BuildPartA() {
cb.product.PartA = "Част A е построена"
}
func (cb *ConcreteBuilder) BuildPartB() {
cb.product.PartB = "Част B е построена"
}
func (cb *ConcreteBuilder) BuildPartC() {
cb.product.PartC = "Част C е построена"
}
func (cb *ConcreteBuilder) GetProduct() *Product {
return cb.product
}
// Director - директор (по избор)
type Director struct {
builder Builder
}
func NewDirector(builder Builder) *Director {
return &Director{builder: builder}
}
func (d *Director) Construct() {
d.builder.BuildPartA()
d.builder.BuildPartB()
d.builder.BuildPartC()
}
// Използване
// concreteBuilder := NewConcreteBuilder()
// director := NewDirector(concreteBuilder)
// director.Construct()
// product := concreteBuilder.GetProduct()
// fmt.Printf("Създаденият продукт: %+v\n", product)
Предимства:
- Изолира кода за изграждане на обекта от клиентския код.
- Позволява да се променя вътрешното представяне на продукта без да се променя клиентският код.
- Позволява стъпково изграждане на обекта.
- Улеснява създаването на обекти с голям брой параметри.
Недостатъци:
- Увеличава броя на класовете/интерфейсите за създаване на обекта.
- Може да бъде излишен за прости обекти.