由于在业务处理上使用了较多的 switch case 或者 if else,使用了策略模式改造下代码,以便后续的扩展,
但不应为了设计模式而设计模式,应从具体业务出发,不然只会让代码的复杂度增加
也叫 政策模式(Policy Pattern)。指的是对象具备某个行为,但是在不同的场景中,该行为有不同的实现算法。比如一个人的交税比率与他的工资有关,不同的工资水平对应不同的税率。
策略模式使用的就是面向对象的继承和多态机制,从而实现同一行为在不同场景下具备不同实现。
策略模式本质:分离算法,选择实现
1)直白写法
public void DoWork(int taskType)
{
switch (taskType)
{
case (int)TaskType.上传单价:
Console.WriteLine("执行上传单价业务");
break;
case (int)TaskType.上传工单:
Console.WriteLine("执行上传工单业务");
break;
case (int)TaskType.上传配件:
Console.WriteLine("执行上传配件业务");
break;
case (int)TaskType.上传附件:
Console.WriteLine("执行上传附件业务");
break;
default:
Console.WriteLine("无效任务类型");
break;
}
}
2)简单策略模式
截取自 http://my.oschina.net/BreathL/blog/52655
2.1)创建策略接口类
///
/// 策略类接口
///
public interface IStrategy
{
void DoStrategyWork();
}
2.2)创建策略实现类
public class 上传单价 : IStrategy
{
public void DoStrategyWork()
{
Console.WriteLine("执行上传单价业务");
}
}
2.3)创建对外调用类
public class User
{
public void StartHere(IStrategy strategy)
{
strategy.DoStrategyWork();
}
}
2.4)调用
new 一般策略写法.User().StartHere(new InstanceFactory<一般策略写法.IStrategy>().CreateInstanceByEnumName(tType));
3)上下文的引入
上下层调用、交互,往往不是固定不变的,比如调用函数的参数变化、增加方法等
截取自 http://my.oschina.net/BreathL/blog/52655
3.1)创建策略抽象类(接口也是可以的,具体业务具体分析)
///
/// 策略类抽象类
///
public abstract class IStrategy
{
public abstract TaskType CommandType { get; }
public abstract void DoStrategyWork(StrategyContext strategyContext);
}
3.2)创建策略实现类
public class 上传单价 : IStrategy
{
public override TaskType CommandType => TaskType.上传单价;
public override void DoStrategyWork(StrategyContext strategyContext)
{
Console.Write("执行上传单价业务 ");
Console.WriteLine("我是可变参数:" + strategyContext.pars);
}
}
3.3)创建上下文类
通过上下文 进行对应策略算法调用,执行具体实现类的算法,同时写携带业务交互参数
public class StrategyContext
{
private IStrategy _strategy;
#region 可变的上下文参数
public string pars { get; set; }
#endregion
public StrategyContext(IStrategy strategy)
{
this._strategy = strategy;
}
public void InvokingStrategy()
{
this._strategy.DoStrategyWork(this);
}
}
3.4)创建对外调用类
public class User
{
private StrategyContext strategyContext;
public User(TaskType taskType, string pars)
{
this.strategyContext = new StrategyContext(new InstanceFactory().CreateInstanceBySubClass(taskType));
this.strategyContext.pars = pars;
}
public void StartHere()
{
strategyContext.InvokingStrategy();
}
}
3.5)调用
new 上下文策略写法.User(tType, "我是参数").StartHere();
///
/// 利用反射创建具体策略类,并缓存起来
///
public class InstanceFactory where T : class
{
///
/// 一般处理对象缓存
///
private static Dictionary dicCommands = new Dictionary();
///
/// 上下文策略对象缓存
///
private static Dictionary dicContextCommands = new Dictionary();
///
/// 根据TaskType 的名称创建类对象
///
///
///
public T CreateInstanceByEnumName(TaskType taskType)
{
foreach (TaskType cd in Enum.GetValues(typeof(TaskType)))
{
if (!dicCommands.Keys.Contains(cd))
{
//(基类)Assembly.Load("当前程序集名称").CreateInstance("命名空间.子类名称"));
T baseCommand = Assembly.Load(typeof(T).Assembly.GetName().Name)
.CreateInstance((typeof(T).Namespace + "." + cd)) as T;
if (baseCommand != null)
{
dicCommands.Add(cd, baseCommand);
}
}
}
return dicCommands.FirstOrDefault(c => c.Key == taskType).Value;
}
///
/// 通过继承关系创建子类
///
///
///
public T CreateInstanceBySubClass(TaskType taskType)
{
Type objType = typeof(T);
// 获取此类型所在的程序集
Assembly assembly = objType.Assembly;
// 遍历获取此程序集中所有的类
foreach (Type t in assembly.GetTypes())
{
// 是类并且不是抽象类并且继承IBaseCommand
if (t.IsClass && !t.IsAbstract && t.IsSubclassOf(objType))
{
// 创建策略实例类
T command = Activator.CreateInstance(t) as T;
var key = (TaskType)Enum.Parse(typeof(TaskType), t.GetProperty("CommandType").DeclaringType.Name);
if (command != null && !dicCommands.ContainsKey(key))
{
dicContextCommands.Add(key, command);
}
}
}
return dicContextCommands.FirstOrDefault(c => c.Key == taskType).Value;
}
}
https://github.com/harrylsp/Strategy
https://my.oschina.net/BreathL/blog/52655
https://blog.csdn.net/qq_19348391/article/details/84404034
https://blog.csdn.net/site008/article/details/77947566