• 设计模式(19)状态模式


    模式介绍

    状态模式旨在允许对象在其内部状态改变时改变其自身行为。

    示例

    我们以烤牛排为例,生熟程度分为:

    • Uncooked (not safe to eat)
    • Rare
    • Medium-Rare (mid-rare)
    • Medium
    • Medium-Well (mid-well)
    • Well done

    简单来说就是从生到熟的几个档次。

    抽象的状态类:

    /// <summary>
    /// The State abstract class
    /// </summary>
    abstract class Doneness
    {
        protected Steak steak;
        protected double currentTemp;
        protected double lowerTemp;
        protected double upperTemp;
        protected bool canEat;
    
        public Steak Steak
        {
            get { return steak; }
            set { steak = value; }
        }
    
        public double CurrentTemp
        {
            get { return currentTemp; }
            set { currentTemp = value; }
        }
    
        public abstract void AddTemp(double temp);
        public abstract void RemoveTemp(double temp);
        public abstract void DonenessCheck();
    }
    

    具体的状态类:

    /// <summary>
    /// A Concrete State class.
    /// </summary>
    class Uncooked : Doneness
    {
        public Uncooked(Doneness state)
        {
            currentTemp = state.CurrentTemp;
            steak = state.Steak;
            Initialize();
        }
    
        private void Initialize()
        {
            lowerTemp = 0;
            upperTemp = 130;
            canEat = false;
        }
    
        public override void AddTemp(double amount)
        {
            currentTemp += amount;
            DonenessCheck();
        }
    
        public override void RemoveTemp(double amount)
        {
            currentTemp -= amount;
            DonenessCheck();
        }
    
        public override void DonenessCheck()
        {
            if (currentTemp > upperTemp)
            {
                steak.State = new Rare(this);
            }
        }
    }
    
    /// <summary>
    /// A 'ConcreteState' class.
    /// </summary>
    class Rare : Doneness
    {
        public Rare(Doneness state) : this(state.CurrentTemp, state.Steak)
        {
        }
    
        public Rare(double currentTemp, Steak steak)
        {
            this.currentTemp = currentTemp;
            this.steak = steak;
            canEat = true; //We can now eat the steak
            Initialize();
        }
    
        private void Initialize()
        {
            lowerTemp = 130;
            upperTemp = 139.999999999999;
            canEat = true;
        }
    
        public override void AddTemp(double amount)
        {
            currentTemp += amount;
            DonenessCheck();
        }
    
        public override void RemoveTemp(double amount)
        {
            currentTemp -= amount;
            DonenessCheck();
        }
    
        public override void DonenessCheck()
        {
            if (currentTemp < lowerTemp)
            {
                steak.State = new Uncooked(this);
            }
            else if (currentTemp > upperTemp)
            {
                steak.State = new MediumRare(this);
            }
        }
    }
    
    /// <summary>
    /// A Concrete State class
    /// </summary>
    class MediumRare : Doneness
    {
        public MediumRare(Doneness state) : this(state.CurrentTemp, state.Steak)
        {
        }
    
        public MediumRare(double currentTemp, Steak steak)
        {
            this.currentTemp = currentTemp;
            this.steak = steak;
            canEat = true;
            Initialize();
        }
    
        private void Initialize()
        {
            lowerTemp = 140;
            upperTemp = 154.9999999999;
        }
    
        public override void AddTemp(double amount)
        {
            currentTemp += amount;
            DonenessCheck();
        }
    
        public override void RemoveTemp(double amount)
        {
            currentTemp -= amount;
            DonenessCheck();
        }
    
        public override void DonenessCheck()
        {
            if (currentTemp < 0.0)
            {
                steak.State = new Uncooked(this);
            }
            else if (currentTemp < lowerTemp)
            {
                steak.State = new Rare(this);
            }
            else if (currentTemp > upperTemp)
            {
                steak.State = new Medium(this);
            }
        }
    }
    
    /// <summary>
    /// A Concrete State class
    /// </summary>
    class Medium : Doneness
    {
        public Medium(Doneness state) : this(state.CurrentTemp, state.Steak)
        {
        }
    
        public Medium(double currentTemp, Steak steak)
        {
            this.currentTemp = currentTemp;
            this.steak = steak;
            canEat = true;
            Initialize();
        }
    
        private void Initialize()
        {
            lowerTemp = 155;
            upperTemp = 169.9999999999;
        }
    
        public override void AddTemp(double amount)
        {
            currentTemp += amount;
            DonenessCheck();
        }
    
        public override void RemoveTemp(double amount)
        {
            currentTemp -= amount;
            DonenessCheck();
        }
    
        public override void DonenessCheck()
        {
            if (currentTemp < 130)
            {
                steak.State = new Uncooked(this);
            }
            else if (currentTemp < lowerTemp)
            {
                steak.State = new MediumRare(this);
            }
            else if (currentTemp > upperTemp)
            {
                steak.State = new WellDone(this);
            }
        }
    }
    
    /// <summary>
    /// A Concrete State class
    /// </summary>
    class WellDone : Doneness //aka Ruined
    {
        public WellDone(Doneness state) : this(state.CurrentTemp, state.Steak)
        {
        }
    
        public WellDone(double currentTemp, Steak steak)
        {
            this.currentTemp = currentTemp;
            this.steak = steak;
            canEat = true;
            Initialize();
        }
    
        private void Initialize()
        {
            lowerTemp = 170;
            upperTemp = 230;
        }
    
        public override void AddTemp(double amount)
        {
            currentTemp += amount;
            DonenessCheck();
        }
    
        public override void RemoveTemp(double amount)
        {
            currentTemp -= amount;
            DonenessCheck();
        }
    
        public override void DonenessCheck()
        {
            if (currentTemp < 0)
            {
                steak.State = new Uncooked(this);
            }
            else if (currentTemp < lowerTemp)
            {
                steak.State = new Medium(this);
            }
        }
    }
    

    上下文类-牛排:

    /// <summary>
    /// The Context class
    /// </summary>
    class Steak
    {
        private Doneness _state;
        private string _beefCut;
    
        public Steak(string beefCut)
        {
            _cook = beefCut;
            _state = new Rare(0.0, this);
        }
    
        public double CurrentTemp
        {
            get { return _state.CurrentTemp; }
        }
    
        public Doneness State
        {
            get { return _state; }
            set { _state = value; }
        }
    
        public void AddTemp(double amount)
        {
            _state.AddTemp(amount);
            Console.WriteLine("Increased temperature by {0} degrees.", amount);
            Console.WriteLine(" Current temp is {0}", CurrentTemp);
            Console.WriteLine(" Status is {0}", State.GetType().Name);
            Console.WriteLine("");
        }
    
        public void RemoveTemp(double amount)
        {
            _state.RemoveTemp(amount);
            Console.WriteLine("Decreased temperature by {0} degrees.", amount);
            Console.WriteLine(" Current temp is {0}", CurrentTemp);
            Console.WriteLine(" Status is {0}", State.GetType().Name);
            Console.WriteLine("");
        }
    }
    

    客户端调用:

    static void Main(string[] args)
    {
        //Let's cook a steak!
        Steak account = new Steak("T-Bone");
    
        // Apply temperature changes
        account.AddTemp(120);
        account.AddTemp(15);
        account.AddTemp(15);
        account.RemoveTemp(10); //Yes I know cooking doesn't work this way, bear with me.
        account.RemoveTemp(15);
        account.AddTemp(20);
        account.AddTemp(20);
        account.AddTemp(20);
    
        Console.ReadKey();
    }
    

    总结

    状态模式允许对象的行为随着其内部状态的改变而改变,并且它通过使对象的状态与对象本身分开来完成这一任务。
    因此,状态可以为对象实现它们自己的行为,并且对象可以对其内部状态改变作出“反应”。

    源代码

    https://github.com/exceptionnotfound/DesignPatterns/tree/master/State

    原文

    https://www.exceptionnotfound.net/state-the-daily-design-pattern/

  • 相关阅读:
    【转载】C/C++中extern关键字详解
    【转载】extern "C"的用法解析(原博主就是抄百度百科的,不如另外一篇好)
    lua Date和Time
    MySQL-Linux安装
    Hive-0.13安装
    MR案例:单表关联查询
    MR案例:小文件处理方案
    MR案例:链式ChainMapper
    MR案例:定制Partitioner
    MR案例:多文件输出MultipleOutputs
  • 原文地址:https://www.cnblogs.com/talentzemin/p/9956461.html
Copyright © 2020-2023  润新知