Создание сложных объектов с множеством необязательных параметров может оказаться непростой задачей.
Традиционный подход конструктора и установщика может стать громоздким при работе с объектами со многими необязательными параметрами.
В этой статье мы рассмотрим шаблон построителя, порождающий шаблон проектирования, который позволяет создавать сложные объекты с множеством необязательных параметров.
Мы рассмотрим пример реализации шаблона построителя в Go и обсудим, как его можно использовать для создания различных вариантов одного и того же объекта.
+----------------+ +-------------------+ | Director | directs | Builder | +----------------+ +-------------------+ | construct() | ------------> | buildPart1() | | setBuilder() | | buildPart2() | +----------------+ | getProduct() | +-------------------+ | V +-------------------+ | Product | +-------------------+ | field1 | | field2 | | ... | +-------------------+
Реализация шаблона Builder в Go
Вот пример шаблона построителя в golang
type Car struct { Make string Model string Year int Color string EngineSize float64 } type CarBuilder struct { Car } func (cb *CarBuilder) SetMake(make string) *CarBuilder { cb.Make = make return cb } func (cb *CarBuilder) SetModel(model string) *CarBuilder { cb.Model = model return cb } func (cb *CarBuilder) SetYear(year int) *CarBuilder { cb.Year = year return cb } func (cb *CarBuilder) SetColor(color string) *CarBuilder { cb.Color = color return cb } func (cb *CarBuilder) SetEngineSize(engineSize float64) *CarBuilder { cb.EngineSize = engineSize return cb } func (cb *CarBuilder) Build() *Car { return &cb.Car }
Структура CarBuilder
включает в себя объект Car
, поэтому все его поля доступны построителю.
Структура CarBuilder
имеет методы для установки необязательных параметров объекта Car
. Каждый метод возвращает указатель на структуру CarBuilder
, чтобы обеспечить цепочку методов.
Метод Build
структуры CarBuilder
возвращает указатель на созданный объект Car
.
Вот пример использования CarBuilder
:
carBuilder := &CarBuilder{} car := carBuilder. SetMake("Toyota"). SetModel("Corolla"). SetYear(2021). SetColor("Red"). SetEngineSize(1.8). Build() fmt.Printf("Make: %s\n", car.Make) // Output: Make: Toyota fmt.Printf("Model: %s\n", car.Model) // Output: Model: Corolla fmt.Printf("Year: %d\n", car.Year) // Output: Year: 2021 fmt.Printf("Color: %s\n", car.Color) // Output: Color: Red fmt.Printf("Engine Size: %.1f\n", car.EngineSize) // Output: Engine Size: 1.8
В этом примере мы создаем объект CarBuilder
и используем его методы для установки дополнительных параметров объекта Car
.
Наконец, мы вызываем метод Build
, чтобы получить окончательный объект Car
. Затем мы распечатываем поля объекта Car
, чтобы убедиться, что они были заданы правильно.
Расширенные варианты использования шаблона Builder в Go
Шаблон построителя имеет несколько расширенных вариантов использования, которые могут быть полезны в определенных ситуациях.
Теперь мы рассмотрим некоторые расширенные варианты использования шаблона Builder в Go.
Создание интерфейса конструктора
В базовом примере шаблона построителя у нас была одна структура построителя, которая использовалась для создания объекта.
Однако вы можете создать интерфейс построителя, который могут реализовать несколько структур построителя.
Это может быть полезно, когда у вас есть разные типы объектов, которые необходимо построить с использованием одного и того же шаблона.
Допустим, у вас есть два типа автомобилей: электромобили и бензиновые автомобили. Оба типа автомобилей имеют одинаковые необязательные параметры, но разные обязательные параметры.
В этом случае вы можете создать интерфейс CarBuilder
, указывающий необходимые методы для сборки автомобиля, а затем создать две структуры, реализующие интерфейс CarBuilder
: ElectricCarBuilder
и GasolineCarBuilder
.
type CarBuilder interface { SetMake(make string) CarBuilder SetModel(model string) CarBuilder SetYear(year int) CarBuilder SetColor(color string) CarBuilder SetEngineSize(engineSize float64) CarBuilder Build() Car } type ElectricCarBuilder struct { Car } type GasolineCarBuilder struct { Car }
И ElectricCarBuilder
, и GasolineCarBuilder
встраивают структуру Car
и реализуют интерфейс CarBuilder
.
Затем у них может быть собственная реализация необходимых методов для сборки автомобиля.
func (b *ElectricCarBuilder) SetMake(make string) CarBuilder { b.Make = make return b } func (b *ElectricCarBuilder) SetModel(model string) CarBuilder { b.Model = model return b } func (b *ElectricCarBuilder) SetYear(year int) CarBuilder { b.Year = year return b } func (b *ElectricCarBuilder) SetColor(color string) CarBuilder { b.Color = color return b } func (b *ElectricCarBuilder) SetEngineSize(engineSize float64) CarBuilder { b.EngineSize = engineSize return b } func (b *ElectricCarBuilder) Build() Car { return b.Car } func (b *GasolineCarBuilder) SetMake(make string) CarBuilder { b.Make = make return b } func (b *GasolineCarBuilder) SetModel(model string) CarBuilder { b.Model = model return b } func (b *GasolineCarBuilder) SetYear(year int) CarBuilder { b.Year = year return b } func (b *GasolineCarBuilder) SetColor(color string) CarBuilder { b.Color = color return b } func (b *GasolineCarBuilder) SetEngineSize(engineSize float64) CarBuilder { b.EngineSize = engineSize return b } func (b *GasolineCarBuilder) Build() Car { return b.Car }
Вот как мы можем создать автомобиль с помощью интерфейса, мы также можем использовать тот же интерфейс для мока.
func CreateCar(builder CarBuilder) Car { return builder. SetMake("Toyota"). SetModel("Corolla"). SetYear(2022). SetColor("blue"). SetEngineSize(2.0). Build() } func main() { electricCarBuilder := &ElectricCarBuilder{} gasolineCarBuilder := &GasolineCarBuilder{} electricCar := CreateCar(electricCarBuilder) gasolineCar := CreateCar(gasolineCarBuilder) fmt.Printf("Electric car: %+v\n", electricCar) fmt.Printf("Gasoline car: %+v\n", gasolineCar) }
В этом примере мы создаем ElectricCarBuilder
и GasolineCarBuilder
и используем их для создания электромобиля и бензинового автомобиля соответственно.
Функция CreateCar
принимает интерфейс CarBuilder
и задает необходимые поля с помощью методов построителя, прежде чем, наконец, вызвать метод Build
для создания объекта Car
.
Хлопайте пожалуйста!!
Если вы нашли эту статью полезной, я был бы признателен за хлопки 👏👏👏👏, это мотивирует меня писать больше таких полезных статей в будущем.
Подписывайтесь на меня на Medium, чтобы получать регулярный потрясающий контент и идеи.
Подпишитесь на мою рассылку
Если вам нравится мой контент, рассмотрите возможность подписки на мой бесплатный информационный бюллетень, чтобы получать эксклюзивный, образовательный, технический, интересный и связанный с карьерой контент прямо на ваш почтовый ящик.
Важные ссылки
Спасибо, что прочитали пост, не забудьте перейти по ссылкам ниже, чтобы увидеть еще больше интересного контента в будущем.
Twitter: https://twitter.com/dsysd_dev
Youtube: https://www.youtube.com/@dsysd-dev< br /> Github: https://github.com/dsysd-dev
Medium: https://medium.com/@dsysd- dev
Электронная почта: [email protected]
Linkedin: https://www.linkedin.com/in/ dsysd-dev/
Информационный бюллетень: https://dsysd.beehiiv.com/subscribe
Gumroad: https://dsysd .gumroad.com/