设计模式-----状态模式

设计模式—–状态模式

个人博客,想要搭建个人博客的可以进来看看: http://www.ioqian.top/


状态模式 , 允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类

设计模式系列源码: https://github.com/liloqian/DesiginModeDemo

背景 , 水有三种状态,通过不同方法可以在三种状态中进行转变;我们这里要做的就是实现这个转变的过程

此处输入图片的描述

1.简单的实现,不是用状态模式

public class InitialDemo {
    //水的三种状态
    public static final int GAS = 0;
    public static final int SOLID = 1;
    public static final int LIQUID = 2;
    //当前状态
    int state = LIQUID;
    //加热方法,只可以在固态执行,其他态都报error
    public void warm(){
        if(state == SOLID){//如果当前状态是固态就进行转变
            state = GAS; //转变完成后当前状态设为气态
            System.out.println("Ok :  warming , solid become gas");
        }else if(state == GAS){
            System.out.println("Error :   now is gas , what do you do!");
        }else if(state == LIQUID){
            System.out.println("Error  :   you need to become liquid to solid , them warm...");
        }
    }
    //液化过程,只有气态执行,其他态都报error
    public void liquidation(){
        if(state == GAS){
            state = LIQUID;
            System.out.println("OK :  liquindation , gas become liquid");
        }else if(state == LIQUID){
            System.out.println("Error :  now is liquid , what do you do!");
        }else if(state == SOLID){
            System.out.println("Error : you need to become solid to gas ,them liquidation");
        }
    }
    //凝固过程,只有液台可执行,其他态都报error
    public void sloiding(){
        if(state == LIQUID){
            state = SOLID;
            System.out.println("OK : Sloding , liquid become solid");
        }else if (state == SOLID){
            System.out.println("Error :  now is Solid , what do you do!");
        }else if(state == GAS){
            System.out.println("Error : you need to become gas to liquid ,them Sloding");
        }
    }
    //返回当前状态
    @Override
    public String toString() {
        return "Now is " + ((state == GAS) ? "gas" : ((state == LIQUID) ? "liquid" : "solid"));
    }
    //测试
    public static void main(String[] args) {
        InitialDemo demo = new InitialDemo();
        System.out.println(demo.toString()); //初始时液态,应该打印出液态信息
        demo.sloiding();
        System.out.println(demo.toString());
        demo.warm();
        System.out.println(demo.toString());
        demo.liquidation();
        System.out.println(demo.toString());
    }
}

我们把所有的代码写到一块,在每个方法中通过判断当前状态是否是方法要求的,需要很多的判断语句,万一科学家发现水还有好多种混合态,哪所有的方法都要改变,我们要利用状态模式了

2.状态模式UML

此处输入图片的描述

  • State接口,定义了一个所有具体状态的公共接口,任何状态都实现这个接口,所有状态之间可以相互替换
  • Context,上下午是一个类,它拥有所有任何部状态
  • ConcreteStateA , 具体状态类

3.代码
State接口

/**State接口,所有的状态(固液气)都要继承他*/
public interface State {
    public void warm();
    public void liquidation();
    public void sloiding();
}

Context上下午

/**Context上下文*/
public class WaterContext {
    //包含了所以的状态
    State gasState;
    State liquidState;
    State soldState;
    //当前状态
    State currentState = null;
    //在构造方法中初始化
    public WaterContext(){
        gasState = new Gas(this);
        liquidState = new Liquid(this);
        soldState = new Solid(this);
        currentState = liquidState;
    }
    public void setCurrentState(State currentState) {
        this.currentState = currentState;

    }
    public State getCurrentState() {
        return currentState;
    }
    //下面上getter()用于在状态具体实现类中改变状态时得到状态
    public State getGasState() {
        return gasState;
    }
    public State getLiquidState() {
        return liquidState;
    }
    public State getSoldState() {
        return soldState;
    }
}

ConcreteStateA

/**注意,每种状态不仅仅要继承State接口,还要持有一个上下午Context的引用*/
public class Gas implements State {
    WaterContext waterContext ;
    public Gas(WaterContext waterContext) {
        this.waterContext = waterContext;
    }
    //错误操作
    @Override
    public void warm() {
        System.out.println("Error :   now is gas , what do you do!");
    }
    //正确的操作
    @Override
    public void liquidation() {
        waterContext.setCurrentState(waterContext.getLiquidState());
        System.out.println("OK :  liquindation , gas become liquid");
    }
    //错误的操作
    @Override
    public void sloiding() {
        System.out.println("Error : you need to become gas to liquid ,them Sloding");
    }
}
/**注意,每种状态不仅仅要继承State接口,还要持有一个上下午Context的引用*/
public class Liquid implements State {
    WaterContext waterContext;
    public Liquid(WaterContext waterContext) {
        this.waterContext = waterContext;
    }
    //下面2个方法都是错误的操作
    @Override
    public void warm() {
        System.out.println("Error  :   you need to become liquid to solid , them warm...");
    }
    @Override
    public void liquidation() {
        System.out.println("Error :  now is liquid , what do you do!");
    }
    //正确的操作,所有设置转变后的状态,打印ok
    @Override
    public void sloiding() {
        waterContext.setCurrentState(waterContext.getSoldState());
        System.out.println("OK : Sloding , liquid become solid");
    }
}
public class Solid implements State {
    WaterContext waterContext;
    public Solid(WaterContext waterContext) {
        this.waterContext = waterContext;
    }
    @Override
    public void warm() {
        waterContext.setCurrentState(waterContext.getGasState());
        System.out.println("Ok :  warming , solid become gas");
    }
    @Override
    public void liquidation() {
        System.out.println("Error : you need to become solid to gas ,them liquidation");
    }
    @Override
    public void sloiding() {
        System.out.println("Error :  now is Solid , what do you do!");
    }
}

测试Main

public class Main {
    public static void main(String[] args) {
        //正确的执行,我们在WaterContext中初始化状态为liquid
        WaterContext waterContext = new WaterContext();
        //liquid -> sold
        waterContext.getCurrentState().sloiding();
        //sold -> gas
        waterContext.getCurrentState().warm();
        // gas->liquid
        waterContext.getCurrentState().liquidation();
    }
}
//结果:
OK : Sloding , liquid become solid
Ok :  warming , solid become gas
OK :  liquindation , gas become liquid

Process finished with exit code 0
//错误的测试一下
        WaterContext waterContext = new WaterContext();
        //liquid无法执行warm,状态还是液体
        waterContext.getCurrentState().warm();
        //liquid -> sold
        waterContext.getCurrentState().sloiding();
        // 当前是sold,无法执行liquidation()操作
        waterContext.getCurrentState().liquidation();
//错误测试结果和上面注释的一样
Error  :   you need to become liquid to solid , them warm...
OK : Sloding , liquid become solid
Error : you need to become solid to gas ,them liquidation

Process finished with exit code 0

看了代码后,结合UML类图,对状态模式更加清晰了,我们这里总结一下,在状态模式中,将一群行为封装在状态对象中,context的新闻随时可委托到它内部的任何一个状态对象,随着时间的改变,contex中的当前状态在一直改变,但是context的客户却不知道,只需要调用contex当前状态的方法就可以

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值