[Программирование, Go] Шаблоны проектирования в Go — Абстрактная Фабрика (перевод)

Автор Сообщение
news_bot ®

Стаж: 6 лет 4 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
26-Ноя-2020 20:32

Привет, Хабр! Представляю вашему вниманию перевод очередной статьи «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Пока
===========
Источник:
habr.com
===========

===========
Автор оригинала: Shubham Zanwar
===========
Похожие новости: Теги для поиска: #_programmirovanie (Программирование), #_go, #_go, #_design_patterns, #_abstract_factory, #_programmirovanie (
Программирование
)
, #_go
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 04-Июл 20:44
Часовой пояс: UTC + 5