状态模式
在编程中,可能会遇到需要进行状态转变的代码,通常我们是定义一堆常量来定义各个状态,通过一个变量来记住当前的状态,但是这样做的话每次操作都得进行一堆的if-else判断,状态一多,代码就很复杂,维护起来也不好维护。这个时候就可以用到状态模式,它把各个状态都用类来表示,状态的动作以及转换交由各个状态自己来维护,这样就不必在主对象中写一堆if-else语句,各个状态分工也很明确。
下面是结构图:
上图实现了一个售货机的类,总共分成4个状态:初始状态、已付款状态、已选择商品状态、售罄状态,动作有三个pay(),selectGoods(),sold(),售货机VendingMechine拥有四个状态对象的引用,以及一个记录当前状态的State引用。每次调用时都是用当前状态State来调用三个动作方法,当前状态的变化由各个状态进行操作,售货机不进行状态的改变,除了初始化的时候。
代码如下:
public interface StateCompoment {
void pay() throws Exception;
void selectGoods() throws Exception;
void sold() throws Exception;
}
初始状态:
public class InitState extends StateBase{
public InitState(VendingMechine vendingMechine) {
super(vendingMechine);
}
@Override
public void pay() throws Exception {
System.out.println("你进行了付款");
vendingMechine.setState(vendingMechine.getPaidState());
}
@Override
public void selectGoods() throws Exception {
System.out.println("你还没付钱");
}
@Override
public void sold() throws Exception {
System.out.println("你还没付钱");
}
}
已付款状态:
public class PaidState extends StateBase{
public PaidState(VendingMechine vendingMechine) {
super(vendingMechine);
}
@Override
public void pay() throws Exception {
System.out.println("你已经付了款");
}
@Override
public void selectGoods() throws Exception {
System.out.println("你选择了一件商品");
vendingMechine.setState(vendingMechine.getSelectState());
}
@Override
public void sold() throws Exception {
System.out.println("还未选择商品");
}
}
已选择状态:
public class SelectState extends StateBase {
public SelectState(VendingMechine vendingMechine) {
super(vendingMechine);
}
@Override
public void pay() throws Exception {
System.out.println("你已经付款了");
}
@Override
public void selectGoods() throws Exception {
System.out.println("你已经选择了商品");
}
@Override
public void sold() throws Exception {
System.out.println("出货");
vendingMechine.setCount(vendingMechine.getCount()-1);
if(vendingMechine.getCount()>0){
vendingMechine.setState(vendingMechine.getInitState());
}else{
vendingMechine.setState(vendingMechine.getSoldOutState());
}
}
}
售罄状态:
public class SoldOutState extends StateBase {
public SoldOutState(VendingMechine vendingMechine) {
super(vendingMechine);
}
@Override
public void pay() throws Exception {
System.out.println("售罄");
}
@Override
public void selectGoods() throws Exception {
System.out.println("售罄");
}
@Override
public void sold() throws Exception {
System.out.println("售罄");
}
}
售货机:
public class VendingMechine implements StateCompoment{
private InitState initState;
private PaidState paidState;
private SelectState selectState;
private SoldOutState soldOutState;
private StateBase state;
private int count = 0;
public VendingMechine(int count){
initState = new InitState(this);
paidState = new PaidState(this);
selectState = new SelectState(this);
soldOutState = new SoldOutState(this);
if(count > 0){
this.count = count;
state = initState;
return;
}
state = soldOutState;
}
@Override
public void pay() throws Exception {
state.pay();
}
@Override
public void selectGoods() throws Exception {
state.selectGoods();
}
@Override
public void sold() throws Exception {
state.sold();
}
//getter and setter
}
测试:
public class Main {
public static void main(String[] args) throws Exception{
VendingMechine vendingMechine = new VendingMechine(2);
System.out.println("剩余数量:"+vendingMechine.getCount());
vendingMechine.pay();
vendingMechine.selectGoods();
vendingMechine.sold();
System.out.println("剩余数量:"+vendingMechine.getCount());
vendingMechine.pay();
vendingMechine.selectGoods();
vendingMechine.sold();
System.out.println("剩余数量:"+vendingMechine.getCount());
vendingMechine.pay();
vendingMechine.selectGoods();
vendingMechine.sold();
}
}
测试结果: