大纲
创建型模式
-工厂方法模式:在不指定具体类的情况下创建对象。
结构型模式
-适配器模式允许具有不兼容接口的类在一起工作,其方法是将自己的接口包裹在一个已经存在的类的接口上。
- 装饰器在一个对象的方法中动态地添加/覆盖行为。
行为型模式
- 策略模式允许在运行时选择一系列算法中的一种。
- 模板方法将一个算法的骨架定义为一个抽象的类、允许其子类提供具体的行为。
- 迭代器按顺序访问一个对象的元素,而不暴露它的底层表示。
- Visitor模式将算法从对象结构中分离出来,将方法的层次结构移到一个对象中。
关于设计模式:
在软件设计的特定背景下,对一个经常发生的问题的一般的、可重复使用的解决方案。OO设计模式通常显示类或对象之间的关系和相互作用,而不指定最终的应用。
1.Factory Method(工厂方法模式)AKA虚拟构造器
意图:
- 定义一个创建对象的接口,但让子类决定哪个类进行实例化。
- 工厂方法让一个类将实例化工作推迟到子类。
▪ 什么时候应该使用工厂方法?
当一个类:
- 无法预测它需要创建的对象的类别
- 希望其子类能指定它所创建的对象
- 将责任委托给多个辅助子类中的一个,而你需要将委派的子类的知识本地化。
例子:
抽象的产品:
public interface Trace { // turn on and off debugging
public void setDebug( boolean debug );
// write out a debug message
public void debug( String message );
// write out an error message
public void error( String message );
}
具体产品1:
public class FileTrace implements Trace {
private PrintWriter pw;
private boolean debug;
public FileTrace() throws IOException {
pw = new PrintWriter( new FileWriter( "t.log" ) );
}
public void setDebug( boolean debug ) {
this.debug = debug;
}
public void debug( String message ) {
if( debug ) {
pw.println( "DEBUG: " + message );
pw.flush();
}
}
public void error( String message ) {
pw.println( "ERROR: " + message );
pw.flush();
}
}
具体产品2:
public class SystemTrace implements Trace {
private boolean debug;
public void setDebug( boolean debug ) {
this.debug = debug;
}
public void debug( String message ) {
if( debug )
System.out.println( "DEBUG: " + message );
}
public void error( String message ) {
System.out.println( "ERROR: " + message );
}
}
工厂接口:
interface TraceFactory {
public Trace getTrace();
public Trace getTrace(String type);
void otherOperation(){};
}
具体工厂类:
public class Factory1 implements TraceFactory {
public Trace getTrace() {
return new SystemTrace();
...
}
}
public class Factory2 implements TraceFactory {
public getTrace(String type) {
if(type.equals(“file”)
return new FileTrace();
else if (type.equals(“system”)
return new SystemTrace();
...
}
2.适配器方法(Adapter)
意图:将某个类/接口转换为client期望的其他形式。
- 适配器让那些因为接口不兼容而无法一起工作的类一起工作。
- 用一个新的接口来包装一个现有的类。
例子:
interface Shape {
void display(int x1, int y1, int x2, int y2);
}
class Rectangle implements Shape {
void display(int x1, int y1, int x2, int y2) {
new LegacyRectangle().display(x1, y1, x2-x1, y2-y1);
}
}
class LegacyRectangle {
void display(int x1, int y1, int w, int h) {...}
}
class Client {
Shape shape = new Rectangle();
public display() {
shape.display(x1, y1, x2, y2);
}
}
3.装饰器模式
解决的问题:对单个对象进行任意的或动态的可组合的扩展。
解决方法:实现一个与你要扩展的对象相同的接口 延伸的对象,增加功能,但将主要责任委托给一个底层对象。
Stack Interface:
interface Stack {
void push(Item e);
Item pop();
}
实现最基础的Stack功能:
public class ArrayStack implements Stack {
... //rep
public ArrayStack() {...}
public void push(Item e) {
...
}
public Item pop() {
...
}
...
}
给出一个用于decorator的基础类,其中利用Delegation:
public abstract class StackDecorator implements Stack {
protected final Stack stack;
public StackDecorator(Stack stack) {
this.stack = stack;
}
public void push(Item e) {
stack.push(e);
}
public Item pop() {
return stack.pop();
}
...
}
具体装饰类:
public class UndoStack
extends StackDecorator
implements Stack {
private final UndoLog log = new UndoLog();
public UndoStack(Stack stack) {
super(stack);
}
public void push(Item e) {
log.append(UndoLog.PUSH, e);
super.push(e);
}
public void undo() {
//implement decorator behaviors on stack
}
...
}
如何使用装饰类:
构造一个普通栈:
– Stack s = new ArrayStack();
构造一个undo stack:
– Stack t = new UndoStack(new ArrayStack());
构造一个secure synchronized undo stack:
– Stack t = new SecureStack(
new SynchronizedStack(
new UndoStack(s))
客户端需要一个具有多种特性的object,通过一层一层的装饰来实现