第5节 合成复用原则


❤️💕💕Java和Golang的设计模式,设计模式介绍、创建者模式、结构型模式、行为型模式。Myblog:http://nsddd.topopen in new window


[TOC]

原则

警告

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

合成复用原则 (Composite Reuse Principle, CRP) :通过组合来实现父类方法

继承和组合

代替继承,Go 语言通过允许将一个结构嵌入到另一个结构中来鼓励组合,这种方式允许调用在嵌入open in new window结构上定义的方法,就像在包含结构上定义一样。

注意:在这篇文章中,我偶尔会使用面向对象的术语,如基类、子类和覆盖。请记住,Go 不支持这些概念;我在这里使用这些术语来说明使用 Go 以这种方式思考会导致问题。

使用合并复用

// Merge reuse principle
package main

import "fmt"

//Define a kitten structure and realize the method of eating and sleeping.
type Cat struct {
	//...
}

//kitten eats
func (c *Cat) Eat() {
	fmt.Println("CatA eat")
}

type CatB struct {
	//继承Cat
	Cat
}

//kitten sleeps
func (c *CatB) Sleep() {
	fmt.Println("CatB sleep")
}

// 组合复用原则(使用组合/聚合关系代替继承关系)
type CatC struct {
	//组合Cat
	C  *Cat  //组合一个Cat类型的指针
	CB *CatB //组合一个CatB类型的指针
}

//kitten eats
func (c *CatC) Eat() {
	c.C.Eat() //调用Cat的Eat方法
	fmt.Println("CatC eat")
}

func main() {
	Cat := &Cat{}
	//kitten eats
	Cat.Eat()

	fmt.Println("=================继承=================")
	CatB := &CatB{}
	//kitten eats
	CatB.Eat()
	//kitten sleeps
	CatB.Sleep()

	fmt.Println("=================组合=================")
	CatC := &CatC{}
	//kitten eats
	CatC.Eat()
	//kitten sleeps
	CatC.CB.Sleep()

	CatC.C.Eat()
}

🚀 编译结果如下:

[Running] go run "d:\文档\最近的\awesome-golang\docs\code\go-super\83-main.go"
CatA eat
=================继承=================
CatA eat
CatB sleep
=================组合=================
CatA eat
CatC eat
CatB sleep
CatA eat

END 链接