软件设计模式

一、设计模式分类

总体来说设计模式分为三大类:

五种创建型模式:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

七种结构型模式:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

十一种行为型模式:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。


二、设计模式概述

创建模式

1、简单工厂方法

  • 创建产品接口/抽象类
  • 创建产品接口实现类/抽象类实现类
  • 创建工厂类:通过工厂类可以实现对各种实现类的实例化并向上转型为接口/抽象类对象

优点:对象创建和使用实现了解耦,符合面向对象原则和面向接口编程

缺点:违背了开闭原则(软件中的对象应该对于扩展是开放的,但是对于修改是封闭的),新接口方法的实现必须依赖工厂


2、工厂方法

  • 创建产品接口类
  • 创建产品接口实现类:各个实现类有不同的实现
  • 创建工厂接口类:接口方法的返回值是产品接口
  • 创建工厂接口实现类:各实现类创建不同的产品类,返回对象是产品接口

优点:功能拓展不在受限于工厂接口类,工厂实现类可以自由实现

缺点:如果有新的产品接口方法增加,工厂类也需要跟着增加


3、抽象工厂

  • 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
  • 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
  • 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
  • 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。

与工厂方法的区别是抽象产品由一个变为多个,抽象工厂(工厂接口类)有多个生产不同抽象产品的接口


4.单例模式

单例模式能保证一个类仅有一个实例,并提供一个访问它的全局访问点,同时在类内部创造单一对象,通过设置权限,使类外部无法再创造对象。


5.构建者模式

  • Product: 最终要生成的对象,例如 Computer实例。
  • Builder: 构建者的抽象基类(有时会使用接口代替)。其定义了构建Product的抽象步骤,其实体类需要实现这些步骤。其会包含一个用来返回最终产品的方法Product getProduct()
  • ConcreteBuilder: Builder的实现类。
  • Director: 决定如何构建最终产品的算法. 其会包含一个负责组装的方法void Construct(Builder builder), 在这个方法中通过调用builder的方法,就可以设置builder,等设置完成后,就可以通过builder的 getProduct() 方法获得最终的产品。

6.原型模式

原型模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用原型模式。

  • 原型接口类:规定了具体原型对象必须实现的接口,例如clone接口。
  • 具体原型类:实现抽象原型类的 clone() 方法,返回对象就是自身。
  • 访问类:使用具体原型类中的 clone() 方法来复制新的对象。


结构性模式

7、适配器模式

将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作

  • Target:客户端client所使用的目标接口,可以是接口或抽象类。
  • Adaptee:需要适配的类接口。
  • Adapter:适配器,负责Adaptee的接口与Target接口进行适配。
  • Client:与符合Target接口的对象协调的类。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package adapter;
//目标接口
interface Target
{
public void request();
}
//适配者接口
class Adaptee
{
public void specificRequest()
{
System.out.println("适配者中的业务代码被调用!");
}
}
//类适配器类
class ClassAdapter extends Adaptee implements Target
{
public void request()
{
specificRequest();
}
}
//客户端代码
public class ClassAdapterTest
{
public static void main(String[] args)
{
System.out.println("类适配器模式测试:");
Target target = new ClassAdapter();
target.request();
}
}

优点:目标类与适配器类进行解藕,解决两者不一致的问题

缺点:提高系统复杂度,降低代码阅读性


8.装饰模式

装饰器模式是动态地给一个对象添加一些额外的职责,给一个对象增加一些新的功能,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。除了动态的增加,也可以动态的撤销,要做到动态的形式,不可以用继承实现,因为继承是静态的。


9.代理模式

代理模式是为其他对象提供一种代理以控制对这个对象的访问,也就是创建类的代理类,间接访问被代理类的过程中,对其功能加以控制。它和装饰器模式的区别在于,装饰器模式为了增强功能,而代理模式是为了加以控制。代理模式就是多一个代理类出来,替原对象进行一些操作,例如买火车票不一定在火车站买,也可以去代售点。再比如打官司需要请律师,因为律师在法律方面有专长,可以替我们进行操作。


10.外观模式

外观模式是为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。在客户端和复杂系统之间再加一层,提供一个容易使用的外观层。外观模式是为了解决类与类之家的依赖关系的,外观模式就是将他们的关系放在一个Facade类中,降低了类类之间的耦合度,比如搜狐门户网站,就利用了外观模式。


11.桥接模式

桥接模式是将抽象部分与实现部分分离,使它们都可以独立的变化。桥接模式就是把事物和其具体实现分开,使他们可以各自独立的变化(突然联想到了mvc模式)。将抽象化与实现化解耦,使得二者可以独立变化,就好比现在常说的mvc模式,view和model之间通过control来控制,达到高内聚低耦合来解耦的目的。


12.组合模式

组合模式是将对象组合成树形结构以表示”部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。创建了一个包含自己对象组的类,并提供修改对象组的方法。在系统的文件和文件夹的问题上就使用了组合模式,文件下不可以有对象,而文件夹下可以有文件对象或者文件夹对象。


13.享元模式

享元模式是运用共享技术有效地支持大量细粒度的对象。享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,重用现有的同类对象,若未找到匹配的对象,则创建新对象,这样可以减少对象的创建,降低系统内存,提高效率。



行为型模式

14.策略模式

策略模式是定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换,且算法的变化不会影响到使用算法的客户。。是为了统一接口下的一系列算法类(也就是多种策略),用一个类将其封装起来,使这些策略可动态切换。策略模式属于行为型模式,是为了使这些策略可以相互切换,是为了选择不同的行为。


15.模版方法模式

模板方法模式是定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。该模式就是在一个抽象类中,有一个主方法,再定义1…n个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤,将一些固定步骤、固定逻辑的方法封装成模板方法。调用模板方法即可完成那些特定的步骤。


16.观察者模式

观察者模式是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。也就是当被观察者状态变化时,通知所有观察者,这种依赖方式具有双向性,在QQ邮箱中的邮件订阅和RSS订阅,当我们浏览一些博客时,经常会看到RSS图标,意思就是,当你订阅了该文章,如果后续有更新,会及时通知你。这种现象即是典型的观察者模式。

Subject:就是“被观察”的角色,它将所有观察者对象的引用保存在一个集合中。

Observer:是抽象的“观察”角色,它定义了一个更新接口,使得在被观察者状态发生改变时通知自己。

ConcreteObserver:具体的观察者。


17.迭代器模式

迭代器模式是提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。在Java当中,将聚合类中遍历各个元素的行为分离出来,封装成迭代器,让迭代器来处理遍历的任务;使简化聚合类,同时又不暴露聚合类的内部,在我们经常使用的JDK中各个类也都是这些基本的东西。


18.责任链模式

责任链模式是避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。有多个对象,每个对象持有对下一个对象的引用,这样就会形成一条链,请求在这条链上传递,直到某一对象决定处理该请求。但是发出者并不清楚到底最终那个对象会处理该请求。在生活中学生进行请假的过程中,会涉及到,学生请假会一级一级往上批,最终处理,具体由谁批准可能不清楚。在程序当中,现在使用的struts拦截器即用到了责任链模式。


19.命令模式

命令模式是将一个请求封装成一个对象,从而使发出者可以用不同的请求对客户进行参数化。模式当中存在调用者、接收者、命令三个对象,实现请求和执行分开;调用者选择命令发布,命令指定接收者。举个例子,司令员下令让士兵去干件事情,司令员的作用是发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行。司令士兵命令三者相互解耦,任何一方都不用去依赖其他人。其实struts框架也涉及到命令模式的思想。


20.备忘录模式

备忘录模式是在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。创建一个备忘录类,用来存储原始类的信息;同时创建备忘录仓库类,用来存储备忘录类,主要目的是保存一个对象的某个状态,以便在适当的时候恢复对象,也就是做个备份。在系统当中使用的撤销操作,即是使用了备忘录模式,系统可以保存有限次数的文件状态,用户可以进行上几个状态的恢复,也就是用到了备忘录模式。


21.状态模式

状态模式是允许对象在内部状态发生改变时改变它的行为。对象具有多种状态,且每种状态具有特定的行为。在网站的积分系统中,用户具有不同的积分,也就对应了不同的状态;还有QQ的用户状态有几种状态,在线、隐身、忙碌等,每个状态对应不同的操作,而且你的好友也能看到你的状态。


22.访问者模式

访问者模式主要是将数据结构与数据操作分离。在被访问的类里面加一个对外提供接待访问者的接口,访问者封装了对被访问者结构的一些杂乱操作,解耦结构与算法,同时具有优秀的扩展性。通俗来讲就是一种分离对象数据结构与行为的方法,通过这种分离,可达到为一个被访问者动态添加新的操作而无需做其它的修改的效果。访问者模式的优点是增加操作很容易,因为增加操作意味着增加新的访问者。访问者模式将有关行为集中到一个访问者对象中,其改变不影响系统数据结构。


23.中介者模式

中介者模式是用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。例如,MVC模式中control就是model和view的中介者。与适配器区别在于,适配器是为了兼容不同的接口,而中介者是为了将显示和操作分离。


24.解释器模式

解释器模式是给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子,基本也就用在这个范围内,适用面较窄,例如:正则表达式的解释等。




参考资料:

https://blog.csdn.net/varyall/article/details/82355964



版权声明:本文为博主原创文章,欢迎转载,转载请注明作者、原文超链接,感谢各位看官!!!

本文出自:monkeyGeek

座右铭:生于忧患,死于安乐

欢迎志同道合的朋友一起交流、探讨!

monkeyGeek
#

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×