经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
设计模式 | 状态模式(state)
来源:cnblogs  作者:莫愆  时间:2019/6/3 9:01:10  对本文有异议

定义:

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

结构:(书中图,侵删)

 

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

实例:

写到这里,看了一眼桌上的零食,想到了一个例子。
食品大概分为三个阶段,或者说三种状态:最佳食用期,可食用期(过了最佳食用期,但未过期),已过期。
食品类(包含:最佳食用天数、过期天数、出厂天数):
  1. package designpattern.state;
  2. public class Food {
  3. private String name;
  4. private int manufactureDays;// 出厂天数
  5. private int bestBeforeDays;// 最佳食用天数(从出厂时间算起)
  6. private int expiryDays;// 保质期天数
  7. private FoodState foodState;
  8. public Food(String name, int bestBeforeDays, int expiryDays) {
  9. this.name = name;
  10. this.bestBeforeDays = bestBeforeDays;
  11. this.expiryDays = expiryDays;
  12. this.foodState = new BestBeforeState();
  13. }
  14. public void eat() {
  15. foodState.reaction(this);
  16. }
  17. public String getName() {
  18. return name;
  19. }
  20. public void setName(String name) {
  21. this.name = name;
  22. }
  23. public int getManufactureDays() {
  24. return manufactureDays;
  25. }
  26. public void setManufactureDays(int manufactureDays) {
  27. this.manufactureDays = manufactureDays;
  28. }
  29. public int getBestBeforeDays() {
  30. return bestBeforeDays;
  31. }
  32. public void setBestBeforeDays(int bestBeforeDays) {
  33. this.bestBeforeDays = bestBeforeDays;
  34. }
  35. public int getExpiryDays() {
  36. return expiryDays;
  37. }
  38. public void setExpiryDays(int expiryDays) {
  39. this.expiryDays = expiryDays;
  40. }
  41. public FoodState getFoodState() {
  42. return foodState;
  43. }
  44. public void setFoodState(FoodState foodState) {
  45. this.foodState = foodState;
  46. }
  47. }
抽象状态类:
  1. package designpattern.state;
  2. public interface FoodState {
  3. public void reaction(Food food);
  4. }
具体状态类:
最佳食用状态:
  1. package designpattern.state;
  2. public class BestBeforeState implements FoodState {
  3. @Override
  4. public void reaction(Food food) {
  5. if (food.getManufactureDays() <= food.getBestBeforeDays()) {
  6. System.out.print("第" + food.getManufactureDays() + "天吃,");
  7. System.out.println("[" + food.getName() + "]在最佳食用期中,好吃~~");
  8. } else {
  9. food.setFoodState(new EatableState());
  10. food.eat();
  11. }
  12. }
  13. }
可食用状态:
  1. package designpattern.state;
  2. public class EatableState implements FoodState {
  3. @Override
  4. public void reaction(Food food) {
  5. if (food.getManufactureDays() <= food.getExpiryDays()) {
  6. System.out.print("第" + food.getManufactureDays() + "天吃,");
  7. System.out.println("[" + food.getName() + "]在可食用期中,味道还可以");
  8. } else {
  9. food.setFoodState(new ExpiredState());
  10. food.eat();
  11. }
  12. }
  13. }
已过期状态:
  1. package designpattern.state;
  2. public class ExpiredState implements FoodState {
  3. @Override
  4. public void reaction(Food food) {
  5. if (food.getManufactureDays() > food.getExpiryDays()) {
  6. System.out.print("第" + food.getManufactureDays() + "天吃,");
  7. System.out.println("[" + food.getName() + "]过期了,没法吃了");
  8. } else {
  9. food.setFoodState(new EatableState());
  10. food.eat();
  11. }
  12. }
  13. }
客户端:
  1. package designpattern.state;
  2. public class Client {
  3. public static void main(String[] args) {
  4. Food food = new Food("面包", 1, 7);// 设置最佳食用期1天,保质期7天
  5. food.setManufactureDays(1);
  6. food.eat();
  7. food.setManufactureDays(3);
  8. food.eat();
  9. food.setManufactureDays(10);
  10. food.eat();
  11. }
  12. }

结果输出:

  1. 1天吃,[面包]在最佳食用期中,好吃~~
  2. 3天吃,[面包]在可食用期中,味道还可以
  3. 10天吃,[面包]过期了,没法吃了

总结:

依旧是为了解耦的一个设计模式,通过抽象的方式来实现,感觉光看代码的话,很多设计模式其实长得都很像,本质区别只是在应用的场景上。
主要是理解在什么情况下应该用哪个设计模式。
而状态模式主要是用在,对象的行为依赖于它的状态,且状态间转换的条件判断相对比较复杂的情况,表现在代码中就是有很多条件判断分支。
从上面的例子,可以看出各个状态间的转换有一种传递的关系,而不是把所有其他的条件判断都写在里面,这样可以保证当前的状态只关注和自己相关的条件。

原文链接:http://www.cnblogs.com/imoqian/p/10965185.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号