###《设计模式》

Author: Erich Gamma.

@(gr_self)[dp]

@author: gr

@date: 2015-11-16

@email: forgerui@gmail.com

一、引言

类继承和接口继承区别:
类继承:它是代码和表示的共享机制,复用父类功能,快速定义新对象。
接口继承:描述了一个对象什么时候能被用来替代另一个对象(抽象编程)。

二、实例研究:设计一个文档编辑器

三、创建型模式(5)

1. 工厂模式

定义一个用于创建对象的接口,让子类决定实例化哪一个类。

2. 抽象工厂模式

为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。工厂有若干,产品有若干类型,所以构成一个产品族。

3. 建造者模式

使用多个简单的对象一步一步构建成一个复杂的对象。只提供一个简单的接口,隐藏复杂的构建过程。

4. 单例模式

只允许有一个实例。要将构造函数、拷贝构造函数、赋值函数设为private。

5. 原型模式

事先设计原型实例,其它实例可以通过拷贝原型来创建。

四、结构型模式(7)

1. 适配器模式

Adapter,Target,Adaptee

想要使用Target类型数据,但返回的却是Adaptee类型,这时需要利用Adapter类继承Target类,并根据Adaptee提供Target的接口。

class Adapter extends Target {
Adaptee adaptee;
}

2. 桥接模式

将抽象部分与实现部分分离,使两者可以独立变化。

3. 组合模式

将对象组合成树形结构以表示"部分-整体"的层次结构。如CEO下销售部门经理和市场部门经理,销售经理下又有若干销售人员,同样市场经理下也有许多办事员。这就构成了一个树形结构。

4. 装饰模式

给原有的类添加新功能,这些额外添加的功能可以放到装饰类中,它不改变原有类功能,只是添加新的功能,这一点不同于代理模式。

5. 外观模式

向客户端提供一个可以访问的接口,来隐藏系统的复杂性。

6. 享元模式

主要用于减少创建对象的数量,以减少内存占用和提高性能。使用HashMap缓存几个对象,重复使用,减少内存占用。

7. 代理模式

在两个系统之间添加一个中间层,通过代理类来访问最初的接口,如果依赖的接口发生改变,只需修改这个代理类就可以了。

五、行为模式(11)

1. 模板方法

定义一系列操作方法的框架,再将其中一些步骤延迟到子类中。

2. 解释器

解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。

public interface Expression {
public boolean interpret(String context);
}

public class TerminalExpression implements Expression {

private String data;

public TerminalExpression(String data){
this.data = data;
}

@Override
public boolean interpret(String context) {
if(context.contains(data)){
return true;
}
return false;
}
}

public class AndExpression implements Expression {

private Expression expr1 = null;
private Expression expr2 = null;

public AndExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}

@Override
public boolean interpret(String context) {
return expr1.interpret(context) && expr2.interpret(context);
}
}

public class InterpreterPatternDemo {

//规则:Robert 和 John 是男性
public static Expression getMaleExpression(){
Expression robert = new TerminalExpression("Robert");
Expression john = new TerminalExpression("John");
return new OrExpression(robert, john);
}

//规则:Julie 是一个已婚的女性
public static Expression getMarriedWomanExpression(){
Expression julie = new TerminalExpression("Julie");
Expression married = new TerminalExpression("Married");
return new AndExpression(julie, married);
}

public static void main(String[] args) {
Expression isMale = getMaleExpression();
Expression isMarriedWoman = getMarriedWomanExpression();

System.out.println("John is male? " + isMale.interpret("John"));
System.out.println("Julie is a married women? " + isMarriedWoman.interpret("Married Julie"));
}
}

3. 责任链

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
每个logger设置下一个logger,this.nextLogger = nextLogger; 在logMessage中可以判断nextLogger是否为null,不null则继续传递到下一个logger。

public abstract class AbstractLogger {
public static int INFO = 1;
public static int DEBUG = 2;
public static int ERROR = 3;

protected int level;

//责任链中的下一个元素
protected AbstractLogger nextLogger;

public void setNextLogger(AbstractLogger nextLogger){
this.nextLogger = nextLogger;
}

public void logMessage(int level, String message){
if(this.level <= level){
write(message);
}
if(nextLogger !=null){
nextLogger.logMessage(level, message);
}
}

abstract protected void write(String message);

}

public class ConsoleLogger extends AbstractLogger {

public ConsoleLogger(int level){
this.level = level;
}

@Override
protected void write(String message) {
System.out.println("Standard Console::Logger: " + message);
}
}

public class ErrorLogger extends AbstractLogger {

public ErrorLogger(int level){
this.level = level;
}

@Override
protected void write(String message) {
System.out.println("Error Console::Logger: " + message);
}
}

public class FileLogger extends AbstractLogger {

public FileLogger(int level){
this.level = level;
}

@Override
protected void write(String message) {
System.out.println("File::Logger: " + message);
}
}

public class ChainPatternDemo {

private static AbstractLogger getChainOfLoggers(){

AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);
AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);

errorLogger.setNextLogger(fileLogger);
fileLogger.setNextLogger(consoleLogger);

return errorLogger;
}

public static void main(String[] args) {
AbstractLogger loggerChain = getChainOfLoggers();

loggerChain.logMessage(AbstractLogger.INFO,
"This is an information.");

loggerChain.logMessage(AbstractLogger.DEBUG,
"This is an debug level information.");

loggerChain.logMessage(AbstractLogger.ERROR,
"This is an error information.");
}
}

4. 命令模式

请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

public class SellStock implements Order { //卖出命令
private Stock abcStock;

public SellStock(Stock abcStock){
this.abcStock = abcStock;
}

public void execute() {
abcStock.sell();
}
}
public class Broker {

private List orderList = new ArrayList(); //保存命令

public void takeOrder(Order order){
orderList.add(order);
}

public void placeOrders(){
for (Order order : orderList) {
order.execute();
}
orderList.clear();
}
}

public class CommandPatternDemo {
public static void main(String[] args) {
Stock abcStock = new Stock();

BuyStock buyStockOrder = new BuyStock(abcStock);
SellStock sellStockOrder = new SellStock(abcStock);

Broker broker = new Broker(); //经理加入两个命令
broker.takeOrder(buyStockOrder);
broker.takeOrder(sellStockOrder);

broker.placeOrders();
}
}

5. 迭代器模式

为遍历提供统一接口。

6. 中介者模式(Mediator)

中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。

public class ChatRoom {
public static void showMessage(User user, String message){
System.out.println(new Date().toString()
+ " [" + user.getName() +"] : " + message);
}
}
public class User {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public User(String name){
this.name = name;
}

public void sendMessage(String message){
ChatRoom.showMessage(this,message);
}
}
public class MediatorPatternDemo {
public static void main(String[] args) {
User robert = new User("Robert");
User john = new User("John");

robert.sendMessage("Hi! John!");
john.sendMessage("Hello! Robert!");
}
}

7. 备忘录模式

备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。

public class Originator {
private String state;

public void setState(String state){
this.state = state;
}

public String getState(){
return state;
}

public Memento saveStateToMemento(){
return new Memento(state); //把状态放到备忘录中
}

public void getStateFromMemento(Memento Memento){
state = Memento.getState();
}
}

public class Memento {
private String state;

public Memento(String state){
this.state = state;
}

public String getState(){
return state;
}
}

public class CareTaker {
private List mementoList = new ArrayList();

public void add(Memento state){
mementoList.add(state);
}

public Memento get(int index){
return mementoList.get(index);
}
}

public class MementoPatternDemo {
public static void main(String[] args) {
Originator originator = new Originator();
CareTaker careTaker = new CareTaker();
originator.setState("State #1");
originator.setState("State #2");
careTaker.add(originator.saveStateToMemento());
originator.setState("State #3");
careTaker.add(originator.saveStateToMemento());
originator.setState("State #4");

System.out.println("Current State: " + originator.getState());
originator.getStateFromMemento(careTaker.get(0));
System.out.println("First saved State: " + originator.getState());
originator.getStateFromMemento(careTaker.get(1));
System.out.println("Second saved State: " + originator.getState());
}
}

8. 观察者模式

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。

主体维护一个观察者列表,观察者

public class Subject {

private List observers
= new ArrayList();
private int state;

public int getState() {
return state;
}

public void setState(int state) {
this.state = state;
notifyAllObservers();
}

public void attach(Observer observer){
observers.add(observer);
}

public void notifyAllObservers(){
for (Observer observer : observers) {
observer.update();
}
}
}

//观察者以subject作为输入,并将自己加到subject的观察者列表中
public class HexaObserver extends Observer{

public HexaObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}

@Override
public void update() {
System.out.println( "Hex String: "
+ Integer.toHexString( subject.getState() ).toUpperCase() );
}
}

public class ObserverPatternDemo {
public static void main(String[] args) {
Subject subject = new Subject();

new HexaObserver(subject);
new OctalObserver(subject);
new BinaryObserver(subject);

System.out.println("First state change: 15");
subject.setState(15);
System.out.println("Second state change: 10");
subject.setState(10);
}
}

9. 状态模式

image

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

public class StartState implements State {

public void doAction(Context context) {
System.out.println("Player is in start state");
context.setState(this);
}

public String toString(){ //不同的状态拥有不同的方法
return "Start State";
}
}

public class Context {
private State state;

public Context(){
state = null;
}

public void setState(State state){
this.state = state;
}

public State getState(){
return state;
}
}

public class StatePatternDemo {
public static void main(String[] args) {
Context context = new Context();

//第一种状态
StartState startState = new StartState();
startState.doAction(context);
System.out.println(context.getState().toString());

//第二种状态
StopState stopState = new StopState();
stopState.doAction(context);
System.out.println(context.getState().toString());
}
}

10. 策略模式

image

定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。

public class Context {
private Strategy strategy;

public Context(Strategy strategy){ //传入不同的策略
this.strategy = strategy;
}

public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}
}

11. 访问者模式(Visitor)

我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。不同访问者具有不同的行为。

public class Computer implements ComputerPart {

ComputerPart[] parts;

public Computer(){
parts = new ComputerPart[] {new Mouse(), new Keyboard(), new Monitor()};
}

@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
for (int i = 0; i < parts.length; i++) {
parts[i].accept(computerPartVisitor);
}
computerPartVisitor.visit(this);
}
}

//可能有多个不同的访问者,不同访问者行为表现不同
public class ComputerPartDisplayVisitor implements ComputerPartVisitor {

@Override
public void visit(Computer computer) {
System.out.println("Displaying Computer.");
}

@Override
public void visit(Mouse mouse) {
System.out.println("Displaying Mouse.");
}

@Override
public void visit(Keyboard keyboard) {
System.out.println("Displaying Keyboard.");
}

@Override
public void visit(Monitor monitor) {
System.out.println("Displaying Monitor.");
}
}

public class VisitorPatternDemo {
public static void main(String[] args) {

ComputerPart computer = new Computer();
computer.accept(new ComputerPartDisplayVisitor());
}
}

六、结论

posted @ 2016-08-08 10:15  bairuiworld  阅读(263)  评论(0)    收藏  举报