zoukankan      html  css  js  c++  java
  • 设计模式 | 状态模式(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();
        }
    }

    结果输出:

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

    总结:

    依旧是为了解耦的一个设计模式,通过抽象的方式来实现,感觉光看代码的话,很多设计模式其实长得都很像,本质区别只是在应用的场景上。
    主要是理解在什么情况下应该用哪个设计模式。
    而状态模式主要是用在,对象的行为依赖于它的状态,且状态间转换的条件判断相对比较复杂的情况,表现在代码中就是有很多条件判断分支。
    从上面的例子,可以看出各个状态间的转换有一种传递的关系,而不是把所有其他的条件判断都写在里面,这样可以保证当前的状态只关注和自己相关的条件。
  • 相关阅读:
    DatePickerDialog、AutoCompleteTextView
    GoF23种设计模式之创建型模式之单态模式
    GoF23种设计模式之创建型模式之原型模式
    GoF23种设计模式之结构型模式之适配器模式
    GoF23种设计模式之结构型模式之桥接模式
    GoF23种设计模式之结构型模式之组合模式
    GoF23种设计模式之结构型模式之装饰模式
    GoF23种设计模式之结构型模式之外观模式
    GoF23种设计模式之结构型模式之享元模式
    GoF23种设计模式之结构型模式之代理模式
  • 原文地址:https://www.cnblogs.com/imoqian/p/10965185.html
Copyright © 2011-2022 走看看