和策略模式很像,都是把具体行为委托给其他类来完成,不同的是,在策略模式中,你要替换行为,需要指定,但是在状态模式里,内部自动会进行替换,你都无法察觉。
怎么做到的,Context(上下文是一个类,拥有一些内部状态)因为它在委其他类完成任务后,会转换上下文的状态。
概念:上下文,自己的理解,本身是一个类,但是拥有其他的对象引用,就像一个大锅,什么都往里装。不同的情景下,装的东西不一样。
定义 状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
这里的对象是上下文,状态改变,就调用不同的对象,所以看起来似乎调用的是同一个方法,但委托的是不同的状态对象。
![类图](https://img-blog.csdn.net/20150309173126403)
状态接口
public interface State extends Serializable{
public void insertQuarter();
public void ejectQuarter();
public void turnCrank();
public void dispense();
}
public class HasQuarterState implements State{
Random randomWinner = new Random(System.currentTimeMillis());
transient GumballMachine gumballMachine;
public HasQuarterState(GumballMachine gumballMachine){
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("You can't insert another quarter");
}
@Override
public void ejectQuarter() {
System.out.println("Quarter returned");
gumballMachine.setState(gumballMachine.getNoQuarterState());
}
@Override
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());
}
}
@Override
public void dispense() {
System.out.println("No gumball dispensed");
}
}
public class NoQuarterState implements State{
transient GumballMachine gumballMachine;
public NoQuarterState(GumballMachine gumballMachine){
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("You inserted a quarter");
gumballMachine.setState(gumballMachine.getHasQuarterState());
}
@Override
public void ejectQuarter() {
System.out.println("You haven't inserted a quarter");
}
@Override
public void turnCrank() {
System.out.println("You turned,but there's no quarter");
}
@Override
public void dispense() {
System.out.println("You need to pay first");
}
}
public class SoldOutState implements State{
transient GumballMachine gumballMachine;
public SoldOutState(GumballMachine gumballMachine){
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
}
@Override
public void ejectQuarter() {
}
@Override
public void turnCrank() {
}
@Override
public void dispense() {
}
}
public class SoldState implements State{
transient GumballMachine gumballMachine;
public SoldState(GumballMachine gumballMachine){
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("Please wait,we're already giving you a gumball");
}
@Override
public void ejectQuarter() {
System.out.println("Sorry,you already turned the crank");
}
@Override
public void turnCrank() {
System.out.println("Turning twice doesn't get you another gumball");
}
@Override
public void dispense() {
gumballMachine.releaseBall();
if(gumballMachine.getCount() > 0){
gumballMachine.setState(gumballMachine.getNoQuarterState());
}else{
System.out.println("Open,out of gumballs!");
gumballMachine.setState(gumballMachine.getSoldOutState());
}
}
}
public class WinnerState implements State{
transient GumballMachine gumballMachine;
public WinnerState(GumballMachine gumballMachine){
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
}
@Override
public void ejectQuarter() {
}
@Override
public void turnCrank() {
}
@Override
public void dispense() {
System.out.println("You're a winner! You get two gumballs for you quarter");
gumballMachine.releaseBall();
if(gumballMachine.getCount() == 0){
gumballMachine.setState(gumballMachine.getSoldOutState());
}else{
gumballMachine.releaseBall();
if(gumballMachine.getCount() > 0){
gumballMachine.setState(gumballMachine.getNoQuarterState());
}else{
System.out.println("Open,out of gumballs!");
gumballMachine.setState(gumballMachine.getSoldOutState());
}
}
}
}
上下文
public class GumballMachine extends UnicastRemoteObject implements GumballMachineRemote{
State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State winnerState;
String location;
State state = soldOutState;
int count = 0;
public GumballMachine(String location,int numberGumballs) throws RemoteException{
soldOutState = new SoldOutState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
soldState = new SoldState(this);
winnerState = new WinnerState(this);
this.count = numberGumballs;
this.location = location;
if(numberGumballs > 0){
state = noQuarterState;
}
}
public void insertQuarter(){
state.insertQuarter();
}
public void ejectQuarter(){
state.ejectQuarter();
}
public void turnCrank(){
state.turnCrank();
state.dispense();
}
public void setState(State state){
this.state = state;
}
public void releaseBall(){
System.out.println("A gumball comes rolling out the slot..");
if(count != 0){
count = count - 1;
}
}
public State getSoldOutState() {
return soldOutState;
}
public State getNoQuarterState() {
return noQuarterState;
}
public State getHasQuarterState() {
return hasQuarterState;
}
public State getSoldState() {
return soldState;
}
public State getState() {
return state;
}
public int getCount(){
return count;
}
public State getWinnerState() {
return winnerState;
}
public void setWinnerState(State winnerState) {
this.winnerState = winnerState;
}
public String getLocation(){
return location;
}
}
客户端
public class GumballMachineTestDrive {
public static void main(String[] args) {
try {
GumballMachine gumballMachine =
new GumballMachine("beijing",12);
LocateRegistry.createRegistry(6600);
Naming.rebind("rmi://127.0.0.1:6600/gumball", gumballMachine);
} catch (Exception e) {
}
}
}