设计模式学习总结--结构型

外观模式
定义:又叫门面模式,提供了一个统一的接口,用来访问子系统中的一群接口;外观模式定义了一个高层接口,让子系统更容易使用
适用场景:子系统越来越复杂,增加外观模式提供简单调用接口;构建多层系统结构,利用外观对象作为每层的入口,简化层之间调用
优点:简化了调用过程,无需了解深入子系统,防止带来风险;减少系统依赖、松散耦合;更好的划分访问层次;符合迪米特法则,及最少知道法则
缺点:增加子系统、扩展子系统行为容易引入风险;不符合开闭原则

相关的设计模式:中介者模式、单例模式、抽象工厂模式
外观模式:关注的是外界和子系统间的交互
中介者模式:关注的是子系统内部之间的交互
单例模式:可以将外观模式中的外观对象做成单例来结合使用
抽象工厂模式:外观类可以通过抽象工厂获取子系统实例,这样子系统可以在内部对外观类进行屏蔽


装饰者模式
定义:在不改变原有对象的基础之上,将功能附加到对象上;提供了比继承更有弹性的替代方案(扩展原有对象功能)
适用场景:扩展一个类的功能或给一个类添加附加职责;动态地给一个对象添加功能,这些功能可以再动态的撤销
优点:继承的有力补充,比继承灵活,不改变原有对象的情况下给一个对象扩展功能;通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同的效果;符合开闭原则
缺点:会出现更多的代码、更多的类,增加程序复杂性;动态装饰时、多层装饰时会更复杂(装饰者会继承被装饰对象,而被装饰对象有具体的实体,导致他们在父类上看起来像是同一类对象,在排查错误时会增加一定的复杂对)

相关设计模式:
装饰者模式:关注在一个对象上动态的添加方法,在使用装饰者模式时会通常将原始对象作为一个参数传给装饰者的构造器;装饰者跟被装饰者可以实现相同的接口或者装饰者是被装饰者的子类,装饰模式可以退化成半装饰者(除了提供被装饰类接口外其他方法)
代理模式:关注于控制对对象的访问,代理类可以对他的客户隐藏一个对象的具体信息,通常在使用代理模式时常常在一个代理类中创建一个代理类的实例
适配器模式:(跟装饰者模式都可以叫做包装模式),适配器和被适配的类具有不同的接口,也有可能有部分的接口是重合的


适配器模式
定义:将一个类的接口转换成客户期望的另一个接口;使原本接口不兼容的类可以一起工作
适用场景:已经存在的类,它的方法和需求不匹配时(方法结果相同或相似);不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不同厂家造成功能类似而接口不相同情况下的解决方案
优点:能提高类的透明性和复用,现有的类复用但不需要改变;目标类和适配器类解耦,提高程序可扩展性;符合开闭原则
缺点:适配器编写过程需要全面考虑,可能会增加系统的复杂性;增加系统代码可读的难度

扩展——分类
对象适配器:符合组合复用原则,并且使用委托机制
类适配器:通过继承来实现

相关设计模式
适配器模式和外观模式都是对现有的类、现成的系统的封装
适配器模式:复用一个原有的接口,指两个已有接口协同工作;最大的区别是是配的粒度不同
外观模式:定义了新的接口,在现有的系统中提供一个更为方便的访问入口;外观针对的对象粒度更大,适配整个子系统


享元模式(重点是共享)
定义:提供了减少对象数量从而改善应用所需的对象结构的方式;运用共享技术有效地支持大量细粒度的对象(减少创建对象的数量,从而减少对内存的占用,并且提高性能)
适用场景:常常应用与系统底层的开发,以便解决系统的性能问题;系统有大量的相似对象、需要缓冲池的场景(注意复用程度)
优点:减少对象的创建,降低内存中对象的数量,降低系统的内存,提高效率;减少内存之外的其他资源占用
缺点:关注内/外部状态、关注线程安全问题;是系统、程序的的逻辑复杂化

扩展
内部状态:在享元对象的内部并且不会随着环境改变而改变的共享部分
外部状态:随着环境改变而改变的,不可以共享的部分

