设计模式之状态模式

Posted 曾淘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之状态模式相关的知识,希望对你有一定的参考价值。

概要

设计模式是一门艺术,如果真正了解这门艺术,你会发现,世界都将变得更加优美。

定义

当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类

使用场景

1.一个对象的行为取决于它的状态,状态改变,行为改变
2.包含大量跟状态相关的条件

UML

大家看这个类图,看起来更前一篇策略模式差不多,那么这两个之间有什么区别么?

1.Status

抽象状态,里面做一些状态相关的事情

2.AStatus

具体的状态,实现抽象状态

3.Context

上下文,设置相关状态,改变对象操作的行为

案例分析

接下来我会为大家分析一个案例,这个案例,就是根据状态改变对象的行为
(1)计算器功能

package com.zengtao.demo.status;

public class Calcuator 

    public static final int OFF = 1;
    public static final int ON = 2;
    private int mStatus;

    public void turnOff() 
        mStatus = OFF;
        System.out.println("关机了");
    

    public void turnOn() 
        mStatus = ON;
        System.out.println("开机了");
    

    public void add() 
        if (mStatus == ON) 
            System.out.println("计算加法");
         else 
            System.out.println("计算器已关机,请先开启");
        
    

    public void sub() 
        if (mStatus == ON) 
            System.out.println("计算减法");
         else 
            System.out.println("计算器已关机,请先开启");
        
    

    public void mult() 
        if (mStatus == ON) 
            System.out.println("计算乘法");
         else 
            System.out.println("计算器已关机,请先开启");
        
    

    public void div() 
        if (mStatus == ON) 
            System.out.println("计算除法");
         else 
            System.out.println("计算器已关机,请先开启");
        
    


可以看到,这里面有计算器的加减乘除法则运行,当然里面没有具体实现,如果要实现,也很简单,比如add方法,给两个参数a,b,return a+b;略过

(2)调用

package com.zengtao.demo;

import com.zengtao.demo.status.Calcuator;

public class Main 

    public static void main(String[] str) 

        Calcuator calcuator = new Calcuator();
        calcuator.turnOn();
        calcuator.add();
        calcuator.sub();

        calcuator.turnOff();
        calcuator.mult();
        calcuator.div();

    

(3)结果

大家可以看到,在实际操作中,我们如果关闭了计算器,在按其它的键,是不是有任何作用的,我们利用上面的伪代码实现了简单的流程,但是大家想想,上面的写法有什么问题?

1.问题分析

如果我们在添加一种计算方法,^,根号,那么不是要不停的添加方法,不停的写if-else语句,我们都知道还有计算器还有其他很多功能,清除,平方,立方等等,还这样一直添加么,显然不可能,这种硬编码方式在编程中也是不推荐的。

2.解决问题

1.很多重复代码,多种判断条件语句if-else
2.计算器状态为关闭的时候,产生不同的行为

3.如何解决

很简单,就是今天要掌握的设计模式:状态模式

代码演示

(1)抽象计算器状态

package com.zengtao.demo.status;

public interface CalculatorStatus 

    public void add();

    public void sub();

    public void mult();

    public void div();


(2)具体状态操作

1.关闭状态

package com.zengtao.demo.status;

public class CloseStatus implements CalculatorStatus 

    @Override
    public void add() 
        // do nothing
    

    @Override
    public void sub() 
        // do nothing
    

    @Override
    public void mult() 
        // do nothing
    

    @Override
    public void div() 
        // do nothing
    


2.开启状态

package com.zengtao.demo.status;

public class OpenStatus implements CalculatorStatus 

    @Override
    public void add() 
        System.out.println("计算加法");
    

    @Override
    public void sub() 
        System.out.println("计算减法");
    

    @Override
    public void mult() 
        System.out.println("计算乘法");
    

    @Override
    public void div() 
        System.out.println("计算除法");
    


(3)抽象控制管理

package com.zengtao.demo.status;

public interface Controller 

    public void turnOff();

    public void turnOn();


(4)具体控制

package com.zengtao.demo.status;

public class CalculatorController implements Controller

    private CalculatorStatus mCalculatorStatus;

    public void setmCalculatorStatus(CalculatorStatus mCalculatorStatus) 
        this.mCalculatorStatus = mCalculatorStatus;
    

    @Override
    public void turnOff() 
        setmCalculatorStatus(new CloseStatus());
        System.out.println("已关闭计算器");
    

    @Override
    public void turnOn() 
        setmCalculatorStatus(new OpenStatus());
        System.out.println("已开启计算器");
    


    public void add() 
        mCalculatorStatus.add();
    


    public void sub() 
        mCalculatorStatus.sub();
    


    public void mult() 
        mCalculatorStatus.mult();
    


    public void div() 
        mCalculatorStatus.div();
    


(5)调用

package com.zengtao.demo;

import com.zengtao.demo.status.CalculatorController;

public class Main 

    public static void main(String[] str) 

        CalculatorController calculatorController = new CalculatorController();
        calculatorController.turnOn();
        calculatorController.add();
        calculatorController.sub();

        // 关闭计算器,无效
        calculatorController.turnOff();
        calculatorController.mult();
        calculatorController.div();

    

(6)结果

总结

大家会发现,跟具体情况符合,关闭计算器,我们在调用乘法和除法的时候,是无效的,没有任何效果,因为在关闭状态里面,我们没有做任何处理,只有开启的时候,在做操作

这样写有什么好处?

1.解耦,我们没有将各种状态堆积在一起
2.没有重复的过多条件判断语句if-else
3.控制了访问的权限,没有直接访问计算器本身,而是通过了CalculatorController
4.有利于扩展和新增

比如:我们要有超级计算器,我们可以实现具体的抽象状态,添加具体的方法,或者超超级计算器,在增加相应方法,单独自己实现自己的逻辑,不用去修改以前的逻辑和代码

这是我们编码的最核心点:尽量新增而不是修改

好了,以上就是状态模式的简单应用了,跟策略模式还是有很大的差异,大家可以对比下,如果了解策略模式,请点击查看,谢谢

上一篇:设计模式之策略模式

以上是关于设计模式之状态模式的主要内容,如果未能解决你的问题,请参考以下文章

行为型:设计模式之解释器模式(二十二)

设计模式之解释器模式

设计模式之状态模式

设计模式之状态模式20170712

python设计模式之状态模式

设计模式之状态模式