《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("\nMighty Gumball, Inc.");
		result.append("\nJava-enabled Standing Gumball Model #2004");
		result.append("\nInventory: " + count + " gumball");
		if (count != 1) {
			result.append("s");
		}
		result.append("\n");
		result.append("Machine is " + state + "\n");
		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();
		
		//再在转动运行多次
	}
}






 
相关文章
|
7月前
|
设计模式
设计模式之 State(状态模式)
设计模式之 State(状态模式)
46 0
|
2月前
|
设计模式 Java Kotlin
Kotlin学习笔记 - 改良设计模式 - 迭代器模式
Kotlin学习笔记 - 改良设计模式 - 迭代器模式
30 2
|
2月前
|
设计模式 JavaScript Scala
Kotlin学习笔记 - 改良设计模式 - 责任链模式
Kotlin学习笔记 - 改良设计模式 - 责任链模式
45 0
|
2月前
|
设计模式 Java Kotlin
Kotlin 学习笔记- 改良设计模式 - 装饰者模式
Kotlin 学习笔记- 改良设计模式 - 装饰者模式
27 0
|
3月前
|
设计模式 Java 测试技术
Java设计模式-状态模式(18)
Java设计模式-状态模式(18)
|
4月前
|
设计模式 网络协议 Java
【十五】设计模式~~~行为型模式~~~状态模式(Java)
文章详细介绍了状态模式(State Pattern),这是一种对象行为型模式,用于处理对象在其内部状态改变时的行为变化。文中通过案例分析,如银行账户状态管理和屏幕放大镜工具,展示了状态模式的应用场景和设计方法。文章阐述了状态模式的动机、定义、结构、优点、缺点以及适用情况,并提供了Java代码实现和测试结果。状态模式通过将对象的状态和行为封装在独立的状态类中,提高了系统的可扩展性和可维护性。
【十五】设计模式~~~行为型模式~~~状态模式(Java)
|
5月前
|
设计模式 JavaScript Go
js设计模式【详解】—— 状态模式
js设计模式【详解】—— 状态模式
91 7
|
5月前
|
设计模式 Java
Head First设计模式学习笔记
Head First设计模式学习笔记
|
6月前
|
设计模式
状态模式-大话设计模式
状态模式-大话设计模式
|
6月前
|
设计模式 存储
行为设计模式之状态模式
行为设计模式之状态模式