Java DesignPartten Code

设计模式-状态模式

Posted on 2020-10-28,4 min read

定义

  • Allow an object to alter its behavior when its internal state changes.The object will appear to change its class.(当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。)

  • 角色

    • State抽象状态角色:接口或抽象类,负责对象状态定义,并且封装环境角色以实现状态切换。
    • ConcreteState具体状态角色:每一个具体状态必须完成两个职责:本状态的行为管理以及趋向状态处理,通俗地说, 就是本状态下要做的事情,以及本状态如何过渡到其他状态。
    • Context环境角色:定义客户端需要的接口,并且负责具体状态的切换。
  • 通用类图:

    状态模式通用类图

优点

  • 结构清晰:避免了过多的switch...case或者if...else语句的使用,避免了程序的复杂性,提高系统的可维护性
  • 很好地体现了开闭原则和单一职责原则:每个状态都是一个子类,要增加状态就要增加子类,要修改状态,只修改一个子类就可以了。
  • 封装性非常好:这也是状态模式的基本要求,状态变换放置到类的内部来实现,外部的调用不用知道类内部如何实现状态和行为的变换

缺点

  • 子类会太多,也就是类膨胀。

使用场景

  • 场景:
    • 行为随状态改变而改变的场景:这也是状态模式的根本出发点,例如权限设计,人员的状态不同即使执行相同的行为结果也会不同,在这种情况下需要考虑使用状态模式
    • 条件、分支判断语句的替代者:在程序中大量使用switch语句或者if判断语句会导致程序结构不清晰,逻辑混乱,使用状态模式可以很好地避免这一问题,它通过扩展子类实现了条件的判断处理。

代码

状态模式

代码

package com.pattern.state;

public class StatePartten {
    public static void main(String[] args) {

    }
}

/**
 * 抽象环境角色
 */
abstract class State {
    //定义一个环境角色,提供子类访问
    protected Context context;

    //设置环境角色
    public void setContext(Context _context) {
        this.context = _context;
    }

    //行为1
    public abstract void handle1();

    //行为2
    public abstract void handle2();
}

class ConcreteState1 extends State {
    @Override
    public void handle1() {
        //本状态下必须处理的逻辑
    }

    @Override
    public void handle2() {
        //设置当前状态为stat2
        super.context.setCurrentState(Context.STATE2);
        //过渡到state2状态,由Context实现
        super.context.handle2();
    }
}

class ConcreteState2 extends State {
    @Override
    public void handle1() {
        //设置当前状态为state1
        super.context.setCurrentState(Context.STATE1);
        //过渡到state1状态,由Context实现
        super.context.handle1();
    }

    @Override
    public void handle2() {
        //本状态下必须处理的逻辑
    }
}

/**
 * 具体环境角色
 */
class Context {
    //定义状态
    public final static State STATE1 = new ConcreteState1();
    public final static State STATE2 = new ConcreteState2();
    //当前状态
    private State CurrentState;

    //获得当前状态
    public State getCurrentState() {
        return CurrentState;
    }

    //设置当前状态
    public void setCurrentState(State currentState) {
        this.CurrentState = currentState;
//切换状态
        this.CurrentState.setContext(this);
    }

    //行为委托
    public void handle1() {
        this.CurrentState.handle1();
    }

    public void handle2() {
        this.CurrentState.handle2();
    }
}

注意

  • 把状态对象声明为静态常量,有几个状态对象就声明几个静态常量
  • 环境角色具有状态抽象角色定义的所有行为,具体执行使用委托方式。
  • 状态模式适用于当某个对象在它的状态发生改变时,它的行为也随着发生比较大的变化,也就是说在行为受状态约束的情况下可以使用状态模式,而且使用时对象的状态最好不要超过5个。

下一篇: 设计模式-访问者模式→

loading...