一.什么是结构型模式?
结构型模式就是从程序的结构上解决模块之间的耦合问题。
二.结构型模式有哪几类?
结构型模式分为类结构型模式和对象结构型模式
类结构型模式关心类的组合,由多个类可以组合成一个更大的系统,在类结构型模式中一般只 存在继承关系和实现关系
对象结构型模式关系类与对象的组合,通过关联关系使得在一个类中定义另一个类的实例对象,然后通过该对象调其方法。
三.结构型模式有几种?
1.适配器模式
(1)定义:
将一个类的接口转换成客户希望的另外一接口,适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
例如:我们现在的电脑要连接扩展屏,由于现在的新款电脑上面没有VGA接口,只有USB接口,这时候我们就需要一个适配器(VGA转接头),来扩展出一个VGA接口来。
(2)适配器的优点:
将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,而无须修改原有代码
增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性
灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”。
2.桥接模式
(1)定义:
将抽象部分与它的实现部分分离,使它们都可以独立地变化
例如:现在我们需要开发一个跨平台视频播放器,可以在不同的操作系统平台(如Windows、Linux、Unix等)上播放多种格式的视频文件,常见的视频格式包括MPEG、RMVB、AVI、WMV等。这时候我们就可以考虑运用桥接模式,
(2)桥接模式的优点:
分离抽象接口与实现部分
桥接模式是比多继承方法更好的解决办法
桥接模式提高了系统的可扩充性,在两个变化维护中任意扩展一个维护,都不需要修改原有的系统
实现细节对客户透明,可以对客户隐藏实现细节
(3)桥接模式缺点:
桥接模式的引入会增加系统的理解与设计难度
桥接模式要求正确识别出系统中两个独立变化的维护,因此使其范围具有一定的局限性
(4)桥接模式的适用环境
如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系
一个类存在两个独立变化的维度,且这两个维度都需要进行扩展
对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
3.组合模式
(1)定义:将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性
(2)模式分析
组合模式的关键是定义了一个抽象构件类,它既可以代表叶子,又可以代表容器,而客户端针对该抽象构件类进行编程,无须知道它到底表示的是叶子还是容器,可以对其进行统一处理。
同时容器对象与抽象构件之间还建立一个聚合关联关系,在容器对象中可以包含叶子,也可以包含容器,以此实现递归组合,形成一个树形结构。
(3)组合模式优点:
可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,使得增加新构件也更容易
客户端调用简单,客户端可以一致的使用组合结构或其中单个对象。
定义了包含叶子对象和容器对象的类层次结构,叶子对象可以被组合成更复杂的容器对象,而这个容器对象又可以被组合,这样不断递归下去可以形成复杂的树形结构
更容易在组合体内加入对象构件,客户端不必因为加入了新的对象构件而更改原有的代码
(4)组合模式缺点:
使设计模式变得更加抽象,对象的业务规则如果很复杂,则实现组合模式具有很大挑战性,而且不是所有的方法都与叶子对象子类都有关联。
增加新构件时可能会产生一些问题,很难对容器中的构件类型进行限制。
组合模式的适用范围:
需要表示一个对象整体或部分层次,在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,可以一致地对待他们。
让客户能够忽略不同对象层次的变化,客户端可以针对抽象构件编程,无须关心对象层次结构的细节
对象的结构是动态的并且复杂程度不一样,但客户需要一致地处理它们。
4.装饰模式:
(1)定义:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更加灵活。
(2)模式分析
与继承关系相比,关联关系的主要优势在于不会破坏类的封装性,而且继承是一种耦合度较大的静态关系,无法在程序运行时动态扩展。
使用装饰模式来实现扩展比继承更加灵活,它以对客户透明的方式动态地给一个对象附近加更多的责任。装饰模式可以在不需要创建更多子类的情况下,将对象的功能加以扩展。
(3) 装饰模式的优点:
装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性
可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的装饰器,从而实现不同的行为。
通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同的行为的组合。
具体构件类与具体装饰类可以独立变化
(4) 装饰模式的缺点:
使用装饰模式进行系统设计时将产生很多小对象,同时还将产生很多具体装饰类。这些装饰类和小对象的产生将增加系统的复杂度,加大学习与理解的难读。
装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为繁琐。
5外观模式:
(1)定义:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
(2)模式分析
根据“单一职责原则”,在软件中将一个系统划分为若干个子系统有利于降低整个系统的复杂性,一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小,而达到该目标的途径之一就是引入一个外观对象,它为子系统的访问提供了一个简单而单一的入口。
外观模式也是“迪米特法则”的体现,通过引入一个新的外观类可以降低原有系统的复杂度,同时降低客户类与子系统类的耦合度。
(3)外观模式的优点:
对客户屏蔽子系统组件,减少了客户处理的对象数目并使系统使用起来更加容易。
实现了子系统与客户之间的松耦合关系
降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程。
只是提供了一个访问子系统的同一入口,并不影响用户直接使用子系统类
(4)外观模式的缺点:
不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性
在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”
6.享元模式:
(1)定义:为运用共享技术有效地支持大量细粒度的对象
(2)模式分析:
享元模式是一个考虑系统性能的设计模式,通过使用享元模式可以节约内存空间,提高系统的性能
享元模式的核心在于享元工厂类,享元工厂的作用在于提供一个用于存储享元对象的享元池,用户需要对象时,首先从享元池中获取,如果享元池中不存在,则创建一个新的享元对象返回给用户,并在享元池中保存该新增对象。
(3)享元模式优点:
享元模式的优点在于它可以极大减少内存中对象的数目,使得相同对象或相似对象在内存中只保持一份。
享元模式的外部状态相对独立,而且不影响其内部状态,从而使得享元对象可以在不同的环境中被共享
(4)享元模式缺点:
享元模式使得系统更加复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化
为了使对象可以共享,享元模式需要将享元对象的状态外部化,而读取外部状态使得运行时间变长
7.代理模式:
(1)定义:为其他对象提供一种代理以控制对这个对象的访问
(2)举例说明:
在某种情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接的引用
代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务。
(3)代理模式的优点:
代理模式能过协调调用者和被调用者,在一定程度上降低了系统的耦合度
远程代理使得客户端可以访问在远程机器上的对象,远程机器可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求
虚拟代理通过使用一个小对象来代表一个大对象,可以减少系统资源消化,对系统进行优化并提高运行速度
保护代理可以控制对真实对象的使用权限
(4)代理模式的缺点:
由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢
实现代理模式需要额外的工作,有些代理模式的实现非常复杂