设计模式学习笔记三:策略模式和状态模式
一.策略模式概念
策略模式(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点起床,不管状态如何都去玩游戏,但是是玩王者荣耀还是英雄联盟(行为相同,具体执行不同).