使用Go实现23种设计模式——结构型模式(上)_go图解设计模式,2024年最新Golang音频面试

53 阅读4分钟

}


#### 适配器模式优点


1. 可以让两个没有关联的类一起运行,复用了现有的类
2. 目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题


#### 适配器模式缺点


1. 增加了系统的复杂性
2. 降低了代码可读性


### 桥接模式


将抽象部分与它的实现部分分离,使它们都可以独立地变化


#### 适用场景


1. 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系
2. 不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统


#### Go语言实现



type MessageInterface interface { Send(msg string) error }

type EmailMessage struct { }

func (m *EmailMessage) Send(msg string) error { fmt.Printf("send %s", msg) return nil }

type NotificationInterface interface { Notify(msg string) error }

type InfoNotification struct { message MessageInterface }

func NewInfoNotification(message MessageInterface) *InfoNotification { return &InfoNotification{message: message} }

func (n *InfoNotification) Notify(msg string) error { return n.message.Send(msg) }

func main() { notify := NewInfoNotification(&EmailMessage{}) err := notify.Notify("Info") if err != nil { return } }


#### 桥接模式优点


1. 抽象与实现分离,扩展能力强
2. 符合开闭原则、合成复用原则



#### 桥接模式缺点


1. 由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,能正确地识别出系统中两个独立变化的维度,这增加了系统的理解与设计难度



### 组合模式


将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性



#### 适用场景


1. 公司部门架构等场景



#### Go语言实现



type IOrganization interface { Count() int }

type Employee struct { Name string }

func (*Employee) Count() int { return 1 }

type Department struct { Name string SubOrganization []IOrganization }

func (d *Department) Count() (count int) { for _, organization := range d.SubOrganization { count += organization.Count() } return count }

func (d *Department) AddOrganization(organization IOrganization) { d.SubOrganization = append(d.SubOrganization, organization) }


#### 组合模式优点


1. 组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了客户端代码
2. 更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,满足“开闭原则”


#### 组合模式缺点


1. 设计较复杂,客户端需要花更多时间理清类之间的层次关系
2. 不容易限制容器中的构件,不容易用继承的方法来增加构件的新功能


### 装饰模式


向现有的对象添加新的功能,同时又不改变其结构,即动态地给对象添加一些额外的功能


#### 适用场景


1. 当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时
2. 当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承关系很难实现,而采用装饰器模式却很好实现
3. 当对象的功能要求可以动态地添加,也可以再动态地撤销时


#### Go语言实现



// 抽象装饰类 type IDecorate interface { Run() }

type Decorate struct { Func func() decorateBefore []IDecorate decorateAfter []IDecorate }

func (d *Decorate) Before(decorate ...IDecorate) { d.decorateBefore = append(d.decorateBefore, decorate...) }

func (d *Decorate) After(decorate ...IDecorate) { d.decorateAfter = append(d.decorateAfter, decorate...) }

func (d *Decorate) Run() { for _, decorateBefore := range d.decorateBefore { decorateBefore.Run() } d.Func() for _, decorateAfter := range d.decorateAfter { decorateAfter.Run() } }

// 具体装饰类 type ADecorate struct { }

func (d *ADecorate) Run() { fmt.Println("执行A") }

type BDecorate struct { }

func (d *BDecorate) Run() {

img img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!