前言
Go语言面向对象设计原则学习笔记
中心思想:高内聚、低耦合
单一指责原则(Single Responsibility Principle, SRP)
- 类的职责单一,对外只提供一种功能,而引起类变化的原因都应该只有一个
采用前代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package main
type Clothes struct { }
func (c *Clothes) OnWork() {}
func (c *Clothes) OnShop() {}
func main() { var c = Clothes{} c.OnWork() c.OnShop() }
|
采用后代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package main
type ClothesForWork struct { }
func (c *ClothesForWork) OnStyle() {}
type ClothesForShop struct { }
func (c *ClothesForShop) OnStyle() {}
func main() {
var clothesForWork = ClothesForWork{} clothesForWork.OnStyle()
var clothesForShop = ClothesForShop{} clothesForShop.OnStyle() }
|
开闭原则(Open-Closed Principle, OCP)
采用前代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package main
type Banker struct{}
func (b *Banker) Save() {}
func (b *Banker) Pay() {}
func main() { var banker = Banker{}
banker.Save()
banker.Pay() }
|
采用后代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package main
type Banker interface { DoBusiness() }
type BankerSaveImpl struct{}
func (b *BankerSaveImpl) DoBusiness() {}
type BankerPayImpl struct{}
func (b *BankerPayImpl) DoBusiness() {}
func main() {
var bankerSaveImpl Banker = &BankerSaveImpl{} bankerSaveImpl.DoBusiness()
var bankerPayImpl Banker = &BankerPayImpl{} bankerPayImpl.DoBusiness() }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package main
type Banker interface { DoBusiness() }
func BankerBusiness(b Banker) { b.DoBusiness() }
type BankerSaveImpl struct{}
func (b *BankerSaveImpl) DoBusiness() {}
type BankerPayImpl struct{}
func (b *BankerPayImpl) DoBusiness() {}
func main() {
BankerBusiness(&BankerSaveImpl{})
BankerBusiness(&BankerPayImpl{}) }
|
里氏代换原则(Liskov Substitution Principle, LSP)
- 任何抽象类(接口)出现的地方都可以用他的实现类进行替换,实际就是虚拟机制,通过语言级别实现面向对象功能
依赖倒转原则(Dependence Inversion Principle, DIP)
- 面向接口编程
- 依赖于抽象类(接口),不依赖于具体实现类
采用前代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| package main
type Benz struct{}
type BMW struct{}
type ZhangSan struct{}
func (zs *ZhangSan) DriveBenz() {}
func (zs *ZhangSan) DriveBMW() {}
type LiSi struct{}
func (ls *LiSi) DriveBenz() {}
func (ls *LiSi) DriveBMW() {}
func main() { var zs = ZhangSan{} var ls = LiSi{}
zs.DriveBenz() zs.DriveBMW()
ls.DriveBenz() ls.DriveBMW() }
|
采用后代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| package main
type Car interface { Run() }
type Driver interface { Drive(car Car) }
type Benz struct{}
func (benz *Benz) Run() {}
type BMW struct{}
func (bmw *BMW) Run() {}
type ZhangSan struct{}
func (zs *ZhangSan) Drive(car Car) { car.Run() }
type LiSi struct{}
func (ls *LiSi) Drive(car Car) { car.Run() }
func main() { var zs Driver = new(ZhangSan) var ls Driver = new(LiSi)
zs.Drive(&Benz{}) zs.Drive(&BMW{})
ls.Drive(&Benz{}) ls.Drive(&BMW{}) }
|
接口隔离原则(Interface Segregation Principle, ISP)
- 不应该强迫用户的程序依赖他们不需要的方法,一个接口应该只提供一种对外功能,不应该把所有操作都封装到一个接口中去
合成复用原则(Composite Reuse Principle, CRP)
- 如果使用继承,会导致父类的任何变换都可能影响到子类的行为,如果使用对象组合,就降低了这种依赖关系,对于继承和组合,优先使用组合
采用前代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package main
type Cat struct{}
func (c *Cat) Eat() {}
func (c *Cat) Sleep() {}
type CatNew struct { Cat }
func main() { var catNew = CatNew{} catNew.Eat() catNew.Sleep() }
|
采用后代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package main
type Cat struct{}
func (c *Cat) Eat() {}
func (c *Cat) Sleep() {}
type CatNew struct { Cat Cat }
func (cn *CatNew) Eat() { cn.Cat.Eat() }
func (cn *CatNew) Sleep() {}
func main() { var catNew = CatNew{} catNew.Eat() catNew.Sleep() }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package main
type Cat struct{}
func (c *Cat) Eat() {}
func (c *Cat) Sleep() {}
type CatNew struct {}
func (cn *CatNew) Eat(cat Cat) { cat.Eat() }
func (cn *CatNew) Sleep() {}
func main() { var catNew = CatNew{} catNew.Eat(Cat{}) catNew.Sleep() }
|
迪米特法则(Law of Demeter, LoD)
- 一个对象应该对其他对象了解越少越好,从而降低对象之间的耦合
完成
参考文献
哔哩哔哩——刘丹冰AceId