Задать вопрос
@AstRonin

Golang путь как использовать паттерн Фабрику без наследования?

Допустим у меня есть некая фабрика пользователей.
Базовая структура с основным базовым кодом, подходящим для всех типов юзеров.
И, к примеру, тип Working в котором мне нужно переопределить метод DoFirst

package main

import "fmt"

type PeopleManager interface {
    Do()
}

func NewPeopleManager(typeOfUser string) PeopleManager {
    switch typeOfUser {
    case "working":
        return NewWorking()
        // also has many others types of user
    default:
        panic("Not found type")
    }
}

type Base struct {
}

func (b *Base) Do() {
    b.DoPrepare()
    b.DoFirst()
    b.DoSecond()
}

func (b *Base) DoPrepare() {
    fmt.Println("Call DoPrepare Base type")
}
func (b *Base) DoFirst() {
    fmt.Println("Call DoFirst Base type")
}
func (b *Base) DoSecond() {
    fmt.Println("Call DoSecond Base type")
}

type Working struct {
    Base
}

func NewWorking() *Working {
    return &Working{}
}

func (w *Working) Do() { // Method just call Base method to run a process
    w.Base.Do()
}
func (w *Working) DoFirst() { // Rewrite just one method on some big chain of methods
    fmt.Println("Call DoFirst Working type")
}

func main() {
    m := NewPeopleManager("working")
    m.Do()

}


Я вижу ответ этого примера:
Call DoPrepare Base type
Call DoFirst Base type
Call DoSecond Base type


А хочу видеть
Call DoPrepare Base type
Call DoFirst Working type
Call DoSecond Base type


Посоветуйте golang путь мастерства как это сделать, не переписывая метод
Do

func (w *Working) Do() {
    w.DoPrepare()
    w.DoFirst()
    w.DoSecond()
}


Потому что метод
Do
может иметь довольно большой код внутри, а так же вызов других методов по цепочке.
Как реализовать это качественно на Golang?
  • Вопрос задан
  • 57 просмотров
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 2
@qeeveex
Вынести Do в отдельный класс или функцию, на входе принимать (или зависимость в случае объекта) интерфейс с методами DoPrepare, w.DoFirst, DoSecond.
И воспользоваться паттерном "декоратор" когда будете объявлять зависимости, например в main.go.

Бонусом получите тестируемость. Так как сможете легко подсовывать моки.
Ответ написан
Фабрику вообще не принято использовать в Го. Используйте вместо нее обычные конструкторы. Функцию New() в пакете, где у вас описан пользователь.

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

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

Войдите, чтобы написать ответ

Похожие вопросы