策略模式的具体应用

1.业务场景

     随着信息化水平逐渐提升,业务部门在数据可视化方面提报了新的需求,上位机软件在扫描枪扫描投入料时,需要将物料的详细发送到对应的LED屏幕上。

2.初步设计

     一开始,只有一个工厂提出这个需求,直接在扫描投入料的代码的后面,增加了调用LED的委托方法(通过委托方式实现线程级别的发送,从未不影响正常业务)。满足需求后,向LED发送数据的业务场景越来越多,比如,切换计划、减料、扫描工位、扫描投入料。这几种场景下可能会导致LED发送方法的同时调用,造成多线程同时出发LED自带的DLL方法的调用,造成发送失败的问题,基于该问题,在实际发送方法增加lock(mLockObj)的锁控制,从未避免出现多线程调用问题。

     随着典型业务的推广,其他工厂也逐渐开始有这种需求,但是采购的LED屏幕厂家却不一样,如果仅仅为了实现需求,可以在代码中根据工厂标志位,进行if...else if...或switch的判断。

3.设计提升

    3.1创建发送信息类

    各工厂实际业务可能会出现不一致的问题, 导致LED显示的信息不一样,如果把信息直接以参数的形式进行传递,后期需要增加显示时,涉及的修改太多,因此,将发送方法的参数提取成一个信息类,以后再扩展直接在类中扩展属性即可,需要使用该参数时,直接调用,涉及到的修改降低到最小。

比如:

 1     public class LEDParameter
 2     {
 3         private int mScreenID;
 4 
 5         private string mIPAddress;
 6 
 7         private string mMessage;
 8 
 9         private Color mForeColor;
10 
11         private int mFontSize;
12     }

   3.2 定义发送方法的接口,每个工厂对应一个具体的类来实现该接口。

   发送接口

1     public interface ILEDDisplay
2     {
3         void DisplayMessage(LEDParameter parameter);
4     }

   各工厂的实现类

 1     public class ALEDDisplay : ILEDDisplay
 2     {
 3         public void DisplayMessage(LEDParameter parameter)
 4         {
 5             Console.WriteLine("Using AFactory LED Display Method");
 6         }
 7     }
 8   
 9     public class BLEDDisplay : ILEDDisplay
10     {
11         public void DisplayMessage(LEDParameter parameter)
12         {
13             Console.WriteLine("Using BFactory LED Display Method");
14         }
15     }

   3.3 根据实际情况初始化实现类

 1 ILEDDisplay dislay = null;
 2 switch (factoryName)
 3 {
 4      case "A":
 5          dislay = new ALEDDisplay();
 6           break;
 7      case "B":
 8            dislay = new BLEDDisplay();
 9            break;
10  }
11      
12  //实际调用时,直接调用接口方法即可
13  var para = new LEDParameter();
14  dislay.DisplayMessage(para);     

 随着应用工厂的增加,直接创建对应的实现类即可,主程序模块的代码不需要进行太多变化(LED显示参数类可能会增加属性,需要主程序模块进行传递)。

另附:

策略模式的定义:对算法的包装,是把使用算法的责任和算法本身分割开,委派给不同的对象负责。策略模式通常把一系列的算法包装到一系列的策略类里面。用一句话慨括策略模式就是——“将每个算法封装到不同的策略类中,使得它们可以互换”。

策略模式的结构图:

  

该模式涉及到三个角色:

  • 环境角色(Context):持有一个Strategy类的引用
  • 抽象策略角色(Strategy):这是一个抽象角色,通常由一个接口或抽象类来实现。此角色给出所有具体策略类所需实现的接口。
  • 具体策略角色(ConcreteStrategy):包装了相关算法或行为。
原文地址:https://www.cnblogs.com/DreamOfLife/p/8719615.html