首页 > 技术文章 > 设计模式

hongyedeboke 2017-04-18 22:31 原文

A pattern is a solution to a problem in a context(特定环境).

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。

一、设计模式的分类

按照目的,设计模式分为三大类:

1.创建型模式(Creational用于创建对象),共五种:工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)、单例模式(Singleton)、建造者模式(Builder)、原型模式(Prototype)。

2.结构型模式(Structural用于处理类或对象的组合),共七种:适配器模式(Adapter)、装饰器模式(Decorator)、代理模式(Proxy)、外观模式(Facade)、桥接模式(Bridge)、组合模式(Composite)、享元模式(Flyweight)。

3.行为型模式(Behavioral用于描述类或对象怎样交互和怎样分配职责),共十一种:策略模式(Strategy)、模板方法模式(Template Method)、观察者模式(Observer)、迭代器模式(Iterator)、责任链模式(Chain of Responsibility)、命令模式(Command)、备忘录模式(Memento)、状态模式(State)、访问者模式(Visitor)、中介者模式(Mediator)、解释器模式(Interpreter)。

根据范围,即模式主要是用于处理类之间关系还是处理对象之间的关系,可分为类模式对象模式两种:

1.类模式(处理类和子类之间的关系,这些关系通过继承建立,在编译时刻就被确定下来,是属于静态的),共 4种:工厂方法模式、适配器模式、解释器模式、模板方法模式。
2.对象模式(处理对象间的关系,这些关系在运行时刻变化,更具动态性),其余都是对象模式。

二、设计模式的六大原则

1、开闭原则(Open Close Principle)

开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类。

2、里氏代换原则(Liskov Substitution Principle)

里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

3、依赖倒转原则(Dependence Inversion Principle)

这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。

4、接口隔离原则(Interface Segregation Principle)

这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。降低依赖,降低耦合。

5、迪米特法则(最少知道原则)(Demeter Principle)

为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。

6、合成复用原则(Composite Reuse Principle)

原则是尽量使用合成/聚合的方式,而不是使用继承。

 三、Java的23个设计模式

1.简单工厂模式

又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。 

模式分析:

将对象的创建和对象本身业务处理分离可以降低系统的耦合度

简单工厂模式最大的问题在于工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,这一点与开闭原则是相违背的。
简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节

在以下情况下可以使用简单工厂模式:
工厂类负责创建的对象比较少;

客户端只知道传入工厂类的参数,对于如何创建对象不关心。

模式应用:

(1) 在JDK类库中广泛使用了简单工厂模式,如工具类java.text.DateFormat,它用于格式化一个本地日期或者时间。

(2) Java加密技术。

 2.工厂方法模式

又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。

模式分析:

在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不负责哪一个产品类被实例化这种细节,这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品,很好地符合了“开闭原则”。 

在以下情况下可以使用工厂方法模式:

一个类不知道它所需要的对象的类;
一个类通过其子类来指定创建哪个对象;
将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。

  3.抽象工厂方法模式

又称为Kit模式。提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

先引入两个概念:

产品等级结构:产品等级结构即产品的继承结构;
产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。

抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构。

模式图:

例子:

 

优点:

1.隔离了具体类的生成,只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。
2.应用抽象工厂模式可以实现高内聚低耦合的设计目的。

3.能够保证客户端始终只使用同一个产品族中的对象。
4.增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。

 

推荐阅读