相关设计模式:
享元模式和代理模式:生成代理对象需要花费的代价较大(资源、时间),那么就可以使用享元模式来提高程序的处理速度
享元模式和单例模式:容器单例


组合模式(最关键的是叶子对象和组合对象实现相同的接口/继承相同的类)
定义:将对象组合成树形结构以表示“部分-整体”的层次结构;组合模式使客户端对单个对象和组合对象保持一致的方式处理(如菜单、目录等)
适用场景:希望客户端可以忽略组合对象与单个对象的差异时(一视同仁);处理一个树形结构时
优点:清楚地定义分层次的复杂对象,表示对象的全部或部分层次;让客户端忽略了层次的差异,方便对整个层次结构进行控制;简化客户端代码;符合开闭原则
缺点:限制类型时会较为复杂;使设计变得更加抽象

相关设计模式:
组合模式和访问者模式:在组合应用中,通过访问者模式来访问组合模式中的递归结构


桥接模式(重点是理解抽象部分和具体实现部分)
定义:将抽象部分与它的具体实现部分分离,使它们都可以独立地变化;通过组合的方式建立两个类之间的联系,而不是继承
适用场景:抽象和具体实现之间增加更多的灵活性(避免在这两个层次之间简历静态的继承关系,通过桥接模式使它们之间建立一层关联关系,另外抽象部分和具体实现部分都可以以继承的方式独立扩展并且互不影响,就可以动态的将一个抽象化的子类对象和一个具体实现化的子类对象进行组合,那么系统对抽象化的角色和具体实现化的角色实现了解耦);一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展;不希望使用继承,或因为多层继承导致系统类的个数剧增
优点:分离抽象部分及其具体实现部分;提高了系统的可扩展性;符合开闭原则;符合合成复用原则
缺点:增加了系统的理解与设计难度;需要正确的识别出系统中两个独立变化的维度

相关设计模式:
桥接模式和组合模式:组合模式更强调的是部分和整体之间的组合;组合模式强调的是平行级别上同类的组合
桥接模式和适配器模式:都是为了让两个东西配合工作。但是目的不一样:适配器模式是改变已有的接口,让它们之间可以相互配合(把功能上相似但是接口不同的类适配起来);而桥接模式是分离抽象和具体的实现,它的目的是分离(把类的抽象和类的具体实现分离开,然后在此基础上使这些层次结构结合起来)


代理模式
定义:为其他对象提供一种代理,以控制对这个对象的访问;代理对象在客户端和目标对象之间起到中介的作用
适用场景:保护目标对象;增强目标对象
优点:代理模式能将代理对象与真实被调用的目标对象分离;一定程度上降低了系统的耦合度,扩展性好;保护目标对象;增强目标对象
缺点:代理模式会造成系统设计中类的数目增加;在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;增加系统的复杂度

扩展:
静态代理:在代码中显示定义了一个实现类的代理,在代理类中对同名的方法进行包装,用户通过调用代理类的被包装过的方法调用被目标类的方法,同时对目标方法进行增强;
动态代理:只能对实现了接口的类生成代理,在程序调用到代理类对象时才由JVM真正创建,JVM根据传进来的业务实现类对象创建以及方法名动态创建代理类class文件,该class文件被字节码引擎执行然后通过该代理类的对象进行方法调用;
CGLib:针对类实现生产代理,会生成被代理类的子类,覆盖其中的方法,通过继承与重写实现代理,使用它时要注意被代理类以及目标方法不能被final修饰
代理速度对比:动态代理>CGLib,

相关设计模式:
代理模式和装饰者模式:装饰者模式是为对象加上行为;代理模式是控制访问,更加注重通过设置代理类的方式来增强目标对象,增强目标对象的方式一般是增强目标对象的某些行为
代理模式和适配器模式:适配器模式主要考虑和改变对象的接口,而代理模式是不能改变对象的接口

猜你喜欢

转载自blog.csdn.net/ybbhai/article/details/84979773