一、设计模式概念
在软件工程中,设计模式是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。设计模式包含的关键概念包括:1)模式名称 2)问题 3)解决方案 4)效果。按照《设计模式》一书可以把设计模式可以分为三大类:创建型模式(用于描述”怎样创建对象”,它的主要特点是“将对象的创建与使用分离”)、结构型模式(用于描述如何将类或对象按某种布局组成更大的结构)、行为型模式(用于描述类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,以及怎样分配职责)。
参考链接:维基百科-设计模式
参考链接:GoF 的 23 种设计模式的分类和功能
二、设计模式六大原则
- 开闭原则:对扩展开放,对修改关闭。
- 里氏代换原则:任何基类可以出现的地方,子类一定可以出现。
- 依赖倒转原则:针对接口编程,依赖于抽象而不依赖于具体。
- 接口隔离原则:使用多个隔离的接口,比使用单个接口要好,降低类之间的耦合度。
- 迪米特法则,又称最少知道原则:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。
- 合成复用原则:尽量使用合成/聚合的方式,而不是使用继承。
参考链接:设计模式简介
三、常用设计模式
3.1 工厂模式
工厂方法模式的实质:定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”。
图3-1 工厂模式结构图3.2 抽象工厂模式
抽象工厂模式的实质:提供接口,创建一系列相关或独立的对象,而不指定这些对象的具体类。抽象工厂模式提供了一种方式,可以将一组具有同一主题的单独的工厂封装起来。
图3-2 抽象工厂模式结构图3.3 单例模式
单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点,单例对象的类必须保证只有一个实例存在。该模式的实现形式包括懒汉式和饿汉式。
图3-3 单例模式结构图3.3.1 懒汉式
public class Singleton {
//volatile synchronized保证线程安全性
public static volatile Singleton instance = null;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
3.3.2 饿汉式
public class Singleton {
public static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
3.4 策略模式
该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。该模式包括的角色:1)抽象策略类 2)具体策略类 3)环境类。
图3-4 策略模式结构图3.5 适配器模式
将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。该模式的角色包括:1)目标接口 2)适配者类 3)适配器类,其实现模式包括类适配器和对象适配器。
图3-5 类适配器模式结构图 图3-6 对象适配器结构图3.6 组合模式
将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。该模式包括的角色:1)抽象构件角色 2)树叶构建角色 3)树枝构建角色。组合模式分为透明式的组合模式和安全式的组合模式。
3.6.1 透明模式
在Component中声明所有来管理子对象的方法,其中包括Add,Remove等。这样实现Component接口的所有子类都具备了Add和Remove方法。这样做的好处是叶节点和枝节点对于外界没有区别,它们具备完全一致的接口。
图3-7 透明模式结构图3.6.2 安全模式
在Component中不去声明Add和Remove方法,那么子类的Leaf就不需要实现它,而是在Composit声明所有用来管理子类对象的方法。
图3-8 安全模式结构图
适用场景:1)需要表示一个对象整体与部分的层次结构的场合。2)要求对用户隐藏组合对象与单个对象的不同,用户可以用统一的接口使用组合结构中的所有对象的场合。
3.7 代理模式
由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
图3-9 代理模式结构图3.8 原型模式
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。该模式包含的角色:1)抽象原型类 2)具体原型类 3)访问类。该模式的实现分为浅克隆和深克隆两种方式。浅克隆是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。深克隆不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。
图3-10 原型模式结构图3.9 观察者模式
指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。(发布-订阅模式)该模式的角色包括:1)抽象主题角色 2)抽象主题角色 3)抽象观察者角色 4)具体观察者角色。
图3-11 观察者模式结构图3.10 桥接模式
将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。该模式的角色包括:1)抽象化角色 2)扩展抽象化角色 3)实现化角色 4)具体实现化角色。
图3-12 桥接模式结构图3.11 责任链模式
为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。该模式中,客户只需要将请求发送到责任链上即可,该模式的角色包括:1)抽象处理者角色 2)具体处理者角色 3)客户类角色。
图3-13 责任链模式结构图 图3-14 责任链3.12 装饰模式
在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)。该模式包含的角色:1)抽象构建角色 2)具体构建角色 3)抽象装饰角色 4)具体装饰角色。
图3-15 装饰模式结构图3.13 模板方法模式
定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。该模式包含的角色:1)抽象类[模版方法,基本方法] 2)具体子类。
图3-16 模版方法模式结构图
网友评论