设计模式学习笔记三:策略模式和状态模式

一.策略模式概念

  策略模式(Strategy)定义了算法家族,分别封装起来,让它们之间可以互相替换.此模式实现了算法的变化不会影响到使用算法的用户.

  策略模式定义了一系列算法,这些算法完成的都是相同的工作,只是实现不同.因此可以使用相同的方式调用这些算法,减少各种算法和算法类之间的耦合.

二.策略模式实现类图

三.策略模式示例代码

/************************************
* 创建人:movin
* 创建时间:2021/8/6 20:38:35
* 版权所有:个人
***********************************/
using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternsCore
{
    /// <summary>
    /// 环境类
    /// </summary>
    public class Context
    {
        //持有策略
        private IStrategy strategy;
        /// <summary>
        /// 设置策略
        /// </summary>
        /// <param name="strategy"></param>
        public void SetStrategy(IStrategy strategy)
        {
            this.strategy = strategy;
        }
        /// <summary>
        /// 执行策略
        /// </summary>
        public void DoStrategy()
        {
            if (strategy != null)
            {
                strategy.DoStrategy();
            }
            else
            {
                Console.WriteLine("please set strategy before do strategy");
            }
        }
    }
    /// <summary>
    /// 策略接口
    /// </summary>
    public interface IStrategy
    {
        void DoStrategy();
    }
    /// <summary>
    /// 策略A
    /// </summary>
    public class StrategyA : IStrategy
    {
        public void DoStrategy()
        {
            Console.WriteLine("do strategy A");
        }
    }
    /// <summary>
    /// 策略B
    /// </summary>
    public class StrategyB : IStrategy
    {
        public void DoStrategy()
        {
            Console.WriteLine("do strategy B");
        }
    }
    /// <summary>
    /// 策略C
    /// </summary>
    public class StrategyC : IStrategy
    {
        public void DoStrategy()
        {
            Console.WriteLine("do strategy B");
        }
    }
}
        static void Main(string[] args)
        {
            Context s = new Context();
            s.SetStrategy(new StrategyA());
            s.DoStrategy();
            s.SetStrategy(new StrategyB());
            s.DoStrategy();
            s.SetStrategy(new StrategyC());
            s.DoStrategy();
            Console.ReadKey();
        }

四.状态模式概念

  状态模式(State)就是当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类.

  状态模式允许对象在内部改变状态时改变其行为,目的是为了消除庞大的条件分支语句,也可以理解为将庞大的条件分支判断分解到了很多状态类中,当增加状态时不是添加条件分支语句而是添加状态类,使逻辑更清晰.同时状态类中需要对当前状态作出判断,根据当前状态决定执行哪些逻辑和切换状态.

五.状态模式实现类图

六.状态模式示例代码

/************************************
* 创建人:movin
* 创建时间:2021/8/6 23:36:02
* 版权所有:个人
***********************************/
using System;
using System.Collections.Generic;
using System.Text;

namespace DesignPatternsCore
{
    /// <summary>
    /// 运动
    /// </summary>
    public class Sport
    {
        /// <summary>
        /// 运动速度
        /// </summary>
        public int Speed { get; set; }
        /// <summary>
        /// 当前状态机
        /// </summary>
        public IState state { get; private set; }
        public Sport()
        {
            Speed = 0;
            state = new IdleState();
        }
        public void SetState(IState state)
        {
            this.state = state;
        }
        public void Move()
        {
            state.Move(this);
        }
    }
    /// <summary>
    /// 状态机接口
    /// </summary>
    public interface IState
    {
        /// <summary>
        /// 运动
        /// </summary>
        /// <param name="sport"></param>
        void Move(Sport sport);
    }
    /// <summary>
    /// 闲置状态
    /// </summary>
    public class IdleState : IState
    {
        public void Move(Sport sport)
        {
            if(sport.Speed <= 0)
            {
                Console.WriteLine("idle");
            }
            else
            {
                sport.SetState(new WalkState());
                sport.Move();
            }
        }
    }
    /// <summary>
    /// 走路状态
    /// </summary>
    public class WalkState : IState
    {
        public void Move(Sport sport)
        {
            if(sport.Speed < 8 && sport.Speed > 0)
            {
                Console.WriteLine("walk");
            }
            else
            {
                sport.SetState(new RunState());
                sport.Move();
            }
        }
    }
    /// <summary>
    /// 跑步状态
    /// </summary>
    public class RunState : IState
    {
        public void Move(Sport sport)
        {
            if(sport.Speed >= 8)
            {
                Console.WriteLine("run");
            }
            else
            {
                sport.SetState(new IdleState());
                sport.Move();
            }
        }
    }
}
        static void Main(string[] args)
        {
            Sport s = new Sport();
            s.Speed = 13;
            s.Move();
            Sport s1 = new Sport();
            s1.Speed = 4;
            s1.Move();
            Console.ReadKey();
        }

七.状态模式和策略模式比较

  状态模式和策略模式乍一看类图感觉非常相似,但是两者的区别还是蛮大的.状态模式更加关注不同的状态下的行为不同,而策略模式更加关注同一行为的不同完成方式;状态模式的状态在内部是会自动切换的,这种切换就是在找当前的准确状态,如示例中速度设置为13时,状态机会作出判断,如果不是当前状态会切换至下一状态,直到合适的状态再执行行为.状态模式就好比周末7点起床,如果状态还是很困,会睡个懒觉,如果状态不是很困,会去玩把游戏(状态不同导致行为不同);而策略模式好比周末7点起床,不管状态如何都去玩游戏,但是是玩王者荣耀还是英雄联盟(行为相同,具体执行不同).

原文地址:https://www.cnblogs.com/movin2333/p/15110852.html