首页 > 其他分享 >go语言设计模式-里氏代换与依赖倒转原则

go语言设计模式-里氏代换与依赖倒转原则

时间:2022-10-17 21:37:52浏览次数:75  
标签:... Run 代换 fmt Println func go 设计模式 type

里氏代换LSP :任何抽象类(interface接口)出现的地方都可以用它的实现类进行替换,实际就是虚拟机制,语言级别实现面向对象功能。能用实例和接口的尽可能抽象成接口,然后用子类来实现。

依赖倒转原则DIP: 依赖于抽象(接口),不要依赖具体实现(类),也就是针对接口编程。

耦合度极高的业务实现:

package main

import "fmt"

//司机张三 李四,汽车奔驰 宝马
//1 张3 开奔驰
//2 李4 开宝马

//奔驰汽车
type Benz struct {
}

func (b *Benz) Run() {
fmt.Println("Benz is running...")
}

//宝马汽车
type BMW struct {
}

func (b *BMW) Run() {
fmt.Println("BMW is running...")
}

//司机张三
type Zhang3 struct {
//...
}

func (z3 *Zhang3) DriveBenz(ben *Benz) {
fmt.Println("zhang3 Drive benz")
ben.Run()
}

// 新+ 司机张三开宝马
func (z3 *Zhang3) DriveBmw(bmw *BMW) {
fmt.Println("z3 Drive BMW")
bmw.Run()
}

//司机李四
type Li4 struct {
//...
}

func (l4 *Li4) DriveBmw(bmw *BMW) {
fmt.Println("li4 Drive BMW")
bmw.Run()
}

//新+ 司机李四开奔驰
func (l4 *Li4) DriveBenz(ben *Benz) {
fmt.Println("z3 Drive Benz")
ben.Run()
}

func main() {
//1 张3 开奔驰
benz := &Benz{}
zhang3 := Zhang3{}
zhang3.DriveBenz(benz)

//2 李4 开宝马
bmw := &BMW{}
li4 := Li4{}
li4.DriveBmw(bmw)
}

如下图所示,新增丰田车需要了解张三,李四的drive方法是如何实现的,它们是如何调用drive方法的。这样每次新加人物或者汽车都需要尝试跟其所依赖的每个接口进行耦合式调试,使得系统的稳定性维护和改造变得极其困难。

go语言设计模式-里氏代换与依赖倒转原则_依赖倒转原则


如下图所示,如果我们在设计一个系统的时候,将模块分为3个层次,抽象层、实现层、业务逻辑层。那么首先将抽象层的模块和接口定义出来,这里就需要interface接口的设计,我们依照抽象层,依次实现每个实现层的模块,在我们写实现层的代码的时候,实际上我们只需要参照对应的抽象层实现就好了,实现每个模块,也和其他的实现的模块没有关系,这样也符合了上面介绍的开闭原则。这样实现起来每个模块只依赖对象的接口,而和其他的模块没关系,依赖关系单一。系统容易扩展和维护。

go语言设计模式-里氏代换与依赖倒转原则_依赖倒转原则_02


依赖倒转原则改造耦合度极高的业务实现:

此时新增汽车只需要知道抽象汽车有哪些方法就行了,而无需关注司机方法的实现。

package main

import "fmt"

//---抽象层---
type Car interface {
Run()
}

type Driver interface {
Drive(car Car)
}

//---实现层---
type BenZ struct {
//...
}

func (b *BenZ) Run() {
fmt.Println("Benz is Running...")
}

type Bmw struct {
//...
}

func (b *Bmw) Run() {
fmt.Println("Bmw is Running...")
}

// 编写zhangsan lisi面向drive方法,无须关注奔驰宝马的实现,知道car如何调用Run方法即可
type Zhangsan struct {
//...
}

func (z3 *Zhangsan) Drive(car Car) {
fmt.Println("zhang3 drive car")
car.Run()
}

type Lisi struct {
//...
}

func (l4 *Lisi) Drive(car Car) {
fmt.Println("li4 drive car")
car.Run()
}

//---业务逻辑层---
func main() {
// zhang3-benz
var benz Car //面向抽象层
benz = new(BenZ)

var zhang3 Driver //面向抽象层
zhang3 = new(Zhangsan)
zhang3.Drive(benz)

//li4---bmw
var bmw Car
bmw = new(Bmw)

var li4 Driver
li4 = new(Lisi)
li4.Drive(bmw)
}

结果:

zhang3 drive car
Benz is Running...
li4 drive car
Bmw is Running...

标签:...,Run,代换,fmt,Println,func,go,设计模式,type
From: https://blog.51cto.com/u_7890003/5764407

相关文章

  • go channel原理及使用场景
    ​​gochannel原理及使用场景​​源码解析typehchanstruct{qcountuint//Channel中的元素个数dataqsizuint//Channel中的循环队列的......
  • 【Rust 日报】2021-11-24 Rust中的依赖注入设计模式
    三个Rust代码库的故事现在是使用Rust的好时机了吗?Convex的创始团队(从DropBox分离出来的)有使用Rust开发MagicPocket(Dropbox的地理分布式数据存储系统),Nucleus(重写的Dropbox的......
  • 11.MongoDB系列之连接副本集
    1.Python连接副本集frompymongoimportMongoClientfrombson.codec_optionsimportCodecOptionsfromretryimportretryimportpytzimportpandasaspdclass......
  • 12.MongoDB系列之副本集管理
    1.控制成员状态1.1把主节点变为从节点rs.stepDown()1.2阻止选举如果需要对主节点维护,不想期间其他从节点选举为主节点,则可以rs.freeze(10000)维护完成后,只需要......
  • 14.MongoDB系列之配置分片
    1.启动服务器1.1启动配置服务器配置服务器是集群的大脑,保存着关于每个服务器包含哪些数据的所有元数据,因此,必须首先创建配置服务器。由于资源限制,在同一机器上启动三......
  • 13.MongoDB系列之分片简介
    1.分片概念分片是指跨机器拆分数据的过程,有时也会用术语分区。MongoDB既可以手工分片,也支持自动分片2.理解集群组件分片的目标之一是由多个分片组成的集群对应用程序......
  • 17.MongoDB系列之了解应用程序动态
    1.查看当前操作mongos>db.currentOp(){"inprog":[{"shard":"study","type":"op......
  • 16.MongoDB系列之分片管理
    1.查看当前状态1.1查看配置信息mongos>useconfig//查看分片mongos>db.shards.find(){"_id":"study","host":"study/localhost:27018,localhost:27019,loc......
  • 15. MongoDB系列之选择片键
    1.片键类型1.1升序片键升序片键通常类似于date或ObjectId--随着时间稳步增长的字段。这种模式通常会使MongoDB更难保持块的平衡,因为所有的块都是由一个分片创建的。1......
  • django项目的创建、运行
    1、创建django项目名为Django_learndjango-adminstartproject Django_learn2、创建名为user的应用cd Django_learnpythonmanage.pystartappusers......