合成复用原则CRP: 如果使用继承,会导致父类的的任何变化都可能影响到子类的行为。如果使用对象组合,就降低了这种依赖关系。对于继承和组合,优先使用组合。


如下图所示,中间的猫咪只需要继承黄猫的睡觉方法,若此时采用继承,则导致继承到黄猫父类恐龙的所有方法,增加了代码复杂度。本身只需要添加一个睡觉的方法,却继承了其父类所有的方法。

一般不建议用继承去添加新的类或者添加新的方法。合成复用原则降低了模块与模块间的依赖关系,能用组合和继承都实现的方法,优先使用组合。

go语言设计模式-合成复用原则_合成复用原则

package main

import "fmt"

type Cat struct {
}

func (c *Cat) Eat() {
fmt.Println("小猫吃饭")
}

//给小猫添加可以睡觉的方法(使用继承的方式)
type CatB struct {
Cat
}

func (cb *CatB) Sleep() {
fmt.Println("小猫睡觉")
}

//给小猫添加可以睡觉的方法(使用组合的方式)
type CatC struct {
//C *Cat
}

func (cc *CatC) Eat(c *Cat) {
//cc.C.Eat()
c.Eat()

}

func (cc *CatC) Sleep() {
fmt.Println("小猫睡觉")
}

func main() {
c := &Cat{}
c.Eat()

fmt.Println("---------------")
cb := &CatB{}
cb.Eat()
cb.Sleep()

fmt.Println("---------------")
cc := &CatC{}
cc.Eat(c)
cc.Sleep()
}

执行结果如下:

小猫吃饭
---------------
小猫吃饭
小猫睡觉
---------------
小猫吃饭
小猫睡觉