Sobes.tech
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)

Предимства:

  • Изолира кода за изграждане на обекта от клиентския код.
  • Позволява да се променя вътрешното представяне на продукта без да се променя клиентският код.
  • Позволява стъпково изграждане на обекта.
  • Улеснява създаването на обекти с голям брой параметри.

Недостатъци:

  • Увеличава броя на класовете/интерфейсите за създаване на обекта.
  • Може да бъде излишен за прости обекти.