设计模式-状态者模式
程序员文章站
2022-03-14 10:14:54
...
- 定义
允许一个对象在内部状态变化时改变它的行为,类似于改变类
- 结构
- Context: 环境类
- State: 抽象状态类
- ConcreteState: 具体状态类
- 优点
- 枚举可能的状态,在枚举状态之前需要确定状态种类。
- 将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。
- 允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。
- 缺点
- 状态模式的使用必然会增加系统类和对象的个数。
- 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
- 状态模式对“开闭原则”的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码
- 代码
原始代码
package com.example.design.pattern.book.state;
public class BallMachine {
final static int sold_out = 0;
final static int no_quarter = 1;
final static int has_quarter = 2;
final static int sold = 3;
int count = 0;
int currentState = sold_out;
public BallMachine(int count) {
this.count = count;
if (this.count > 0) {
currentState = no_quarter;
}
}
/**
* 投入钱
*/
public void insertQuarter() {
if (currentState == has_quarter) {
System.out.println("has quart");
} else if (currentState == no_quarter) {
currentState = has_quarter;
System.out.println("you insert a quarter");
} else if (currentState == sold_out) {
System.out.println("can not insert a quarter , sold out");
} else if (currentState == sold) {
System.out.println("please wait ,a ball will come out");
}
}
/**
* 退回钱
*/
public void ejectQuarter() {
if (currentState == has_quarter) {
System.out.println("quarter turn back");
currentState = no_quarter;
} else if (currentState == no_quarter) {
System.out.println("no quarter");
} else if (currentState == sold_out) {
System.out.println("can not eject");
} else if (currentState == sold) {
System.out.println("can not eject");
}
}
/**
* 转动手柄
*/
public void turnCrank() {
if (currentState == has_quarter) {
System.out.println("you turned ....");
currentState = sold;
dispense();
} else if (currentState == no_quarter) {
System.out.println("no quarter");
} else if (currentState == sold_out) {
System.out.println("can not turn");
} else if (currentState == sold) {
System.out.println("can not turn");
}
}
private void dispense() {
if (currentState == has_quarter) {
System.out.println("no");
} else if (currentState == no_quarter) {
currentState = has_quarter;
System.out.println("no");
} else if (currentState == sold_out) {
System.out.println("no");
} else if (currentState == sold) {
System.out.println("a ball come");
count = count - 1;
if (count == 0) {
System.out.println("no ball");
currentState = sold_out;
} else {
currentState = no_quarter;
}
}
}
}
Test
@org.junit.Test
public void testxx(){
BallMachine ballMachine = new BallMachine(1);
ballMachine.insertQuarter();
ballMachine.turnCrank();
使用状态模式后的代码
抽象状态类
package com.example.design.pattern.book.state.ok;
public interface AbState {
final static int sold_out = 0;
final static int no_quarter = 1;
final static int has_quarter = 2;
final static int sold = 3;
void insertQuarter();
void ejectQuarter();
void turnCrank();
void dispense();
}
各状态类
package com.example.design.pattern.book.state.ok;
public class HasQuarterState implements AbState {
private BallMachine1 ballMachine1;
public HasQuarterState(BallMachine1 ballMachine1) {
this.ballMachine1 = ballMachine1;
}
@Override
public void insertQuarter() {
System.out.println("has quart");
}
@Override
public void ejectQuarter() {
System.out.println("quarter returned");
ballMachine1.setCurrentState(ballMachine1.noQuarterState);
}
@Override
public void turnCrank() {
System.out.println("you turned");
ballMachine1.setCurrentState(ballMachine1.soldState);
}
@Override
public void dispense() {
System.out.println("no ball dispense");
}
}
package com.example.design.pattern.book.state.ok;
public class NoQuarterState implements AbState {
private BallMachine1 ballMachine1;
public NoQuarterState(BallMachine1 ballMachine1) {
this.ballMachine1 = ballMachine1;
}
@Override
public void insertQuarter() {
System.out.println("insert a quarter");
ballMachine1.setCurrentState(ballMachine1.hasQuarterState);
}
@Override
public void ejectQuarter() {
System.out.println("has no quarter");
}
@Override
public void turnCrank() {
System.out.println("no quarter");
}
@Override
public void dispense() {
System.out.println("no quarter");
}
}
package com.example.design.pattern.book.state.ok;
public class SoldoutQuarterState implements AbState {
private BallMachine1 ballMachine1;
public SoldoutQuarterState(BallMachine1 ballMachine1) {
this.ballMachine1 = ballMachine1;
}
@Override
public void insertQuarter() {
//.....
}
@Override
public void ejectQuarter() {
//.....
}
@Override
public void turnCrank() {
//.....
}
@Override
public void dispense() {
//.....
}
}
package com.example.design.pattern.book.state.ok;
public class SoldState implements AbState {
private BallMachine1 ballMachine1;
public SoldState(BallMachine1 ballMachine1) {
this.ballMachine1 = ballMachine1;
}
@Override
public void insertQuarter() {
//.....
}
@Override
public void ejectQuarter() {
//.....
}
@Override
public void turnCrank() {
//.....
}
@Override
public void dispense() {
//.....
}
}
package com.example.design.pattern.book.state.ok;
import com.example.design.pattern.book.state.ok.*;
public class BallMachine1 {
SoldState soldState;
HasQuarterState hasQuarterState;
NoQuarterState noQuarterState;
SoldoutQuarterState soldoutQuarterState;
int count = 0;
AbState currentState = soldState;
public BallMachine1(int count) {
soldState = new SoldState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
soldoutQuarterState = new SoldoutQuarterState(this);
this.count = count;
if (this.count > 0) {
currentState = noQuarterState;
}
}
/**
* 投入钱
*/
public void insertQuarter() {
currentState.insertQuarter();
}
/**
* 退回钱
*/
public void ejectQuarter() {
currentState.ejectQuarter();
}
/**
* 转动手柄
*/
public void turnCrank() {
currentState.turnCrank();
}
private void dispense() {
currentState.dispense();
}
public void setCurrentState(AbState currentState) {
this.currentState = currentState;
}
}
BallMachine1 ballMachine1 = new BallMachine1(1);
ballMachine1.insertQuarter();
ballMachine1.turnCrank();
运行后打印
insert a quarter
you turned