1. 状态模式

1.1 介绍

状态模式(state pattern) 的定义:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

在状态模式(State Pattern)中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。

1.2 优缺点

优点

  1. 结构清晰,状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”。
  2. 将状态转换显示化,减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。
  3. 状态类职责明确,有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。

缺点

  1. 状态模式的使用必然会增加系统的类与对象的个数。
  2. 状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。
  3. 状态模式对开闭原则的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源码,否则无法切换到新增状态,而且修改某个状态类的行为也需要修改对应类的源码。

1.3 使用场景

  • 行为随状态改变而改变的场景
  • 条件、分支语句的代替者

1.4 注意事项

在行为受状态约束的时候使用状态模式,而且状态不超过 5 个。状态模式中,最重要的是状态的切换以及清晰的逻辑性。

2. 案例实现

现在布娃娃已经装到车上了,暂时够了,我决定开始我的极速之旅,这是我发现娃娃在不同速度时呈现的状态不一样,我匀速时娃娃正常,我加速时娃娃向后摆动,我减速时娃娃向前摆动。

// 布娃娃
public class Ragdoll {
   
    public String getName(){
   
        return "xx";
    };
    
    public void stop(){
   
        System.out.println("娃娃静止不动");
    }
    
    public void toForward(){
   
        System.out.println("娃娃往前晃");
    }

    public void toBackward(){
   
        System.out.println("娃娃往后晃");
    }
    
    public  static Ragdoll getRagdoll(String ragdollName){
   
        if(ragdollName == "太平公主"){
   
            return new ragdoll_1();
        }else if(ragdollName == "白雪公主"){
   
            return new ragdoll_2();
        }else if(ragdollName == "铁扇公主"){
   
            return new ragdoll_3();
        }
        
        return new ragdoll_1();
    }
}

class ragdoll_1 extends Ragdoll{
   
    public String getName(){
   
        return "太平公主";
    }
}

class ragdoll_2 extends Ragdoll{
   
    public String getName(){
   
        return "白学公主";
    }
}

class ragdoll_3 extends Ragdoll{
   
    public String getName(){
   
        return "铁扇公主";
    }
}

public class DecoratorRagdoll {
   
    private Ragdoll ragdoll;

    public void setRagdoll(Ragdoll ragdoll) {
   
        this.ragdoll = ragdoll;
    }

    public DecoratorRagdoll() {
   
        this.ragdoll = ragdoll;
    }
    
    
    public void getState(int accelerate){
   
        if(accelerate > 0){
   
            ragdoll.toBackward();
        }else if(accelerate < 0){
   
            ragdoll.toForward();
        }else {
   
            ragdoll.stop();
        }
    }
}

// 负责给我我想要的娃娃
public class CraneMachine {
   
    HashMap<String, DecoratorRagdoll> hashMap;

    public CraneMachine() {
   
        this.hashMap = new HashMap<>();
    }

    public DecoratorRagdoll getRagdoll(String ragdollName, String skirtColor){
   
        // 找到娃娃
        if(hashMap.containsKey(ragdollName+skirtColor)){
   
            return hashMap.get(ragdollName+skirtColor);
        }else{
   
            Ragdoll ragdoll = Ragdoll.getRagdoll(ragdollName);
            DecoratorRagdoll build = this.build(ragdoll);
            hashMap.put(ragdollName+skirtColor, build);
            return build;
        }
    }

    private DecoratorRagdoll build(Ragdoll ragdoll){
   
        DecoratorRagdoll decoratorRagdoll = new DecoratorRagdoll();
        decoratorRagdoll.setRagdoll(ragdoll);
        return decoratorRagdoll;
    }
}

public class Car {
   
    private DecoratorRagdoll ragdoll;
    
    private int accelerate;
    
    public void accelerate(){
   
        System.out.println("加速了");
        accelerate += 1;
        this.ragdoll.getState(this.accelerate);
    }
    
    public void slowDown(){
   
        System.out.println("减速了");
        accelerate -= 1;
        this.ragdoll.getState(this.accelerate);
    }
    
    
    public Car(DecoratorRagdoll ragdoll) {
   
        this.ragdoll = ragdoll;
    }

    public Car() {
   
        this.ragdoll = ragdoll;
    }

    public void setRagdoll(DecoratorRagdoll ragdoll) {
   
        this.ragdoll = ragdoll;
    }
}

/** * 状态模式 * *@Author cly *@Date 2021/08/31 16:56 *@Version 1.0 */
public class State {
   
    public static void main(String[] args) {
   
        CraneMachine craneMachine = new CraneMachine();
        Car car = new Car();
        car.setRagdoll(craneMachine.getRagdoll("白雪公主",""));
        car.accelerate();
        car.slowDown();
        car.slowDown();
    }
}

3. 源码实现