• 《Head First 设计模式》学习笔记——状态模式


    在软件开发过程中。应用程序可能会依据不同的情况作出不同的处理。

    最直接的解决方式是将这些全部可能发生的情况全都考虑到。然后使用if... ellse语句来做状态推断来进行不同情况的处理。

    可是对复杂状态的推断就显得“力不从心了”。

    随着添加新的状态或者改动一个状体(if else(或switch case)语句的增多或者改动)可能会引起非常大的改动,而程序的可读性,扩展性也会变得非常弱。维护也会非常麻烦。

    那么我就考虑仅仅改动自身状态的模式。————题记


    设计模式
    状态模式:同意对象在内部状态改变时改变他的行为,对象看起来好像改动了它的类。
    这个模式将状态封装称为独立的类,并将动作托付到代表当前状态的对象。我们知道行为会随着内部状态而改变。

    设计原则
    封装变化
    多用组合。少用继承
    针对接口编程,不针对实现编程
    为交互对象之间松耦合设计而努力
    类应该对扩展开发。对改动关闭
    依赖抽象,不依赖详细类
    仅仅和朋友交谈
    别找我,我会找你
    类应该仅仅有一个改变的理由

    要点
    状态模式同意一个对象基于内部状态而拥有不同的行为。

    和程序状态机不同,状态模式用类代表状态。
    策略模式一般会用行为或算法来配置context类,状态模式同意context随着状态改变而改变行为。状态转变能够由state类或context类控制。

    使用状态模式会导致设计模式中类的数目大量添加。

    状态类能够被多个context共享。

    模型匹配
    状态模型          封装基于状态的行为,并将行为托付到当前状态
    策略模型          将能够互换的行为封装起来,然后使用托付的方法,决定使用哪一个行为。
    模板方法模型    由子类决定实现算法的某些步骤

    何时使用?
    State模式在实际使用中比較多,适合"状态的切换".由于我们常常会使用If elseif else 进行状态切换, 假设针对状态的这样推断切换重复出现,我们就要联想到能否够採取State模式了.
    不仅仅是依据状态,也有依据属性.假设某个对象的属性不同,对象的行为就不一样,这点在数据库系统中出现频率比較高,我们常常会在一个数据表的尾部,加上property属性含义的字段,用以标识记录中一些特殊性质的记录,这样的属性的改变(切换)又是随时可能发生的,就有可能要使用State.

    状态模式:
    //状态接口
    public interface State {
     
    	public void insertQuarter();
    	public void ejectQuarter();
    	public void turnCrank();
    	public void dispense();
    }
    
    
    //实现状态接口
    public 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.getHasQuarterState());
    	}
     
    	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";
    	}
    }
    
    
    public 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.getNoQuarterState());
    	}
     
    	public void turnCrank() {
    		System.out.println("You turned...");
    		
    		//决定这名顾客是否赢了
    		int winner = randomWinner.nextInt(10);
    		if ((winner == 0) && (gumballMachine.getCount() > 1)) {
    			gumballMachine.setState(gumballMachine.getWinnerState());
    		} else {
    			gumballMachine.setState(gumballMachine.getSoldState());
    		}
    	}
    
        public void dispense() {
            System.out.println("No gumball dispensed");
        }
     
    	public String toString() {
    		return "waiting for turn of crank";
    	}
    }
    
    
    //实现糖果机
    public 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;
    		}
    	}
     
    	int getCount() {
    		return count;
    	}
     
    	void refill(int count) {
    		this.count = count;
    		state = noQuarterState;
    	}
    
        public State getState() {
            return state;
        }
    
        public State getSoldOutState() {
            return soldOutState;
        }
    
        public State getNoQuarterState() {
            return noQuarterState;
        }
    
        public State getHasQuarterState() {
            return hasQuarterState;
        }
    
        public State getSoldState() {
            return soldState;
        }
    
        public State getWinnerState() {
            return winnerState;
        }
     
    	public String toString() {
    		StringBuffer result = new StringBuffer();
    		result.append("
    Mighty Gumball, Inc.");
    		result.append("
    Java-enabled Standing Gumball Model #2004");
    		result.append("
    Inventory: " + count + " gumball");
    		if (count != 1) {
    			result.append("s");
    		}
    		result.append("
    ");
    		result.append("Machine is " + state + "
    ");
    		return result.toString();
    	}
    }
    
    
    package net.dp.state.gumballstatewinner;
    
    public class GumballMachineTestDrive {
    
    	public static void main(String[] args) {
    		GumballMachine gumballMachine = 
    			new GumballMachine(10);
    
    		System.out.println(gumballMachine);
    
    		gumballMachine.insertQuarter();
    		gumballMachine.turnCrank();
    		gumballMachine.insertQuarter();
    		gumballMachine.turnCrank();
    		
    		//再在转动运行多次
    	}
    }
    


  • 相关阅读:
    arcgis开发笔记【silverlight开发资料】
    arcgis开发笔记【系统介绍】
    Vs2010架构设计概述
    arcgis开发笔记【Oracle使用汇总】
    arcgis开发笔记【silverlight 发布rest地图服务】
    arcgis开发笔记【系统的安装】
    关于处理Ajax请求的一些心得
    IE浏览器Css选择的优先问题
    requestFeature() must be called before adding content错误
    Error inflating class错误
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5147171.html
Copyright © 2020-2023  润新知