История изменений
Исправление kaldeon, (текущая версия) :
как в Go реализуется вот такой элементарный паттерн
Напрямую — никак, ибо наследование реализации отсутствует. Это, кстати, защищает от проблемы хрупкого базового класса [1].
Но вообще аналогичный код пишется так:
1. Пишем derived1 и derived2
2. Пишем base, который при создании принимает derived1 или derived2 через общий интерфейс. Именно к нему будем обращаться в base.DoSomething.
3. В f передаём только инстанс base
В целом, прямое применение принципа “favor composition over inheritance.”
Важно и то, что интерфейс привязан только к base. Это расслабляет порядок написания: можно сначала реализовать derived1/derived2 и уже потом написать base/doer.
Код выглядит как-то так:
type doer interface{ Do() }
type base struct{ doer doer }
type derived1 struct{}
type derived2 struct{}
func (b *base) DoSomething() {
b.doer.Do()
}
func (d *derived1) Do() { fmt.Println("hello world") }
func (d *derived2) Do() { fmt.Println("hello existence") }
func main() {
b := &base{
doer: &derived2{},
}
b.DoSomething()
}
Исправление kaldeon, :
как в Go реализуется вот такой элементарный паттерн
Напрямую — никак, ибо наследование реализации отсутствует. Это, кстати, защищает от проблемы хрупкого базового класса [1].
Но вообще аналогичный код пишется так:
1. Пишем derived1 и derived2
2. Пишем base, который при создании принимает derived1 или derived2 через общий интерфейс. Именно к нему будем обращаться в base.DoSomething.
3. В f передаём только инстанс base
В целом, прямое применение принципа “favor composition over inheritance.”
Важно и то, что интерфейс привязан только к base. Это ослабляет порядок написания: можно сначала реализовать derived1/derived2 и уже потом написать base/doer.
Код выглядит как-то так:
type doer interface{ Do() }
type base struct{ doer doer }
type derived1 struct{}
type derived2 struct{}
func (b *base) DoSomething() {
b.doer.Do()
}
func (d *derived1) Do() { fmt.Println("hello world") }
func (d *derived2) Do() { fmt.Println("hello existence") }
func main() {
b := &base{
doer: &derived2{},
}
b.DoSomething()
}
Исходная версия kaldeon, :
как в Go реализуется вот такой элементарный паттерн
Напрямую — никак, ибо наследование реализации отсутствует. Это, кстати, защищает от проблемы хрупкого базового класса [1].
Но вообще аналогичный код пишется так:
1. Объявляем интерфейс doer
2. При создании base передаём в него конкретный инстанс, реализующий doer. Именно к нему base.DoSomething будет обращаться.
3. В f передаём только инстанс base.
В целом, прямое применение принципа “favor composition over inheritance.”
Код выглядит как-то так:
type doer interface{ Do() }
type base struct{ doer doer }
type derived1 struct{}
type derived2 struct{}
func (b *base) DoSomething() {
b.doer.Do()
}
func (d *derived1) Do() { fmt.Println("hello world") }
func (d *derived2) Do() { fmt.Println("hello existence") }
func main() {
b := &base{
doer: &derived2{},
}
b.DoSomething()
}
Важно и то, что интерфейс привязан только к base. Это ослабляет порядок написания: можно сначала реализовать derived1/derived2 и уже потом ретроспективно написать base/doer.