设计模式之结构型模式

设计模式之结构型模式

适配器模式

适配器模式(Adapter),将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作

image-20230206160300758

Target(这是客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口)代码如下。

image-20230206160322417

Adaptee(需要适配的类)代码如下。

image-20230206160333084

Adapter(通过在内部包装一个Adaptee对象,把源接口转换成目标接口)代码如下。

image-20230206160345511

客户端代码:

image-20230206160356950

桥接模式

桥接模式(Bridge),将抽象部分与它的实现部分分离,使它们都可以独立地变化

image-20230206161217356

这里需要理解一下,什么叫抽象与它的实现分离,这并不是说,让抽象类与其派生类分离,因为这没有任何意义。实现指的是抽象类和它的派生类用来实现自己的对象。就刚才的例子而言,就是让’手机’既可以按照品牌来分类,也可以按照功能来分类。

1、按品牌分类实现结构图

image-20230206160723732

2、按软件分类实现结构图

image-20230206160738148

3、由于实现方式有多种,桥接模式的核心意图是把这些实现独立出来,让它们各自变化。这就使得每种实现的变化不会影响其他实现,从而达到应对变化的目的

image-20230206160802888

手机软件抽象类:

image-20230206161028933

游戏、通讯录等具体类:

image-20230206161036811

手机品牌类:

image-20230206161047414

品牌N品牌M具体类:

image-20230206161101040

客户端代码:

image-20230206161108948

image-20230206161113469

现在如果要增加一个功能,比如手机音乐播放功能,那么只要增

加这个类就行了。不会影响其他任何类。类的个数增加也只是一个

image-20230206161128081

组合模式

组合模式(Composite),将对象组合成树形结构以表示’部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

image-20230206161700189

Component为组合中的对象声明接口,在适当情况下,实现所有类共有接

口的默认行为。声明一个接口用于访问和管理Component的子部件。

image-20230206161949371

image-20230206161954264

Leaf在组合中表示叶节点对象,叶节点没有子节点。

image-20230206162005711

Composite定义有枝节点行为,用来存储子部件,

在Component接口中实现与子部件有关的操作,比如增加add和删除remove。

image-20230206162013734

客户端代码,能通过Component接口操作组合部件的对象。

image-20230206162024189

image-20230206162029232

结果显示:

image-20230206162035326

当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式了。

装饰器模式

装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。

image-20230206162453272

Component是定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职 责 。 Decorator , 装 饰 抽 象 类 , 继 承 了 Component , 从 外 类 来 扩 展Component类的功能,但对于Component来说,是无须知道Decorator的存在

的。至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能

image-20230206162524991

image-20230206162531078

image-20230206162539171

image-20230206162545247

image-20230206162554298

image-20230206162602734

image-20230206162608937

装饰模式是利用SetComponent来对对象进行包装的。这样每个装饰对象的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中

image-20230206162656878

第二例子

image-20230207090330143

ICharacter接口(Component):

image-20230207090345906

Person类(ConcreteComponent):

image-20230207090355855

Finery类(Decorator):

image-20230207090419948

具体服饰类(ConcreteDecorator):

image-20230207090453344

其余类类似,省略。

客户端代码:

image-20230207090503472

image-20230207090517668

结果显示:

image-20230207090545098

外观模式

外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

​ 外观模式(Facade)结构图

image-20230207090809333

四个子系统的类:

image-20230207090926037

外观类:

image-20230207090937322

客户端调用:

image-20230207090943928

"那外观模式在什么时候使用最好呢?

这要分三个阶段来说。首先,在设计初期阶段,应该要有意识地将不同的两个层分离,比如经典的三层架构,就需要考虑在数据访问层和业务逻辑层、业务逻辑层和表示层的层与层之间建立外观Facade,这样可以为复杂的子系统提供一个简单的接口,使得耦合大大降低。其次,在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂,大多数的模式使用时也都会产生很多很小的类,这本是好事,但也给外部调用它们的用户程序带来了使用上的困难,增加外观Facade可以提供一个简单的接口,减少它们之间的依赖。第三,在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了,但因为它包含非常重要的功能,新的需求开发必须要依赖于它。此时用外观模式Facade也是非常合适的。你可以为新系统开发一个外观Facade类,来提供设计粗糙或高度复杂的遗留代码的比较清晰简单的接口,让新系统与Facade对象交互,Facade与遗留代码交互所有复杂的工作

image-20230207091102393

享元模式

享元模式(Flyweight),运用共享技术有效地支持大量细粒度的对象

​ 享元模式(Flyweight)结构图

image-20230207091454116

Flyweight类,是所有具体享元类的超类或接口,通过这个接口,Flyweight可以接受并作用于外部状态。

image-20230207091636731

ConcreteFlyweight是继承Flyweight超类或实现Flyweight接口,并为内部状态增加存储空间。

image-20230207091655878

UnsharedConcreteFlyweight是指那些不需要共享的Flyweight子类。因为Flyweight接口共享成为可能,但它并不强制共享。

image-20230207091709104

FlyweightFactory是一个享元工厂,用来创建并管理Flyweight对象。它主要是用来确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)。

image-20230207091736076

客户端代码:

image-20230207091746324

结果显示:

image-20230207091757744

在享元对象内部并且不会随环境改变而改变的共享部分,可以称为享元对象的内部状态,而随环境改变而改变的、不可以共享的状态就是外部状态了。事实上,享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本上都是相同的,有时就能够大幅度地减少需要实例化的类的数量。如果能把那些参数移到类实例的外面,在方法调用时将它们传递进来,就可以通过共享大幅度地减少单个实例的数目

第二版–网站共享代码

image-20230207092152516

用户类,用于网站的客户账号,是"网站"类的外部状态。

image-20230207092208834

网站抽象类:

image-20230207092226883

具体网站类:

image-20230207092239621

网站工厂类:

image-20230207092258352

客户端代码:

image-20230207092309056

结果显示,尽管给六个不同用户使用网站,但实际上只有两个网站实例

image-20230207092325757

代理模式

代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问。

image-20230207092522981

ISubject类,定义了RealSubject和Proxy的共用接口,这样就在任何使用RealSubject的地方都可以使用Proxy。

image-20230207092537444

RealSubject类,定义Proxy所代表的真实实体。

image-20230207092548563

Proxy类,保存一个引用使得代理可以访问实体,并提供一个与Subject的接口相同的方法,这样代理就可以用来替代实体。

image-20230207092559881

客户端代码:
在这里插入图片描述

参考:大话设计模式–程杰

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值