设计模式 | 状态模式(state)

定义:

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

结构:(书中图,侵删)

 

一个抽象的状态类,拥有一个与状态相关的行为方法
若干个具体的状态类
一个上下文类,持有抽象状态类
 

实例:

写到这里,看了一眼桌上的零食,想到了一个例子。
食品大概分为三个阶段,或者说三种状态:最佳食用期,可食用期(过了最佳食用期,但未过时),已过时。
食品类(包含:最佳食用天数、过时天数、出厂天数):
package designpattern.state;

public class Food {
    private String name;
    private int manufactureDays;// 出厂天数
    private int bestBeforeDays;// 最佳食用天数(从出厂时间算起)
    private int expiryDays;// 保质期天数
    private FoodState foodState;

    public Food(String name, int bestBeforeDays, int expiryDays) {
        this.name = name;
        this.bestBeforeDays = bestBeforeDays;
        this.expiryDays = expiryDays;
        this.foodState = new BestBeforeState();
    }

    public void eat() {
        foodState.reaction(this);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getManufactureDays() {
        return manufactureDays;
    }

    public void setManufactureDays(int manufactureDays) {
        this.manufactureDays = manufactureDays;
    }

    public int getBestBeforeDays() {
        return bestBeforeDays;
    }

    public void setBestBeforeDays(int bestBeforeDays) {
        this.bestBeforeDays = bestBeforeDays;
    }

    public int getExpiryDays() {
        return expiryDays;
    }

    public void setExpiryDays(int expiryDays) {
        this.expiryDays = expiryDays;
    }

    public FoodState getFoodState() {
        return foodState;
    }

    public void setFoodState(FoodState foodState) {
        this.foodState = foodState;
    }

}
抽象状态类:
package designpattern.state;

public interface FoodState {
    public void reaction(Food food);
}
具体状态类:
最佳食用状态:
package designpattern.state;

public class BestBeforeState implements FoodState {

    @Override
    public void reaction(Food food) {
        if (food.getManufactureDays() <= food.getBestBeforeDays()) {
            System.out.print("第" + food.getManufactureDays() + "天吃,");
            System.out.println("[" + food.getName() + "]在最佳食用期中,好吃~~");
        } else {
            food.setFoodState(new EatableState());
            food.eat();
        }
    }

}
可食用状态:
package designpattern.state;

public class EatableState implements FoodState {

    @Override
    public void reaction(Food food) {
        if (food.getManufactureDays() <= food.getExpiryDays()) {
            System.out.print("第" + food.getManufactureDays() + "天吃,");
            System.out.println("[" + food.getName() + "]在可食用期中,味道还能够");
        } else {
            food.setFoodState(new ExpiredState());
            food.eat();
        }
    }

}
已过时状态:
package designpattern.state;

public class ExpiredState implements FoodState {

    @Override
    public void reaction(Food food) {
        if (food.getManufactureDays() > food.getExpiryDays()) {
            System.out.print("第" + food.getManufactureDays() + "天吃,");
            System.out.println("[" + food.getName() + "]过时了,无法吃了");
        } else {
            food.setFoodState(new EatableState());
            food.eat();
        }
    }

}
客户端:
package designpattern.state;

public class Client {
    public static void main(String[] args) {
        Food food = new Food("面包", 1, 7);// 设置最佳食用期1天,保质期7天
        food.setManufactureDays(1);
        food.eat();

        food.setManufactureDays(3);
        food.eat();

        food.setManufactureDays(10);
        food.eat();
    }
}

结果输出:react

第1天吃,[面包]在最佳食用期中,好吃~~
第3天吃,[面包]在可食用期中,味道还能够
第10天吃,[面包]过时了,无法吃了

总结:

依旧是为了解耦的一个设计模式,经过抽象的方式来实现,感受光看代码的话,不少设计模式其实长得都很像,本质区别只是在应用的场景上。
主要是理解在什么状况下应该用哪一个设计模式。
而状态模式主要是用在,对象的行为依赖于它的状态,且状态间转换的条件判断相对比较复杂的状况,表如今代码中就是有不少条件判断分支。
从上面的例子,能够看出各个状态间的转换有一种传递的关系,而不是把全部其余的条件判断都写在里面,这样能够保证当前的状态只关注和本身相关的条件。
相关文章
相关标签/搜索