定义:
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
结构:(书中图,侵删)
一个抽象的状态类,拥有一个与状态相关的行为方法
若干个具体的状态类
一个上下文类,持有抽象状态类
实例:
写到这里,看了一眼桌上的零食,想到了一个例子。
食品大概分为三个阶段,或者说三种状态:最佳食用期,可食用期(过了最佳食用期,但未过期),已过期。
食品类(包含:最佳食用天数、过期天数、出厂天数):
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(); } }
结果输出:
第1天吃,[面包]在最佳食用期中,好吃~~
第3天吃,[面包]在可食用期中,味道还可以
第10天吃,[面包]过期了,没法吃了
总结:
依旧是为了解耦的一个设计模式,通过抽象的方式来实现,感觉光看代码的话,很多设计模式其实长得都很像,本质区别只是在应用的场景上。
主要是理解在什么情况下应该用哪个设计模式。
而状态模式主要是用在,对象的行为依赖于它的状态,且状态间转换的条件判断相对比较复杂的情况,表现在代码中就是有很多条件判断分支。
从上面的例子,可以看出各个状态间的转换有一种传递的关系,而不是把所有其他的条件判断都写在里面,这样可以保证当前的状态只关注和自己相关的条件。