1. UML介绍
1.1 类图
类名:正体字,如果是斜体,表示抽象类
属性:public(+),private(-),protected(#)
方法:public(+),private(-),protected(#),静态方法(_)
性质:即一个全局变量,具有get/set方法
1.2 类图关系
一般化(Generalization): 类之间的继承,接口之间的继承,类对接口的实现
关联(Association): 类之间的连接,使一个类知道另一个类的方法或属性,分为单向和双向
0..1: 零个或一个实例
0..*: 对实例无限制
1: 只有一个实例
1..*: 至少一个实例
聚合(Aggregation): 整体和个体的关系,如汽车和引擎
合成(Composition): 整体和个体,但是不能分割,如孙悟空和他的四肢
依赖(Dependency): 一个类依赖另一个类的定义,如人可以买车和房子,体现为局部变量的传入
2. 设计原则
2.1 开-闭原则(Open-Closed Principle, OCP)
一个软件实体应当对扩展开放,对修改关闭。扩展已有系统,提供新的功能;不修改抽象层,只修改实现层
2.2 里氏代换原则(Liskov Substitution Principle, LSP)
凡是基类使用的地方,对子类一定适用,尽量把相同的特征抽象成抽象类
2.3 依赖倒转原则(Dependency Inversion Principle, DIP)
要依赖于抽象,不要依赖于具体,针对接口编程,不要针对实现编程
List emp = new Vector();
List是抽象,而Vector是实现
2.4 接口隔离原则(Interface Segregation Principle, ISP)
一个类对另一个类的依赖应建立在最小接口之上,对不同功能的方法,应当建立不同的接口类型
2.5 组合/聚合复用原则(Composition/Aggregation Principle, CARP)
尽量使用合成,不要使用继承
"Is-A": 一个类是另一个类的一种,那么可以使用继承
"Has-A": 一个类是另一个类的一种角色,那需要使用组合
2.6 迪米特法则(Law of Demeter, LoD)
不要与陌生人通信,如果需要,则通过朋友来进行
3. 设计模式分类
创建模式,结构模式,行为模式
4. 创建模式 - 分为类创建和对象创建
类创建: 延迟到子类进行创建
对象创建: 把对象的创建过程动态委派给另一个对象
简单工厂模式,工厂方法模式,抽象工厂模式,单例模式,多例模式,建造模式,原始模型模式
5. 简单工厂模式(Simple Factory)
又称为静态工厂方法,由一个工厂类根据传入的参数来决定创建出哪一类产品
涉及到工厂类,抽象产品,具体产品3个角色
//工厂角色
public class Creator {
public static Product factory() {
return new ConcreteProduct();
}
}
//抽象产品角色
public interface Product {}
//具体产品角色
purlic class ConcreteProduct implements Product {
public ConcreteProduct() {}
}
6. 工厂方法模式(Factory Method)
将实际创建工作推迟到子类,便于引入新的产品,如果一个产品有很多层次,那么同样需要相同层次的工厂类
//抽象工厂角色
public interface Creator {
public Product factory();
}
//具体工厂1
public class ConcreteCreator1 implements Creator {
public Product factory() {
return new ConcreteProduct1();
}
}
//具体工厂2
public class ConcreteCreator2 implements Creator {
public Product factory() {
return new ConcreteProduct2();
}
}
//抽象产品角色
public interface Product {}
//具体产品1
purlic class ConcreteProduct1 implements Product {
public ConcreteProduct1() {//do something}
}
//具体产品2
purlic class ConcreteProduct2 implements Product {
public ConcreteProduct2() {//do something}
}
7. 抽象工厂模式(Abstract Factory)
如果多个产品有很多层次,那么抽象工厂模式就将被应用。用于处理不同产品族但具有相同产品层次的情况,
可以使用一个抽象工厂中多个具体工厂角色来负责不同的产品类型
//抽象工厂角色
public interface Creator {
public ProductA factoryA() //产品等级结构A的工厂方法
public ProductB factoryB() //产品等级结构B的工厂方法
}
//具体工厂1
public class ConcreteCreator1 implements Creator {
public ProductA factoryA() {
return new ProductA1();
}
public ProductA factoryB() {
return new ProductB1();
}
}
//具体工厂2
public class ConcreteCreator2 implements Creator {
public ProductA factoryA() {
return new ProductA2();
}
public ProductA factoryB() {
return new ProductB2();
}
}
//具体产品类ProductA
public interface ProductA {}
//具体产品类ProductA1
purlic class ProductA1 implements ProductA {
public ProductA1() {//do something}
}
//具体产品类ProductA2
purlic class ProductA2 implements ProductA {
public ProductA2() {//do something}
}
//具体产品类ProductB
public interface ProductB {}
//具体产品类ProductB1
purlic class ProductB1 implements ProductB {
public ProductB1() {//do something}
}
//具体产品类ProductB2
purlic class ProductB2 implements ProductB {
public ProductB2() {//do something}
}
8. 单例模式(Singleton)
一个类只有一个实例,一般工具类使用单例模式
//饥饿式单例
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return instance;
}
}
//懒汉式单例
public class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() {}
public synchronized static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
//登记式单例-个人以为不适用
9. 多例模式(Multiton)
//有限多实例
public class Die {
private static Die die1 = new Die();
private static Die die2 = new Die();
private Die() {}
public static Die getInstance(int whichOne) {
if (whichOne == 1) {
return die1;
} else {
return die2;
}
}
}
//无上限多实例 - 可以返回多实例
键值生成器可以应用单例模式来处理
10. 建造模式(Builder)
零件很多,那么由建造者对客户端进行隐藏,抽象工厂更具体,建造模式更宏观
//Director-负责调用产生对象
public clas Director {
private Builder builder;
public void construct() {
builder = new ConcreteBuilder();
builder.buildPart1();
builder.buildPart2();
builder.retrieveResult();
}
}
//抽象建造者
public abstract class Builder {
public abstract void buildPart1();
public abstract void buildPart2();
public abstract Product retrieveResult();
}
//具体建造者
public class ConcreteBuilder extends Builder {
private Product product = new Product();
public Product retrieveResult() {
return product;
}
public void buildPart1() {
//build the first part of product
}
public void buildPart2() {
//build the first part of product
}
}
//产品
public class Product {}
11. 原始模型模式(Prototype)
指明所要创建对象的类型,然后复制这个原型对象创建更多同类对象
11.1 简单形式 - 原型数量少且固定
//客户端
public class Client {
private Prototype prototype;
public void operation(Prototype example) {
Prototype p = (Prototype)example.clone();
}
}
//抽象原型
public interface Prototype extends Cloneable {
Prototype clone();
}
//具体原型
public class ConcretePrototype implments Prototype {
public Object clone() {
super.clone();
}
}
11.2 登记形式 - 原型对象不固定
//抽象原型
public interface Prototype extends Cloneable {
Prototype clone();
}
//具体原型
public class ConcretePrototype implments Prototype {
public synchronized Object clone() {
Prototype tmep = null;
try {
temp = (Prototype)super.clone();
return temp;
} catch(CloneNotSupportedException e) {
System.out.println("Clone failed.");
} finally {
return temp;
}
}
}
//原型管理器,记录所有原型对象
public class PrototypeManager {
private Vector objects = new Vector();
public void add(Prototype object) {
objects.add(object);
}
public Prototype get(int i) {
return (Prototype)objects.get(i)
}
public int getSize() {
return objects.size();
}
}
//客户端
public class Client {
private Prototype prototype;
private PrototypeManager mgr;
public void registerPrototype() {
protoypte = new ConcretePrototype();
Prototype p = (Prototype)protoypte.clone();
mgr.add(p);
}
}
11.3 浅复制和深复制
浅复制: 使用clone,复制引用
Monkey temp = (Monkey)super.clone();
深复制: 使用Serializable,复制所有对象
//首先将对象写入流
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oo.writeObject(this);
//然后将对象从流里读出
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return(ois.readObject());
12. 结构模式 - 将类和对象结合在一起形成更大的结构
适配器模式,缺省适配器模式,合成模式,装饰模式,代理模式,享元模式,门面模式,桥梁模式
13. 适配器模式(Adapter)
把一个类的接口变换成客户端可以使用的接口
13.1 类适配器: 适配器和源角色是继承关系
//目标角色
public interface Target {
void sampleOperation1();
void sampleOperation2();
}
//源角色
public class Adaptee {
public void sampleOperation1() {}
}
//适配器,把原和目标适配起来
public class Adpater extends Adaptee implements Target {
//由于Adaptee没有sampleOperation2方法,所以补充上
public void sampleOperation2() {}
}
13.2 对象的适配器: 适配器和源角色是委派关系
//目标角色
public interface Target {
void sampleOperation1();
void sampleOperation2();
}
//源角色
public class Adaptee {
public void sampleOperation1() {}
}
//适配器,把原和目标适配起来
public class Adpater implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
super();
this.adaptee = adaptee;
}
//源方法中有sampleOperation1方法,适配器直接委派即可
public void sampleOperation1() {
adaptee.sampleOperation1();
}
//由于Adaptee没有sampleOperation2方法,所以补充上
public void sampleOperation2() {}
}
14. 缺省适配器(Default Adapter)
一个类需要实现一个接口,但又不想完全实现接口中所有方法,那么可以定义一个抽象类,
让抽象类实现接口方法,然后具体类继承该抽象类,覆盖部分方法即可。
//接口
public interface AbstractService {
void serviceOperation1();
int serviceOperation2();
String serviceOperation3();
}
//缺省适配类
public class ServicAdapter implements AbstractService {
public void serviceOperation1();
public int serviceOperation2() {return 0;}
public String serviceOperation3() {return null;}
}
15. 合成模式(Composite)
把一个个具体对象和由它们复合而成的合成对象同等看待,如同树叶和树枝组成一个大对象
15.1 安全式合成模式: 管理子类的方法只出现在树枝类,不出现在树叶类
//抽象构件
public interface Component {
Composite getComposite();
void sampleOperation();
}
//树枝构件
public class Composite implements Component {
private Vector componentVector = new java.util.Vector();
public Composite getComposite() {return this;}
public void sampleOperation() {
Enumeration enum = components();
while(enum.hasMoreElements()) {
((Component)enum.nextElement()).sampleOperation();
}
}
public void add(Component comp) {
componentVector.addElement(comp);
}
public void remove(Component comp) {
componentVector.removeElement(comp);
}
public Enumeration components {
return componentVector.elments();
}
}
//树叶构件
public class Leaf implements Component {
public void sampleOperation() {}
public Composite getComposite() {}
}
15.2 透明式合成模式: 所有的方法均定义在接口中
//抽象构件
public interface Component {
Composite getComposite();
void sampleOperation();
void add(Component comp);
void remove(Component comp);
Enumeration components();
}
//树枝构件
public class Composite implements Component {
private Vector componentVector = new java.util.Vector();
public Composite getComposite() {return this;}
public void sampleOperation() {
Enumeration enum = components();
while(enum.hasMoreElements()) {
((Component)enum.nextElement()).sampleOperation();
}
}
public void add(Component comp) {
componentVector.addElement(comp);
}
public void remove(Component comp) {
componentVector.removeElement(comp);
}
public Enumeration components {
return componentVector.elments();
}
}
//树叶构件
public class Leaf implements Component {
public void sampleOperation() {}
public Composite getComposite() {}
public void add(Component comp) {}
public void remove(Component comp) {}
public Enumeration components {}
}
16. 装饰(Decorator)
对客户端透明方式扩展对象功能,是继承关系一个替代方案
//抽象构件-规范接收附加责任
public intreface Component {
void sampleOperation();
}
//具体构件-准备接收附加责任
public class ConcreteComponent implements Component {
public ConcreteComponent() {}
public void sampleOperation() {}
}
//装饰角色-持有一个构件实例,并定义一个与抽象构建接口一致的接口
public class Decorator implements Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
public void sampleOperation() {
component.sampleOperation();
}
}
//具体装-实现抽象装饰类
public class ConcreteDecorator extends Decorator {
public void sampleOperation() {
super.sampleOperation();
}
}
17. Java I/O中设计模式
String line;
//适配器模式
InputStreamReader input = new InputStreamReader(System.in);
System.out.println("Enter data and push enter: ");
//装饰模式
BufferedReader reader = new BufferedReader(input);
line = reader.readLine();
System.out.println("Data entered: " + line);
18. 代理模式(Proxy)
给一个对象提供一个代理对象,由代理对象控制对原对象的引用
可以用于权限检查,调用前后逻辑处理,进行计数,虚拟代理(譬如加载图像慢,给出"加载中..."字样)
//抽象主题 - 所有被使用对象接口
public abstract class Subject {
public abstract void request();
}
//真实主题 - 具体被使用对象
public class RealSubject extends Subject {
public void request() {
System.out.println("From real subject.");
}
}
//代理
public class ProxySubject extends Subject {
private RealSubject realSubject;
public void request() {
preRequest();
if (realRequest == null) {
realSubject = new RealSubject();
}
realSubject.request();
postRequest();
}
private void preRequest() {todo}
private void postRequest() {todo}
}
//客户端
Subject subject = new ProxySubject();
subject.request();
19. 享元模式(Flywight)
以共享的方式高效支持大量的细粒度对象
使用条件: 系统有大量对象,对象耗费大量内存,对象状态可以外部化
分为内部状态(可以共享)和外部状态(不可共享)
19.1 单纯享元模式 - 所有的享元对象都是可以共享
//抽象享元角色 - 所有具体享元类的父类
public abstract class Flyweight {
public abstract void operation(String state); //参数state是外部状态
}
//具体享元角色
public class ConcreteFlyweight extends Flyweight {
private Character interState = null; //内部状态
public ConcreteFlyweight(Character state) {
this.interState = state;
}
public void operation(String state) {
Syste.out.print("interState = " + interState + ", ExtenState = " + state);
}
}
//享元工厂角色 - 客户端不能直接将具体享元类实例化,所以调用工厂对象
public class FlyweightFactory {
private HashMap flies = new HashMap();
private Flyweight flyweight;
public Flyweight factory(Character state) {
//如果存在,则直接返回
if (flies.containsKey(state)) {
return (Flyweight)flise.get(state);
} else {
Flyweight fly = new ConcreteFlyweight(state);
flise.put(state, fly);
return fly;
}
}
}
//客户端
FlyweightFactory factory = new FlyweightFactory();
Flyweight fly = factory.factory(new Character('a'));
fly.operation("First Call");
fly = factory.factory(new Character('b'));
fly.operation("Second Call");
fly = factory.factory(new Character('a'));
fly.operation("Second Call");
以上申请了三个享元对象,但实际创建的只有2个
19.2 复合享元模式 - 单纯享元使用合成模式加以复合,复合享元本身不能共享,但可以分解成单纯享元对象
比单纯享元模式多一个复合享元角色
//抽象享元角色 - 所有具体享元类的父类
public abstract class Flyweight {
public abstract void operation(String state); //参数state是外部状态
}
//具体享元角色
public class ConcreteFlyweight extends Flyweight {
private Character interState = null; //内部状态
public ConcreteFlyweight(Character state) {
this.interState = state;
}
public void operation(String state) {
Syste.out.print("interState = " + interState + ", ExtenState = " + state);
}
}
//具体复合享元角色
public class ConcreteCompositeFlyweight extends Flyweight {
private HashMap flies = new HashMap(10);
private Flyweight flyweight;
public void add(Character key, Flyweight fly) {
flies.put(key, fly);
}
public void operation(Character extenState) {
Flyweight fly = null;
for (Iterator it = flies.entrySet().iterator(); it.hasNext();) {
Map.Entry e = (Map.Entry)it.next();
fly = (Flyweight)e.getValue();
fly.operation(extenState);
}
}
}
//享元工厂角色 - 客户端不能直接将具体享元类实例化,所以调用工厂对象
public class FlyweightFactory {
private HashMap flies = new HashMap();
//单纯享元工厂方法,所需状态以参数传入
public Flyweight factory(Character state) {
//如果存在,则直接返回
if (flies.containsKey(state)) {
return (Flyweight)flise.get(state);
} else {
Flyweight fly = new ConcreteFlyweight(state);
flise.put(state, fly);
return fly;
}
}
//复合享元工厂方法
public Flyweight factory(String compositeState) {
ConcreteCompositeFlyweight ccf = new ConcreteCompositeFlyweight();
int length = compositeState.length();
Character state = null;
for (int i = 0; i < length; i++) {
state = new Character(compositeState.charAt(i));
System.out.println("factory(" + state + ")");
ccf.add(state, this.factory(state));
}
return ccf;
}
}
//客户端
FlyweightFactory factory = new FlyweightFactory();
Flyweight fly = factory.factory("aba");
fly.operation("Composite Call");
aba三个Character
20. 门面模式(Facade)
外部与一个子系统通信必须通过一个统一的门面对象进行
Session门面: 一个SessionBean,用于提供客户端和EntityBean打交道
21. 桥梁模式(Bridge)
将抽象化和实现化脱耦,脱耦也就是使用组合而不是继承
//抽象化角色 - 给出定义,并保存一个实例化的引用
public abstract class Abstraction {
protected Implementor imp;
public void operation() {
imp.operationImp();
}
}
//修正抽象化角色 - 扩展抽象化角色,改变和修正父类对抽象化的定义
public class RefinedAbstraction extends Abstraction {
public void operation() {//improved logic}
}
//实现化角色 - 只是实现化接口,不给出具体实现
public abstract class Implementor {
public abstract void operationImp();
}
//具体实现化角色
public class ConcreteImplementorA extends Implementor {
public void operationImp() {//implement it}
}
22. 行为模式
不同对象之间划分责任和算法的抽象化
不变模式,策略模式,模板方法模式,观察者模式,迭代模式,责任链模式,命令模式,
备忘录模式,状态模式,访问者模式,解释器模式,调停者模式
23. 不变模式(Immutable)
一个对象的状态在被创建之后就不再变化,譬如java.lang.String
23.1 弱不变模式
一个类的实例不可变化,但给类的子类实例可能会变化
23.2 强不变模式
一个类和子类的实例都不可变,该类所有方法是final
24. 策略模式(Strategy)
又称为Policy模式,针对一组算法,将每一个算法封装到具有共同接口的独立类中,是的它们可以相互替换
比如购物车,不同种类商品打折,计算总价,就应该把计算价格封装到策略类中
//环境(Context)角色 - 持有一个Strategy类的引用
public class Context {
private Strategy strategy;
//策略方法
public void contextInterface() {
strategy.strategyInterface();
}
}
//抽象策略类
public abstract class Strategy {
public abstract void strategyInterface();
}
//具体策略
public class ConcreteStrategy extends Strategy {
public void strategyInterface() {
//implement
}
}
25. 模板方法模式(Template Method)
准备一个抽象类,实现部分逻辑,然后剩余逻辑由不同子类实现。模板方法中的方法分为模板方法和基本方法
模板方法: 定义在抽象类中
基本方法: 抽象方法(由抽象类声明,具体类实现),具体方法,钩子方法(由抽象类声明并实现,子类会扩展,
通常以do开始,譬如HttpServlet中的doGet()和doPost()方法)
//抽象模板 - 定义多个抽象操作,由子类实现
public abstract class AbstractClass {
public void templateMethod() {
doOperation1(); //由子类实现
doOperation2(); //由子类实现
doOperation3(); //已经实现
}
protected abstract void doOperation1(); //由子类实现
protected abstract void doOperation2(); //由子类实现
private final void doOperation3() {//do something} //已经实现
}
//具体模板类
public class ConcreteClass extends AbstractClass {
public void doOperation1() {
System.out.println("doOperation1()");
}
public void doOperation2() {
System.out.println("doOperation2()");
}
}
26. 观察者模式(Observer)
定义了一对多的依赖关系,多个观察者同时监听一个主题对象。又称为发布-订阅模式(Publish/Subscribe),
模型-视图模式(Model/View),源-监听器(Source/Listener),从属者模式(Dependents)
典型应用: AWT中的Listener应用,SAX2应用,Swing Timer应用
26.1 简单观察者模式 - 使用具体主题来保存观察者对象
//抽象主题 - 把所有观察者对象的引用保存到一个集合对象,被观察者对象
public interface Subject {
public void attach(Observer observer); //登记新的观察者对象
public void detach(Observer observer); //删除观察者对象
void notifyObservers(); //通知观察者对象
}
//具体主题 - 将有关状态存入具体观察者,在具体主题改变,通知所有观察者
public class ConcreteSubject implements Subject {
private Vector observers = new Vector();
public void attach(Observer observer) {
observers.addElement(observer);
}
public void detach(Observer observer) {
observers.removeElement(observer);
}
void notifyObservers() {
Enumeration enum = observers();
while (enum.hasMoreElements()) {
((Observer)enum.nextElement()).update();
}
}
public Enumeration observers() {
return ((Vector)observers.clone()).elements();
}
}
//抽象观察者
public interface Observer {
void update();
}
//具体观察者
public class ConcreteObserver implements Observer {
public void update() {
System.out.println("I am notified.");
}
}
26.2 第二种模式 - 使用抽象主题来保存观察者对象
//抽象主题 - 把所有观察者对象的引用保存到一个集合对象,被观察者对象
public abstract class Subject {
private Vector observers = new Vector();
public void attach(Observer observer) {
observers.addElement(observer);
}
public void detach(Observer observer) {
observers.removeElement(observer);
}
void notifyObservers() {
Enumeration enum = observers();
while (enum.hasMoreElements()) {
((Observer)enum.nextElement()).update();
}
}
public Enumeration observers() {
return ((Vector)observers.clone()).elements();
}
}
//具体主题
public class ConcreteSubject extends Subject {
private String state;
public void change(String newState) {
state = newState;
this.notifyObservers();
}
}
//客户端
private static ConcreteSubject subject;
private static Observer observer;
subject = new ConcreteSubject();
observer = new ConcreteObserver();
subject.attach(observer);
subject.change("new state");
27. 迭代模式(Iterator)
可以顺序的访问一个集合中的元素而不必暴露集合的内部表象,又称为游标模式(Cursor)
宽接口: 提供了修改聚集元素的方法的接口
百箱聚集: 提供宽接口的聚集
外部迭代: 宽接口,可以从外部控制
窄接口: 没有提供修改聚集元素的方法的接口
黑箱聚集: 同时提供聚集对象的封装和迭代功能的实现的聚集
内部迭代: 迭代是聚集的内部类
27.1 白箱聚集和外部迭代
//抽象聚集 - 给出创建迭代对象的接口
public abstract clas Aggregate {
public Iterator createIterator() {
return null;
}
}
//抽象迭代 - 定义遍历元素所需接口
public interface Iterator {
void first();
void next();
boolean isDone();
Object currentItem();
}
//具体聚集角色
public class ConcreteAggregate extends Aggregate {
private Object[] objs = {"Monk Tang", "Monkey", "Pigsy", "Sandy", "Horse"};
public Iterator createIterator() {
return new ConcreteIterator(this);
}
public Object getElement(int index) {
if (index < objs.length) {
return objs[index];
} else {
return null;
}
}
public int size() {
return objs.length;
}
}
//具体迭代
public class ConcreteIterator implements Iterator {
private ConcreteAggregate agg;
private int index = 0;
private int size = 0;
public ConcreteIterator(ConcreteAggregate agg) {
this.agg = agg;
size = agg.size();
index = 0;
}
public void first() {
index = 0;
}
public void next() {
if (index < size) {
index++;
}
}
public boolean isDone() {
return (index >= size); //是否最后一个元素
}
public Object currentItem() {
return agg.getElement(index);
}
}
//客户端
public class Client {
private Iterator it;
private Aggregate agg = new ConcreteAggregate();
public void operation() {
it = agg.createIterator();
while (!it.isDone()) {
System.out.println(it.currentItem().toString());
it.next();
}
}
public static void main(String[] args) {
Client client = new Client();
client.operation();
}
}
27.2 黑箱聚集和内部迭代
//抽象聚集 - 给出创建迭代对象的接口
public abstract clas Aggregate {
public Iterator createIterator();
}
//抽象迭代 - 定义遍历元素所需接口
public interface Iterator {
void first();
void next();
boolean isDone();
Object currentItem();
}
//具体聚集角色
public class ConcreteAggregate extends Aggregate {
private Object[] objs = {"Monk Tang", "Monkey", "Pigsy", "Sandy", "Horse"};
public Iterator createIterator() {
return new ConcreteIterator(this);
}
//内部成员类:具体迭代子类
private class ConcreteIterator implements Iterator {
private int currentIndex = 0;
public void first() {
currentIndex = 0;
}
public void next() {
if (currentIndex < objs.length) {
currentIndex++;
}
}
public boolean isDone() {
return (currentIndex == objs.length); //是否最后一个元素
}
public Object currentItem() {
return objs(currentIndex);
}
}
}
//客户端
public class Client {
private Iterator it;
private Aggregate agg = new ConcreteAggregate();
public void operation() {
it = agg.createIterator();
while (!it.isDone()) {
System.out.println(it.currentItem().toString());
it.next();
}
}
public static void main(String[] args) {
Client client = new Client();
client.operation();
}
}
28. 责任链模式(Chain of Responsibility)
很多对象组成一条链,而请求由链上某个对象来决定处理
//抽象处理者 - 定义处理请求的接口或方法,以设定和返回对下家的引用
public abstract class Handler {
protected Handler handler;
public abstract void handleRequest(); //调用该方法处理请求
public void setHandler(Handler handler) { //调用该方法设定下家
this.handler = handler;
}
public Handler getHandler() { //调用该方法取值
return handler;
}
}
//具体处理者 - 可以处理或者传递给下家
public class ConcreteHandler extends Handler {
public void handleRequest() {
if (getHandler() != null) {
System.out.println("The request is passed to " + getHandler());
getHandler().handleRequest();
} else {
System.out.println("Thre request is handled here.");
}
}
}
//客户端
private static Handler handler1, handler2;
handler1 = new ConcreteHandler();
handler2 = new ConcreteHandler();
handler1.setHandler(handler2);
handler1.handleRequest();
29. 命令模式(Command)
命令模式把发出命令的责任和执行命令的责任分开,委派给不同对象。
命令模式,可以没有接收者,具体命令类中实现执行细节
执行顺序:
1. Client创建具体命令对象,指明接收者
2. 请求者保存具体命令对象
3. 请求者调用action发出请求
4. 具体命令对象调用接收者来执行命令
//客户角色 - 创建一个具体命令并确定其接收者
Receiver receiver = new Receiver();
Command cmd = new ConcreteCommand(receiver);
Invoker invoker = new Invoker(cmd);
invoker.action();
//请求者 - 负责调用命令对象执行请求,相关的方法叫行动方法
public class Invoker {
private Command cmd;
public Invoker(Command cmd) {
this.cmd = cmd;
}
public void action() {
cmd.execute();
}
}
//接收者 - 负责具体执行一个请求
public class Receiver {
public Receiver() {//do something}
public void action() {
System.out.println("Action has been taken.");
}
}
//抽象命令
public interface Command {
void execute();
}
//具体命令 - 实现execute方法,负责调用接收者相应操作
public class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
public void execute() {
receiver.action();
}
}
30. 备忘录模式(Memento)
又名快照模式(Snapshot)或Token模式。
用来存储另一个对象内部状态的快照,在不破坏封装的条件下,讲一个对象捕捉住,并外部化存储起来,
在合适时间把该对象还原到原始状态,可以存储多个状态,也称检查点(check point)
备忘录角色:
1. 将发起人(Originator)对象的内部状态存储起来
2. 窄接口: 负责人(Caretaker)看到窄接口,只允许吧备忘录对象传给其他对象
3. 宽接口: 允许发起人读取所有数据
发起人(Originator)角色: 创建一个含有当前内部状态的备忘录对象,使用备忘录存储其内部状态
负责人(Caretaker)角色:负责保存备忘录对象,不检查备忘录对象的内容
30.1 白箱实现
//发起人
public class Originator {
private String state;
//工厂方法,返回一个新的备忘录对象
public Memento createMemento() {
return new Memento(state);
}
//将发起人恢复到备忘录对象所记载的状态
public void restoreMemento(Memento memento) {
this.state = memento.getState();
}
public String getState() {
return this.state;
}
public void setState(String state) {
this.state = state;
System.out.println("Current state = " + this.state);
}
}
//备忘录
public class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return this.state;
}
public void setState(String state) {
this.state = state;
}
}
//负责人
public class Caretaker {
private Memento memento;
public Memento retrieveMemento() {
return this.memento;
}
public void saveMemento(Memento memento) {
this.memento = memento;
}
}
//客户端
private static Originator o = new Originator();
private static Caretaker c = new Caretaker();
o.setState("On"); //设置发起人对象状态
c.saveMemento(o.createMemento); //创建备忘录,存储发起人对象状态
o.setState("Off"); //修改发起人对象状态
o.restoreMemento(c.retrieveMemento()); //恢复发起人对象状态
30.2 黑箱实现 - 把Memento设计成Originator的内部类
//发起人
public class Originator {
private String state;
//工厂方法,返回一个新的备忘录对象
public Memento createMemento() {
return new Memento(state);
}
//将发起人恢复到备忘录对象所记载的状态
public void restoreMemento(MementoIF memento) {
Memento aMemento = (Memento)memento;
this.setState(aMemento.getState());
}
public String getState() {
return this.state;
}
public void setState(String state) {
this.state = state;
System.out.println("Current state = " + this.state);
}
protected class Memento implements MementoIF {
private String savedState;
private Memento(String someState) {
savedState = someState;
}
public String getState() {
return savedState;
}
public void setState(String someState) {
savedState = someState;
}
}
}
//备忘录标识接口
public interface MementoIF {}
//负责人
public class Caretaker {
private MementoIF memento;
public MementoIF retrieveMemento() {
return this.memento;
}
public void saveMemento(MementoIF memento) {
this.memento = memento;
}
}
//客户端
private static Originator o = new Originator();
private static Caretaker c = new Caretaker();
o.setState("On"); //设置发起人对象状态
c.saveMemento(o.createMemento); //创建备忘录,存储发起人对象状态
o.setState("Off"); //修改发起人对象状态
o.restoreMemento(c.retrieveMemento()); //恢复发起人对象状态
31. 状态模式(State)
允许一个对象在其内部状态改变的时候改变其行为
//环境类 - 定义客户端定制接口,保留一个具体状态类实例,把行为委派给抽象状态
public class Context {
private State state;
public void sampleOperation() {
state.sampleOperation();
}
public void setState(State state) {
this.state = state;
}
}
//抽象状态
public interface State {
void sampleOperation();
}
//具体状态
public class ConcreteState implements State {
public void sampleOperation() {//do something}
}
32. 访问者模式(Visitor)
封装一些施加于某种数据结构元素之上的操作。聚集中有一群对象,那么每个对象方法中会相互持有对方
如果有一堆
if (o instanceof Collection) {
} else if (o instanceof String){
}
......
那么访问者模式就派上用场
//抽象访问者 - 声明一个或多个访问操作
public interface Visitor {
void visit(NodeA node); //对NodeA的访问操作
void visit(NodeB node); //对NodeB的访问操作
}
//具体访问者VisitorA
public class VisitorA implements Visitor {
public void visit(NodeA nodeA) {
System.out.println(nodeA.operationA());
}
public void visit(NodeB nodeB) {
System.out.println(nodeB.operationB());
}
}
//具体访问者VisitorB
public class VisitorB implements Visitor {
public void visit(NodeA nodeA) {
System.out.println(nodeA.operationA());
}
public void visit(NodeB nodeB) {
System.out.println(nodeB.operationB());
}
}
//抽象节点 - 声明一个接受操作
public abstract class Node {
public abstract void accept(Visitor visitor);
}
//具体节点A
public class NodeA extends Node {
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String operationA() {
return "NodeA is visited.";
}
}
//具体节点B
public class NodeB extends Node {
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String operationB() {
return "NodeB is visited.";
}
}
//结构对象 - 持有聚集,向外提供add()方法作为聚集的管理操作
public class ObjectStructure {
private Vector nodes;
private Node node;
public ObjectStructure() {
nodes = new Vector();
}
public void action(Visitor visitor) {
for (Enumeration e = nodes.elements(); e.hasMoreElements();) {
node = (Node)e.nextElement();
node.accept(visitor);
}
}
public void add(Node node) {
nodes.addElement(node);
}
}
//客户端
private static ObjectStructure objects;
private static Visitor visitor;
objects = new ObjectStructure();
objects.add(new NodeA());
objects.add(new NodeB());
visitor = new VisitorA();
objects.action(visitor);
33. 解释器模式(Interpreter)
把一种语言按照文法翻译成另一种表示,比如匹配模式搜寻字符串
对布尔表达式进行操作和求值示例:
//抽象表达式 - 声明所有具体表达式角色都要实现的接口,其中主要是interpret()方法
//AND OR NOT Variable Constant一系列操作
public abstract class Expression {
public abstract boolean interpret(Context ctx);
public abstract boolean equals(Object o);
public abstract int hashCode();
public abstract String toString();
}
//Constant代表一个布尔常量
public class Constant extends Expression {
private boolean value;
public Constant(boolean value) {
this.value = value;
}
public boolean interpret(Context ctx) {
return value;
}
public boolean equals(Object o) {
if (o != null && o instanceof Constant) {
return this.value == ((Constant)o).value;
}
return false;
}
public int hashCode() {
return (this.toString()).hashCode();
}
public String toString() {
return new Boolean(value).toString();
}
}
//Variable代表一个有名变量
public class Variable extends Expression {
private String name;
public Variable(String name) {
this.name = name;
}
public boolean interpret(Context ctx) {
return ctx.lookup(this);
}
public boolean equals(Object o) {
if (o != null && o instanceof Variable) {
return this.name.equals((Variable)o).name;
}
return false;
}
public int hashCode() {
return (this.toString()).hashCode();
}
public String toString() {
return name;
}
}
//And类
public class And extends Expression {
private Expression left, right;
public And(Expression left, Expression right) {
this.left = left;
this.right = right;
}
public boolean interpret(Context ctx) {
return (left.interpret(ctx) && right.interpret(ctx));
}
public boolean equals(Object o) {
if (o != null && o instanceof And) {
return (this.left.equals((And)o).left && this.right.equals((And)o).right);
}
return false;
}
public int hashCode() {
return (this.toString()).hashCode();
}
public String toString() {
return "(" + left.toString() + " AND " + right.toString() + ")";
}
}
//OR类
public class Or extends Expression {
private Expression left, right;
public Or(Expression left, Expression right) {
this.left = left;
this.right = right;
}
public boolean interpret(Context ctx) {
return (left.interpret(ctx) && right.interpret(ctx));
}
public boolean equals(Object o) {
if (o != null && o instanceof Or) {
return (this.left.equals((Or)o).left && this.right.equals((Or)o).right);
}
return false;
}
public int hashCode() {
return (this.toString()).hashCode();
}
public String toString() {
return "(" + left.toString() + " Or " + right.toString() + ")";
}
}
//NOT类
public class Not extends Expression {
private Expression exp;
public Not(Expression exp) {
this.exp = exp;
}
public boolean interpret(Context ctx) {
return !exp.interpret(ctx);
}
public boolean equals(Object o) {
if (o != null && o instanceof Not) {
return this.exp.equals((Not)o).exp;
}
return false;
}
public int hashCode() {
return (this.toString()).hashCode();
}
public String toString() {
return "(" + exp.toString() + ")";
}
}
//Context类 - 定义出从变量到布尔值的一个映射
public class Context {
private HashMap map = new HashMap();
public void assign(Variable var, boolean value) {
map.put(var, new Boolean(value));
}
public boolean lookup(Variable var) throws IllegalArgumentException {
Boolean value = (Boolean)map.get(var);
if (value == null) {
throw new IllegalArgumentException();
}
return value.booleanValue();
}
}
//Client
private static Context ctx;
private static Expression exp;
ctx = new Context();
Variable x = new Variable("x");
Variable y = new Variable("y");
Constant c = new Constant(true);
ctx.assign(x. false);
ctx.assign(y. true);
exp = new Or(new Adn(c, x), new And(y, new Not(x)));
34. 调停者模式(Mediator)
包装了一系列对象相互作用的方式,使得这些对象不惜互相明显引用
调停者可以只有一个调停者和一系列的同事类角色
//抽象同事类 - 定义出调停者到同事对象的接口
public abstract class Colleague {
private Mediator mediator;
public Colleague(Mediator m) {
mediator = m;
}
public Mediator getMediator() {
return mediator;
}
public abstract void action(); //行动方法,由子类实现
public void change() {
mediator.colleagueChanged(this); //调用此方法,可以改变对象内部状态
}
}
//具体同事类1
public class Colleague1 extends Colleague {
public Colleague1(Mediator m) {
super(m);
}
public void action() {
System.out.println("This is an action from Colleague1");
}
}
//具体同事类1
public class Colleague2 extends Colleague {
public Colleague2(Mediator m) {
super(m);
}
public void action() {
System.out.println("This is an action from Colleague2");
}
}
//抽象调停类
public abstract class Mediator {
public abstract void colleagueChanged(Colleague c); //事件方法,由子类实现
public static void main(String args[]) {
ConcreteMediator mediator = new ConcreteMediator();
mediator.createConcreteMediator();
Colleague c1 = new Colleague1(mediator);
Colleague c2 = new Colleague2(mediator);
mediator.colleagueChanged(c1);
}
}
//具体调停类
public class ConcreteMediator extends Mediator {
private Colleague1 colleague1;
private Colleague2 colleague2;
public void colleagueChanged(Colleague c) {
colleague1.action();
colleague2.action();
}
public void createConcreteMediator() {
Colleague1 = new Colleague1(this);
Colleague2 = new Colleague2(this);
}
public Colleague1 getColleague1() {
return colleague1;
}
public Colleague2 getColleague2() {
return colleague2;
}
}