结构型模式

Java 中一般认为有23 种设计模式,我们不需要所有的都会,但是其中常用的几种设计模式应该去掌握。
下面列出了所有的设计模式。需要掌握的设计模式我单独列出来了,当然能掌握的越多越好。
总体来说设计模式分为三大类:
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

总结:每一种设计模式,代码去理解实现方式,根据结构图记忆理解。本文没有给出具体代码,可以在码云下载代码使用,本文适合不断翻看理解这些设计模式

 

1.适配器模式 adapter

分类
类适配器、对象适配器、接口适配器
UML图

 

 

 

适配器模式应用场景
类适配器与对象适配器的使用场景一致,仅仅是实现手段稍有区别,二者主要用于如下场景
(1)想要使用一个已经存在的类,但是它却不符合现有的接口规范,导致无法直接去访问,这时创建一个适配器就能间接去访问这个类中的方法。
(2)我们有一个类,想将其设计为可重用的类(可被多处访问),我们可以创建适配器来将这个类来适配其他没有提供合适接口的类。
接口适配器使用场景:
1)想要使用接口中的某个或某些方法,但是接口中有太多方法,我们要使用时必须实现接口并实现其中的所有方法,可以使用抽象类来实现接口,并不对方法进行实现(仅置空),然后我们再继承这个抽象类来通过重写想用的方法的方式来实现。这个抽象类就是适配器。

2.装饰器模式 decorator

 

 

 

Component为统一接口,也是装饰类和被装饰类的基本类型。
ConcreteComponent为具体实现类,也是被装饰类,他本身是个具有一些功能的完整的类。
Decorator是装饰类,实现了Component接口的同时还在内部维护了一个ConcreteComponent的实例,并可以通过构造函数初始化。而Decorator本身,通常采用默认实现,他的存在仅仅是一个声明:我要生产出一些用于装饰的子类了。而其子类才是赋有具体装饰效果的装饰产品类。
ConcreteDecorator是具体的装饰产品类,每一种装饰产品都具有特定的装饰效果。可以通过构造器声明装饰哪种类型的ConcreteComponent,从而对其进行装饰。
优点:
装饰器模式是一种用于代替继承的技术,无需通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。

3.代理模式 proxy

 

 

 

AOP中使用场景
事务代理(声明式事务, 哪个方法需要加事务, 哪个方法不需要加事务)
日志监听
假如我们定义了一个service 方法
开启一个事务(open) 代理来做
事务的执行 执行我们的service方法
监听到是否有异常, 可能需要根据异常的类型来决定这个事务是否要回滚还是继续提交 代理来做
(commit/rollback) 代理来做
事务要关闭(close) 代理来做

4.外观模式 Facade (门面模式)

概念:
外观模式(Facade),他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口。这种类型的设计模式属于结构性模式。为子系统中的一组接口提供了一个统一的访问接口,这个接口使得子系统更容易被访问或者使用。

 

 

 

简单来说,该模式就是把一些复杂的流程封装成一个接口供给外部用户更简单的使用。这个模式中,设计到3个角色。
  1).门面角色:外观模式的核心。它被客户角色调用,它熟悉子系统的功能。内部根据客户角色的需求预定了几种功能的组合。
  2).子系统角色:实现了子系统的功能。它对客户角色和Facade时未知的。它内部可以有系统内的相互交互,也可以由供外界调用的接口。
  3).客户角色:通过调用Facede来完成要实现的功能

5.桥接模式 Bridge

1.桥接模式的优点
(1)实现了抽象和实现部分的分离
桥接模式分离了抽象部分和实现部分,从而极大的提供了系统的灵活性,让抽象部分和实现部分独立开来,分别定义接口,这有助于系统进行分层设计,从而产生更好的结构化系统。对于系统的高层部分,只需要知道抽象部分和实现部分的接口就可以了。
(2)更好的可扩展性
由于桥接模式把抽象部分和实现部分分离了,从而分别定义接口,这就使得抽象部分和实现部分可以分别独立扩展,而不会相互影响,大大的提供了系统的可扩展性。
(3)可动态的切换实现
由于桥接模式实现了抽象和实现的分离,所以在实现桥接模式时,就可以实现动态的选择和使用具体的实现。
(4)实现细节对客户端透明,可以对用户隐藏实现细节。
2.桥接模式的缺点
(1)桥接模式的引入增加了系统的理解和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程。
(2)桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围有一定的局限性。
3.桥接模式的使用场景
(1)如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
(2)抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
(3)一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
(4)虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。
(5)对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用

6.组合模式 Composite

 

 

1.角色组成
抽象构件角色(component):是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。这个接口可 以用来管理所有的子对象。(可选)在递归结构中定义一个接口,用于访问一个父部件,并在合适的情况下实现它。
树叶构件角色(Leaf):在组合树中表示叶节点对象,叶节点没有子节点。并在组合中定义图元对象的行为。
树枝构件角色(Composite):定义有子部件的那些部件的行为。存储子部件。在Component接口中实现与子部件有关的操作。
客户角色(Client):通过component接口操纵组合部件的对象。

2、组合模式的优缺点
优点:
组合模式使得客户端代码可以一致地处理对象和对象容器,无需关系处理的单个对象,还是组合的对象容器。
将”客户代码与复杂的对象容器结构“解耦。
可以更容易地往组合对象中加入新的构件。
缺点: 使得设计更加复杂。客户端需要花更多时间理清类之间的层次关系。(这个是几乎所有设计模式所面临的问题)。
注意的问题:
有时候系统需要遍历一个树枝结构的子构件很多次,这时候可以考虑把遍历子构件的结构存储在父构件里面作为缓存。
客户端尽量不要直接调用树叶类中的方法(在我上面实现就是这样的,创建的是一个树枝的具体对象;),而是借用其父类(Graphics)的多态性完成调用,这样可以增加代码的复用性。
3、组合模式的使用场景
在以下情况下应该考虑使用组合模式:
当想表达对象的部分-整体的层次结构时。
希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象时。

7.享元模式 Flyweight Pattern

享元模式:以共享的方式高效的支持大量的细粒度对象。通过复用内存中已存在的对象,降低系统创建对象实例的性能消耗。
java的 String 类型就是享元模式

视频链接:https://www.bilibili.com/video/BV1vK411L7n1/

posted @ 2020-04-08 16:31  李李林  阅读(256)  评论(0)    收藏  举报