1

【笔记】Go 语言面向对象设计原则

 7 months ago
source link: https://loli.fj.cn/zh-CN/2024/02/18/Go%E8%AF%AD%E8%A8%80%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Go 语言面向对象设计原则学习笔记
中心思想:高内聚、低耦合

单一指责原则(Single Responsibility Principle, SRP)

  • 类的职责单一,对外只提供一种功能,而引起类变化的原因都应该只有一个

采用前代码

package main

// Clothes 穿衣服的方式
type Clothes struct {
}

// OnWork 工作需要穿的衣服
func (c *Clothes) OnWork() {}

// OnShop 逛街需要穿的衣服
func (c *Clothes) OnShop() {}

func main() {
var c = Clothes{}

// 工作时穿的衣服
c.OnWork()

// 逛街时穿的衣服
c.OnShop()
}

采用后代码

package main

// ClothesForWork 工作需要穿的衣服
type ClothesForWork struct {
}

func (c *ClothesForWork) OnStyle() {}

// ClothesForShop 逛街需要穿的衣服
type ClothesForShop struct {
}

func (c *ClothesForShop) OnStyle() {}

func main() {

// 工作时穿的衣服
var clothesForWork = ClothesForWork{}
clothesForWork.OnStyle()

// 逛街时穿的衣服
var clothesForShop = ClothesForShop{}
clothesForShop.OnStyle()
}

开闭原则(Open-Closed Principle, OCP)

  • 类的改动是通过增加代码进行的,而不是修改代码

采用前代码

package main

// Banker 银行业务员
type Banker struct{}

// Save 存款业务
func (b *Banker) Save() {}

// Pay 支付业务
func (b *Banker) Pay() {}

func main() {
var banker = Banker{}

// 执行存款业务
banker.Save()

// 执行支付业务
banker.Pay()
}

采用后代码

package main

// Banker 银行业务员
type Banker interface {
DoBusiness()
}

// BankerSaveImpl 存款业务员
type BankerSaveImpl struct{}

func (b *BankerSaveImpl) DoBusiness() {}

// BankerPayImpl 支付业务员
type BankerPayImpl struct{}

func (b *BankerPayImpl) DoBusiness() {}

func main() {

// 执行存款业务
var bankerSaveImpl Banker = &BankerSaveImpl{}
bankerSaveImpl.DoBusiness()

// 执行支付业务
var bankerPayImpl Banker = &BankerPayImpl{}
bankerPayImpl.DoBusiness()
}
package main

// Banker 银行业务员
type Banker interface {
DoBusiness()
}

// BankerBusiness 银行业务执行
func BankerBusiness(b Banker) {
b.DoBusiness()
}

// BankerSaveImpl 存款业务员
type BankerSaveImpl struct{}

func (b *BankerSaveImpl) DoBusiness() {}

// BankerPayImpl 支付业务员
type BankerPayImpl struct{}

func (b *BankerPayImpl) DoBusiness() {}

func main() {

// 执行存款业务
BankerBusiness(&BankerSaveImpl{})

// 执行支付业务
BankerBusiness(&BankerPayImpl{})
}

里氏代换原则(Liskov Substitution Principle, LSP)

  • 任何抽象类(接口)出现的地方都可以用他的实现类进行替换,实际就是虚拟机制,通过语言级别实现面向对象功能

依赖倒转原则(Dependence Inversion Principle, DIP)

  • 面向接口编程
  • 依赖于抽象类(接口),不依赖于具体实现类

采用前代码

package main

// Benz 奔驰汽车
type Benz struct{}

// BMW 宝马汽车
type BMW struct{}

// ZhangSan 司机张三
type ZhangSan struct{}

// DriveBenz 开奔驰
func (zs *ZhangSan) DriveBenz() {}

// DriveBMW 开宝马
func (zs *ZhangSan) DriveBMW() {}

// LiSi 司机李四
type LiSi struct{}

// DriveBenz 开奔驰
func (ls *LiSi) DriveBenz() {}

// DriveBMW 开宝马
func (ls *LiSi) DriveBMW() {}

func main() {
var zs = ZhangSan{}
var ls = LiSi{}

// 张三开奔驰
zs.DriveBenz()
// 张三开宝马
zs.DriveBMW()

// 李四开奔驰
ls.DriveBenz()
// 李四开宝马
ls.DriveBMW()
}

采用后代码

package main

// Car 汽车
type Car interface {
Run()
}

// Driver 司机
type Driver interface {
Drive(car Car)
}

// Benz 奔驰汽车
type Benz struct{}

func (benz *Benz) Run() {}

// BMW 宝马汽车
type BMW struct{}

func (bmw *BMW) Run() {}

// ZhangSan 司机张三
type ZhangSan struct{}

func (zs *ZhangSan) Drive(car Car) {
car.Run()
}

// LiSi 司机李四
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)

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

采用前代码

package main

// Cat 猫
type Cat struct{}

// Eat 吃
func (c *Cat) Eat() {}

// Sleep 睡
func (c *Cat) Sleep() {}

// CatNew 新猫
type CatNew struct {
Cat
}

func main() {
var catNew = CatNew{}
catNew.Eat()
catNew.Sleep()
}

采用后代码

package main

// Cat 猫
type Cat struct{}

// Eat 吃
func (c *Cat) Eat() {}

// Sleep 睡
func (c *Cat) Sleep() {}

// CatNew 新猫
type CatNew struct {
Cat Cat
}

// Eat 吃
func (cn *CatNew) Eat() {
cn.Cat.Eat()
}

// Sleep 睡
func (cn *CatNew) Sleep() {}

func main() {
var catNew = CatNew{}
catNew.Eat()
catNew.Sleep()
}
package main

// Cat 猫
type Cat struct{}

// Eat 吃
func (c *Cat) Eat() {}

// Sleep 睡
func (c *Cat) Sleep() {}

// CatNew 新猫
type CatNew struct {}

// Eat 吃
func (cn *CatNew) Eat(cat Cat) {
cat.Eat()
}

// Sleep 睡
func (cn *CatNew) Sleep() {}

func main() {
var catNew = CatNew{}
catNew.Eat(Cat{})
catNew.Sleep()
}

迪米特法则(Law of Demeter, LoD)

  • 一个对象应该对其他对象了解越少越好,从而降低对象之间的耦合

哔哩哔哩 —— 刘丹冰 AceId


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK