Паттерны проектирования Go : Фабрика

Это паттерн создания, который позволяет нам создать «фабрику» объектов из базового класса и реализовать полиморфное поведение, которое позволяет нам изменять поведение наследуемых классов.

Обычно он используется для повторного использования логики создания, разделяющей ряд объектов.

Go не является строго объектно-ориентированным языком, но мы можем реализовать логику ООП через интерфейсы и концепцию композиции над наследованием.

Пример
У нас есть серия продуктов (объектов), которые ведут себя одинаково. Мы можем либо создать отдельный класс для каждого из них, либо поместить всю эту логику в базовый класс, чтобы создать наследуемые классы для каждого продукта.

  • Сначала нам нужно определить интерфейс, который описывает поведение наших продуктов, «сделанных» на нашей «фабрике».
type IProduct interface {
    setStock(stock int)
    getStock() int
    setName(name string)
    getName() string
}
Вход в полноэкранный режим Выйти из полноэкранного режима
  • Определите, как выглядит наш продукт, затем реализуйте методы IProduct, чтобы соответствовать интерфейсу. Это похоже на определение абстрактного класса.
type Computer struct {
    name  string
    stock int
}

func (c *Computer) setStock(stock int) {
    c.stock = stock
}

func (c *Computer) getStock() int {
    return c.stock
}

func (c *Computer) setName(name string) {
    c.name = name
}

func (c *Computer) getName() string {
    return c.name
}
Войти в полноэкранный режим Выход из полноэкранного режима
  • Создайте классы наших продуктов, которые наследуются от класса Computer. Здесь применяется концепция композиции над наследованием.
type Laptop struct {
    Computer
}

func newLaptop() IProduct {
    return &Laptop{
        Computer: Computer{
            name:  "Laptop Computer",
            stock: 0,
        },
    }
}

type Desktop struct {
    Computer
}

func newDesktop() IProduct {
    return &Desktop{
        Computer: Computer{
            name:  "Desktop Computer",
            stock: 0,
        },
    }
}

Вход в полноэкранный режим Выход из полноэкранного режима
  • Наконец, нам нужно «создать» наш метод фабрики, этот метод будет возвращать экземпляр указанного объекта.
func GetComputerFactory(computerType string) (IProduct, error) {
    if computerType == "laptop" {
        return newLaptop(), nil
    } else if computerType == "desktop" {
        return newDesktop(), nil
    } else {
        return nil, fmt.Errorf("invalid computer type")
    }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Запуск нашего кода

func PrintNameAndStock(p IProduct) {
    fmt.Printf("Product name: %s, with stock %dn", p.getName(), p.getStock())
}

func main() {
    laptop, _ := GetComputerFactory("laptop")
    desktop, _ := GetComputerFactory("desktop")

    laptop.setStock(10)
    PrintNameAndStock(laptop)
    desktop.setStock(20)
    PrintNameAndStock(desktop)

}
Вход в полноэкранный режим Выйти из полноэкранного режима

Вывод

Product name: Laptop Computer, with stock 10
Product name: Desktop Computer, with stock 20
Вход в полноэкранный режим Выход из полноэкранного режима

Пример полного экрана

package main

import "fmt"

type IProduct interface {
    setStock(stock int)
    getStock() int
    setName(name string)
    getName() string
}

type Computer struct {
    name  string
    stock int
}

func (c *Computer) setStock(stock int) {
    c.stock = stock
}

func (c *Computer) getStock() int {
    return c.stock
}

func (c *Computer) setName(name string) {
    c.name = name
}

func (c *Computer) getName() string {
    return c.name
}

type Laptop struct {
    Computer
}

func newLaptop() IProduct {
    return &Laptop{
        Computer: Computer{
            name:  "Laptop Computer",
            stock: 0,
        },
    }
}

type Desktop struct {
    Computer
}

func newDesktop() IProduct {
    return &Desktop{
        Computer: Computer{
            name:  "Desktop Computer",
            stock: 0,
        },
    }
}

func GetComputerFactory(computerType string) (IProduct, error) {
    if computerType == "laptop" {
        return newLaptop(), nil
    } else if computerType == "desktop" {
        return newDesktop(), nil
    } else {
        return nil, fmt.Errorf("invalid computer type")
    }
}

func PrintNameAndStock(p IProduct) {
    fmt.Printf("Product name: %s, with stock %dn", p.getName(), p.getStock())
}

func main() {
    laptop, _ := GetComputerFactory("laptop")
    desktop, _ := GetComputerFactory("desktop")

    laptop.setStock(10)
    PrintNameAndStock(laptop)
    desktop.setStock(20)
    PrintNameAndStock(desktop)
}

Вход в полноэкранный режим Выход из полноэкранного режима

Надеюсь, я вам помог 😊😊😊

Оцените статью
Procodings.ru
Добавить комментарий