今天就说一说设计模式中的策略模式,从名字来讲,意思就是,对应不同的情况,就有一种解决问题的办法,不同的情况,就有不同的应对方法,这就是策略模式,非常的智能化。
也可以参考菜鸟
策略模式 | 菜鸟教程
1.下面我们看一组经常会写到的代码
尤其在业务场景非常复杂的逻辑中,经常出现大量的if语句,包括switch语句,不过switch稍微比if语句好点。
namespace StrategyPatternDemo
{internal class Program{static void Main(string[] args){string a = Console.ReadLine().ToString();if (a == "a"){a = "A";//业务}else if (a == "b"){a = "B";//业务}else if (a == "c"){a = "C";//业务}else if (a == "d"){a = "D";//业务}else if (a == "e"){a = "E";//业务}else if (a == string.Empty){a = "空";//业务}Console.WriteLine(a);Console.ReadKey();}}
}
该代码要实现的业务就是,输入小写字母,然后输出大写字母,再处理一些业务员需求,当然也可以ToUpper方法,就可以了,我们不做讨论,主要是要采用策略模式来设计一下(当然这个也算是过度设计了)。代码简洁、有效、实现功能才是最好的代码。
2.接下来,我们使用策略模式
TypeSelect类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace StrategyPatternDemo
{/// <summary>/// 业务类型,后面继续加/// </summary>public enum TypeSelect{A = 1,B = 2,C = 3,D = 4,E = 5,Empty = 6,}
}
2.StrategyPatternDemo类,定义公共接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace StrategyPatternDemo
{/// <summary>/// 定义一个公开的接口/// </summary>public interface IStrategy{void Execute(string str);}
}
3.StrategyPatternDemo类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;namespace StrategyPatternDemo
{/// <summary>/// 增加实例/// </summary>/// <typeparam name="T"></typeparam>public class InstanceFactory<T> where T : class{private static Dictionary<TypeSelect, T> dicCommands = new Dictionary<TypeSelect, T>();public T CreateInstanceByEnumName(TypeSelect taskType){foreach (TypeSelect cd in Enum.GetValues(typeof(TypeSelect))){if (!dicCommands.Keys.Contains(cd)){//此处获取业务类的种类,可以使用其他方法T baseCommand = Assembly.Load(typeof(T).Assembly.GetName().Name).CreateInstance((typeof(T).Namespace + ".Business.StrategyBusiness" + cd)) as T;if (baseCommand != null){dicCommands.Add(cd, baseCommand);}}}return dicCommands.FirstOrDefault(c => c.Key == taskType).Value;}}
}
4.StrategyPatternDemo类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace StrategyPatternDemo
{/// <summary>/// 一般写法/// </summary>internal class Context{private IStrategy _strategy;public Context(IStrategy strategy){_strategy = strategy;}public void ExecuteStrategy(string str){_strategy?.Execute(str);}}
}
5.业务类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace StrategyPatternDemo.Business
{internal class StrategyBusinessA : IStrategy{public void Execute(string s){Console.WriteLine(s);//其他业务}}
}
6.调用
可见,调用只需要一句话
using StrategyPatternDemo.Business;namespace StrategyPatternDemo
{internal class Program{static void Main(string[] args){//string a = Console.ReadLine().ToString();//if (a == "a")//{// a = "A";// //业务//}//else if (a == "b")//{// a = "B";// //业务//}//else if (a == "c")//{// a = "C";// //业务//}//else if (a == "d")//{// a = "D";// //业务//}//else if (a == "e")//{// a = "E";// //业务//}//else if (a == string.Empty)//{// a = "空";// //业务//}//Console.WriteLine(a);//Console.ReadKey();int a = Convert.ToInt32(Console.ReadLine());var str = (TypeSelect)a; //转化类型new Context(new InstanceFactory<IStrategy>().CreateInstanceByEnumName(str)).ExecuteStrategy(str.ToString()); //调用Console.ReadKey();}}
}
7.效果
8.增加F
只需要增加2处,其他地方不变
效果
9.文件总览
此文,只是为了策略模式而策略模式,设计模式在日常的开发代码中,很少使用,比如以上案例,使用设计模式,就太复杂了, 根本没必要使用。但是在用到的时候,将会非常的给力,大部分都是后期业务堆起来后,才会体现出设计模式优点,当然使用了设计模式,也有缺点,一切的一切,都按照当下的业务量来衡量,是否有必要使用设计模式。
其中ConsoleApp1是另一种方式实现,效果一样
源码:
https://download.csdn.net/download/u012563853/87993185