zoukankan      html  css  js  c++  java
  • Head First 设计模式 --10 状态模式

    状态模式:允许对象在内部状态改变时改变他的行为,对象看起来好像修改了他的类。

    用到的设计原则
    1、封装变化
    2、多用组合,少用继承
    3、针对接口编程,不针对实现编程
    4、松耦合
    5、对扩展开放,对修改关闭
    6、依赖抽象,而不依赖具体
    7、只和朋友交谈
    8、别找我,我会找你
    9、类应该只有一个修改的理由 

    例子来自《Head First设计模式》,糖果机的例子

    interface State {
    
      public void insertQuarter();
    
      public void ejectQuarter();
    
      public void turnCrank();
    
      public void dispense();
    }
    
    class NoQuarterState implements State {
      GumballMachine gumballMachine;
    
      public NoQuarterState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
      }
    
      public void insertQuarter() {
        System.out.println("You inserted a quarter");
        gumballMachine.setState(gumballMachine.hasQuarterState);
      }
    
      public void ejectQuarter() {
        System.out.println("You haven't inserted a quarter");
      }
    
      public void turnCrank() {
        System.out.println("You turned, but there's no quarter");
      }
    
      public void dispense() {
        System.out.println("You need to pay first");
      }
    
      public String toString() {
        return "waiting for quarter";
      }
    }
    
    class HasQuarterState implements State {
      Random randomWinner = new Random(System.currentTimeMillis());
      GumballMachine gumballMachine;
    
      public HasQuarterState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
      }
    
      public void insertQuarter() {
        System.out.println("You can't insert another quarter");
      }
    
      public void ejectQuarter() {
        System.out.println("Quarter returned");
        gumballMachine.setState(gumballMachine.noQuarterState);
      }
    
      public void turnCrank() {
        System.out.println("You turned...");
    
        int winner = randomWinner.nextInt(10);
        if ((winner == 0) && (gumballMachine.count > 1)) {
          gumballMachine.setState(gumballMachine.winnerState);
        } else {
          gumballMachine.setState(gumballMachine.soldOutState);
        }
      }
    
      public void dispense() {
        System.out.println("No gumball dispensed");
      }
    
      public String toString() {
        return "waiting for turn of crank";
      }
    }
    
    class GumballMachine {
      State soldOutState;
      State noQuarterState;
      State hasQuarterState;
      State soldState;
      State winnerState;
    
      State state = soldOutState;
      int count = 0;
    
      public GumballMachine(int numberGumballs) {// soldOutState = new SoldOutState(this);
        noQuarterState = new NoQuarterState(this);
        hasQuarterState = new HasQuarterState(this);
        // soldState = new SoldState(this);
        // winnerState = new WinnerState(this);
    
        this.count = numberGumballs;
        if (numberGumballs > 0) {
          state = noQuarterState;
        }
      }
    
      public void insertQuarter() {
        state.insertQuarter();
      }
    
      public void ejectQuarter() {
        state.ejectQuarter();
      }
    
      public void turnCrank() {
        state.turnCrank();
        state.dispense();
      }
    
      void setState(State state) {
        this.state = state;
      }
    
      void releaseBall() {
        System.out.println("A gumball comes rolling out the slot...");
        if (count != 0) {
          count = count - 1;
        }
      }
    
    }
    
    public class StateTest {
      public static void main(String[] args) {
        GumballMachine gumballMachine = new GumballMachine(10);
    
        gumballMachine.insertQuarter();
        gumballMachine.turnCrank();
        gumballMachine.insertQuarter();
        gumballMachine.turnCrank();
      }
    }

    类图:

     上面的代码运行不了。缺少三种State,这里只是看一下要表达的意思。

    装填模式将状态封装成独立的类,并将每个动作委托给当前状态的对象。如果对象能够完全改变它的行为,那么你会觉得,这个对象实际是从别的类实例化出来的,而实际上,我们是用组合通过简单引用不同的状态对象来造成类的改变的假象。

    当我们看到上面的类图时,会发现这个类图和策略模式的类图是一样的。
    策略模式:我们将一群行为封装在状态对象中,context的行为随时可委托到哪个状态对象中。随着状态的改变,以反应context的内部的状态。但是context的客户对于状态对象了解不多。状态模式代替多条件判断的设计方案,通过包装状态对象,在context内简单地改变状态对象。
    装填模式:通常是主动指定context所要组合的对象是哪一个。这个对象一般情况不会改变,因为对于程序而言,他就是这个类型的,具有特定的行为。一般来说,策略模式是除了继承外一种弹性的设计方案。

    状态模式:封装基于装填的行为,并将行为委托到当前状态
    策略模式:将可以减缓的行为封装起来,然后使用委托的方法决定使用那一个行为
    模板方法模式:由子类决定如何实现算法中的某个步骤

  • 相关阅读:
    Asp.Net+Oracle+BootStrap+Jquery
    UML类图几种关系的总结
    PHP对象在内存堆栈中的分配
    php sprintf 详解
    微信错误代码45047:客服消息只能发送20条/个用户
    php利用array_search与array_column实现二维数组查找
    mvc 详解
    php中++i 与 i++ 的区分详解
    Git 别名多个命令 超实用
    php 对象继承
  • 原文地址:https://www.cnblogs.com/badboyf/p/6223874.html
Copyright © 2011-2022 走看看