Design Patterns - Simple Factory
# 简单工厂(Simple Factory)
# Intent
在创建一个对象时不向客户暴露内部细节,并提供一个创建对象的通用接口。
# Class Diagram
简单工厂把实例化的操作单独放到一个类中,这个类就成为简单工厂类,让简单工厂类来决定应该用哪个具体子类来实例化。
这样做能把客户类和具体子类的实现解耦,客户类不再需要知道有哪些子类以及应当实例化哪个子类。客户类往往有多个,如果不使用简单工厂,那么所有的客户类都要知道所有子类的细节。而且一旦子类发生改变,例如增加子类,那么所有的客户类都要进行修改。
# Implementation
public interface Product {
}
public class ConcreteProduct implements Product {
}
public class ConcreteProduct1 implements Product {
}
public class ConcreteProduct2 implements Product {
...
Design Patterns - Observer
# 观察者(Observer)
# Intent
定义对象之间的一对多依赖,当一个对象状态改变时,它的所有依赖都会收到通知并且自动更新状态。
主题(Subject)是被观察的对象,而其所有依赖者(Observer)称为观察者。
# Class Diagram
主题(Subject)具有注册和移除观察者、并通知所有观察者的功能,主题是通过维护一张观察者列表来实现这些操作的。
观察者(Observer)的注册功能需要调用主题的 registerObserver () 方法。
# Implementation
天气数据布告板会在天气信息发生改变时更新其内容,布告板有多个,并且在将来会继续增加。
public interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObserver();
}
public class WeatherData implements Subject { ...
Design Patterns - Intepreter
# 解释器(Interpreter)
# Intent
为语言创建解释器,通常由语言的语法和语法分析来定义。
# Class Diagram
TerminalExpression:终结符表达式,每个终结符都需要一个 TerminalExpression。
Context:上下文,包含解释器之外的一些全局信息。
# Implementation
以下是一个规则检验器实现,具有 and 和 or 规则,通过规则可以构建一颗解析树,用来检验一个文本是否满足解析树定义的规则。
例如一颗解析树为 D And (A Or (B C)),文本 “D A” 满足该解析树定义的规则。
这里的 Context 指的是 String。
public abstract class Expression {
public abstract boolean interpret(String str);
}
public class TerminalExpression extends Expression {
private String literal ...
Design Patterns - Singleton
# 单例(Singleton)
# Intent
确保一个类只有一个实例,并提供该实例的全局访问点。
# Class Diagram
使用一个私有构造函数、一个私有静态变量以及一个公有静态函数来实现。
私有构造函数保证了不能通过构造函数来创建对象实例,只能通过公有静态函数返回唯一的私有静态变量。
# Implementation
# Ⅰ 懒汉式 - 线程不安全
以下实现中,私有静态变量 uniqueInstance 被延迟实例化,这样做的好处是,如果没有用到该类,那么就不会实例化 uniqueInstance,从而节约资源。
这个实现在多线程环境下是不安全的,如果多个线程能够同时进入 if (uniqueInstance == null) ,并且此时 uniqueInstance 为 null,那么会有多个线程执行 uniqueInstance = new Singleton(); 语句,这将导致实例化多次 uniqueInstance。
public class Singleton {
private static Singleton uniqueI ...
Design Patterns - Proxy
# 代理(Proxy)
# Intent
控制对其它对象的访问。
# Class Diagram
代理有以下四类:
远程代理(Remote Proxy):控制对远程对象(不同地址空间)的访问,它负责将请求及其参数进行编码,并向不同地址空间中的对象发送已经编码的请求。
虚拟代理(Virtual Proxy):根据需要创建开销很大的对象,它可以缓存实体的附加信息,以便延迟对它的访问,例如在网站加载一个很大图片时,不能马上完成,可以用虚拟代理缓存图片的大小信息,然后生成一张临时图片代替原始图片。
保护代理(Protection Proxy):按权限控制对象的访问,它负责检查调用者是否具有实现一个请求所必须的访问权限。
智能代理(Smart Reference):取代了简单的指针,它在访问对象时执行一些附加操作:记录对象的引用次数;当第一次引用一个对象时,将它装入内存;在访问一个实际对象前,检查是否已经锁定了它,以确保其它对象不能改变它。
# Implementation
以下是一个虚拟代理的实现,模拟了图片延迟加载的情况下使用与图片大小相等的临时内容去替换原始图片,直到图片加载完成 ...
Design Patterns - Abstract Factory
# 抽象工厂(Abstract Factory)
# Intent
提供一个接口,用于创建 相关的对象家族 。
# Class Diagram
抽象工厂模式创建的是对象家族,也就是很多对象而不是一个对象,并且这些对象是相关的,也就是说必须一起创建出来。而工厂方法模式只是用于创建一个对象,这和抽象工厂模式有很大不同。
抽象工厂模式用到了工厂方法模式来创建单一对象,AbstractFactory 中的 createProductA () 和 createProductB () 方法都是让子类来实现,这两个方法单独来看就是在创建一个对象,这符合工厂方法模式的定义。
至于创建对象的家族这一概念是在 Client 体现,Client 要通过 AbstractFactory 同时调用两个方法来创建出两个对象,在这里这两个对象就有很大的相关性,Client 需要同时创建出这两个对象。
从高层次来看,抽象工厂使用了组合,即 Cilent 组合了 AbstractFactory,而工厂方法模式使用了继承。
# Implementation
public class AbstractProdu ...
Design Patterns - Strategy
# 策略(Strategy)
# Intent
定义一系列算法,封装每个算法,并使它们可以互换。
策略模式可以让算法独立于使用它的客户端。
# Class Diagram
Strategy 接口定义了一个算法族,它们都实现了 behavior () 方法。
Context 是使用到该算法族的类,其中的 doSomething () 方法会调用 behavior (),setStrategy (Strategy) 方法可以动态地改变 strategy 对象,也就是说能动态地改变 Context 所使用的算法。
# 与状态模式的比较
状态模式的类图和策略模式类似,并且都是能够动态改变对象的行为。但是状态模式是通过状态转移来改变 Context 所组合的 State 对象,而策略模式是通过 Context 本身的决策来改变组合的 Strategy 对象。所谓的状态转移,是指 Context 在运行过程中由于一些条件发生改变而使得 State 对象发生改变,注意必须要是在运行过程中。
状态模式主要是用来解决状态转移的问题,当状态发生转移了,那么 Context 对象就会改变它的行为 ...
Design Patterns - Visitor
# 访问者(Visitor)
# Intent
为一个对象结构(比如组合结构)增加新能力。
# Class Diagram
Visitor:访问者,为每一个 ConcreteElement 声明一个 visit 操作
ConcreteVisitor:具体访问者,存储遍历过程中的累计结果
ObjectStructure:对象结构,可以是组合结构,或者是一个集合。
# Implementation
public interface Element {
void accept(Visitor visitor);
}
class CustomerGroup {
private List<Customer> customers = new ArrayList<>();
void accept(Visitor visitor) {
for (Customer customer : customers) {
customer.accept(visitor);
...
Design Patterns - Iterator
# 迭代器(Iterator)
# Intent
提供一种顺序访问聚合对象元素的方法,并且不暴露聚合对象的内部表示。
# Class Diagram
Aggregate 是聚合类,其中 createIterator () 方法可以产生一个 Iterator;
Iterator 主要定义了 hasNext () 和 next () 方法;
Client 组合了 Aggregate,为了迭代遍历 Aggregate,也需要组合 Iterator。
# Implementation
public interface Aggregate {
Iterator createIterator();
}
public class ConcreteAggregate implements Aggregate {
private Integer[] items;
public ConcreteAggregate() {
items = new Integer[10];
for (int i = ...
Design Patterns - Mediator
# 中介者(Mediator)
# Intent
集中相关对象之间复杂的沟通和控制方式。
# Class Diagram
Mediator:中介者,定义一个接口用于与各同事(Colleague)对象通信。
Colleague:同事,相关对象
# Implementation
Alarm(闹钟)、CoffeePot(咖啡壶)、Calendar(日历)、Sprinkler(喷头)是一组相关的对象,在某个对象的事件产生时需要去操作其它对象,形成了下面这种依赖结构:
使用中介者模式可以将复杂的依赖结构变成星形结构:
public abstract class Colleague {
public abstract void onEvent(Mediator mediator);
}
public class Alarm extends Colleague {
@Override
public void onEvent(Mediator mediator) {
mediator.doEvent ...