Избегайте дублирования кода между «подтипами» - PullRequest
2 голосов
/ 08 ноября 2019

Я работаю над переписыванием старого Java-проекта на Go.

Я уже сделал несколько Go на работе, но я не могу понять, как я могу перевести свой ООП (с помощью абстрактных классов,и т.д.) к философии Go.

По идее, у меня есть два типа (скоро 3), у которых есть некоторые общие методы, но некоторые другие (ну всего 1 или 2 макс.) должны иметь одинаковые подписи, но неодни и те же тела.

Я знаю, что у Го нет какого-то наследства. Пока у меня есть что-то вроде этого:

type A struct {...}
func (a *A) M1 (){ stuff1 }
func (a *A) M2 (){ stuff2 }
func (a *A) SM (){ special stuff A }

затем:

type B struct {...}
func (b *B) M1 (){ stuff1 }
func (b *B) M2 (){ stuff2 }
func (b *B) SM (){ special stuff B }

Я не знаю, как Го справляется с этим. В Java я создал абстрактный класс, а затем реализовал его с моими двумя конкретными классами.

Мне не нужно дублировать M1 () и M2 (), а иметь универсальный тип для вызова этихметоды, а затем просто нужно определить SM () для обоих типов.

Ответы [ 2 ]

3 голосов
/ 08 ноября 2019

Вы можете встроить структуру, например:

type Common struct {}

func (c *Common) M1() {
    fmt.Println("M1")
}

func (c *Common) M2() {
    fmt.Println("M2")
}

type A struct {
    Common
}

func (a *A) SM() {
    fmt.Println("A SM()")
}

type B struct {
    Common
}

func (b *B) SM() {
    fmt.Println("B SM()")
}   

type Thing interface {
    M1()
    M2()
    SM()
}
func main() {
    var a Thing = &A{}
    var b Thing = &B{}

    a.M1()
    b.M2()
    a.SM()
    b.SM()
}

https://play.golang.org/p/Q3mIH_W8X44

0 голосов
/ 08 ноября 2019

Есть несколько способов решить эту проблему - встраивание не единственный ответ. Если эти методы хотят получить доступ к данным из типов, в которых они определены в вашем псевдокоде (например, A.M1 должен иметь доступ к полям A), то встраивание не поможет вам, потому что встроенный тип не знает типаон встроен в. Вам нужно будет пересмотреть свой дизайн в целом и как программу Go, а не проектировать ее так, как если бы она была программой Java, и пытаться заставить эти концепции работать в Go. Как выяснили многие, попытка разработки ООП в Go приводит к большому разочарованию и очень незначительному успеху.

С другой стороны, если эти методы не , необходимо получить доступ к любым полямтогда зачем они методы? Это могут быть просто чистые функции, которые упростят их использование и рассудят и полностью устранят любые проблемы встраивания или фальсификации наследования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...