Русский
Русский
English
Статистика
Реклама

Abstract factory

Шаблоны проектирования в Go Абстрактная Фабрика

26.11.2020 18:13:16 | Автор: admin

Привет, Хабр! Представляю вашему вниманию перевод очередной статьи Design Patterns: Abstract Factory Pattern автора Shubham Zanwar.

Абстрактная фабрика - это порождающий шаблон проектирования. Он используется, когда нам нужно создать семейство похожих продуктов. Давайте для понимания возьмем пример сети пиццерий.

Пиццерия

Представим, что вы глава бизнеса и открываете сеть пиццерий по всему городу. Одной из ваших обязанностей является производство всех основных продуктов (в нашем случае это пиццы и жареный чесночный хлеб), которые будут представлять такие бренды как Домино и Жаровня (назовем их так - прим. перев.).

Есть множество способов как это сделать. Самый простой - создать фабрику по производству пицц каждого бренда и еще похожую фабрику для жаренного хлеба.

Если вы еще не представляете, как работают фабрики, вы можете почитать здесь

Проблема в том, что теперь мы доверяем пользователю выбор правильного типа пиццы и жаренного хлеба, который они хотят. Если они сделают ошибку в приготовлении пиццы Домино с чесночным хлебом Жаровни, ваши заказчики будут в ярости и вы можете потерять контракт с сетями этих брендов.

Не волнуйтесь, есть простой способ.

Вместо создания фабрики для каждого продукта (пиццы или жаренного хлеба), вы сможете создавать фабрику для каждого бренда. Обе фабрики будут производить пиццу и жареный хлеб.

Открыв пиццерию, вы передаете менеджеру фабрику Домино или Жаровню и можете отдохнуть, потому что теперь никто ничего не перепутает.

Давайте посмотрим на код. Перед тем как мы напишем фабрики, создадим сами продукты:

Обычная пицца

type iPizza interface {    GetPrice() float64    GetName() string    GetToppings() []string}type pizza struct {    name     string    price    float64    toppings []string}func (p *pizza) GetName() string {    return p.name}func (p *pizza) GetPrice() float64 {    return p.price}func (p *pizza) GetToppings() []string {    return p.toppings}

Пиццы наших брендов

type pizzaHutPizza struct {    pizza}type dominosPizza struct {    pizza}

Жареный чесночный хлеб

type iGarlicBread interface {    GetPrice() float64    GetName() string}type garlicBread struct {    name  string    price float64}func (g *garlicBread) GetName() string {    return g.name}func (g *garlicBread) GetPrice() float64 {    return g.price}

И наших брендов

type pizzaHutGarlicBread struct {    garlicBread}type dominosGarlicBread struct {    garlicBread}

Мы создали оба наших продукта, которые реализуют общий интерфейс, облегчая конечному пользователю их потребление. Вот такой каламбур.

Теперь напишем сами фабрики, сначала общая

type iPizzaFactory interface {    createPizza() iPizza    createGarlicBread() iGarlicBread}

Теперь наших брендов: Жаровня-фабрика и Домино-фабрика с унифицированной функциональностью

type PizzaHutFactory struct {}func (p *PizzaHutFactory) createPizza(): iPizza {    return &pizzaHutPizza{        pizza{            name:     "pepperoni",            price:    230.3,            toppings: []string{"olives", "mozzarella", "pork"},        },    }}func (p *pizzaHutFactory) createGarlicBread() iGarlicBread {    return &pizzaHutGarlicBread{        garlicBread{            name:  "garlic bread",            price: 180.99,        },    }}
type dominosFactory struct{}func (d *dominosFactory) createPizza() iPizza {    return &dominosPizza{        pizza{            name:     "margherita",            price:    200.5,            toppings: []string{"tomatoes", "basil", "olive oil"},        },    }}func (d *dominosFactory) createGarlicBread() iGarlicBread {    return &dominosGarlicBread{        garlicBread{            name:  "cheesy bread sticks",            price: 150.00,        },    }}

Мы можем выбирать любую фабрику и продолжить приготовление пиццы или жаренного хлеба и быть абсолютно уверенными, что любой производный продукт будет соответствующего семейства/бренда.

Мы почти у цели. Давайте обернем это в фабрику, которая будет возвращать нам фабрику по нашему желанию. Сбиты с толку? Тогда еще раз прочитайте предыдущее предложение.

Думайте о наших фабриках как о другом объекте. Основываясь на типе или пиццерии, которые мы хотим открыть (Жаровня или Домино), мы создаем нужную фабрику (просто другой объект). Чтобы автоматически получать эти "объекты", у нас будет своя фабрика.

Этот код поможем вам - Фабрика фабрик

func getPizzaFactory(chain string) (iPizzaFactory, error) {    if chain == "P" {        return &pizzaHutFactory{}, nil    }    if chain == "D" {        return &dominosFactory{}, nil    }    return nil, fmt.Errorf("Enter a valid chain type next time")}

Надеюсь, стало понятнее.

Основное, что нужно запомнить: шаблон абстрактная фабрика реализует фабрику фабрик. Внутренние фабрики используются для создания продуктов нужного вида.

Вы можете найти этот код на github

Пока

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru