zoukankan      html  css  js  c++  java
  • ###《设计模式》

    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<Order> orderList = new ArrayList<Order>();   //保存命令
    
       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<Memento> mementoList = new ArrayList<Memento>();
    
       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<Observer> observers 
          = new ArrayList<Observer>();
       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());
       }
    }
    

    六、结论

  • 相关阅读:
    支付平台架构
    进程、线程与协程
    WSGI
    TLS(SSL)
    Python logger
    Jedis操作Redis--Hash类型
    Jedis操作Redis--List类型
    Jedis操作Redis--String类型
    SpringMVC整合Apache Shiro
    JDK中的Proxy技术实现AOP功能
  • 原文地址:https://www.cnblogs.com/gr-nick/p/5748238.html
Copyright © 2011-2022 走看看