设计模式之——策略模式

定义:定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

纯概念不太好理解,让我们来看一个需求:

现在需要制造一批不同种类的交通工具(包括汽车、摩托车、自行车……),假设所有的交通工具只有两个部分构成:引擎(热力和人力)和轮子(大小等),可以如下实现方法,抽象出交通工具Transport类:

View Code
 1     public abstract class Transport
 2     {
 3         /// <summary>
 4         /// 引擎
 5         /// </summary>
 6         /// <returns></returns>
 7         public abstract string Engine();
 8 
 9         /// <summary>
10         /// 轮子
11         /// </summary>
12         /// <returns></returns>
13         public abstract string Wheel();
14     }

制造汽车(假设所有的汽车都是一样的,贴上不同的标签就是不同的牌子)、摩托车、自行车类如下所示:(简化了Engine和Wheel的制造方法)

View Code
 1  1     public class Car:Transport
 2  2     {
 3  3         /// <summary>
 4  4         /// 热动力引擎
 5  5         /// </summary>
 6  6         /// <returns></returns>
 7  7         public override string Engine()
 8  8         {
 9  9             return "Engine For Heat";
10 10         }
11 11 
12 12         /// <summary>
13 13         /// 特制轮子
14 14         /// </summary>
15 15         /// <returns></returns>
16 16         public override string Wheel()
17 17         {
18 18             return "Special wheel";
19 19         }
20 20     }
View Code
 1     public class Motorcycle:Transport
 2     {
 3         /// <summary>
 4         /// 热动力引擎
 5         /// </summary>
 6         /// <returns></returns>
 7         public override string Engine()
 8         {
 9             return "Engine For Heat";
10         }
11 
12         /// <summary>
13         /// 一般轮子
14         /// </summary>
15         /// <returns></returns>
16         public override string Wheel()
17         {
18             return "General wheel";
19         }
20     }
View Code
 1     public class Bicycle:Transport
 2     {
 3         /// <summary>
 4         /// 人力引擎
 5         /// </summary>
 6         /// <returns></returns>
 7         public override string Engine()
 8         {
 9             return "Engine For People";
10         }
11 
12         /// <summary>
13         /// 一般轮子
14         /// </summary>
15         /// <returns></returns>
16         public override string Wheel()
17         {
18             return "General wheel";
19         }
20     }

摩托车(MotorCycle)介于Car和Bicycle之间,引擎和Car一样,Wheel和Bicycle一样,这样实现虽然解决了问题。但是有两个弊端:

一、出现比较多的重复代码,无法达到重用。而且随着需求变化,出现三轮车(Engine、Wheel和Bicycle一样)、卡车(Engine、Wheel和Car一样)……重复的部分会越来越多。

二、某一天,相关部门研究发现依靠热力的Engine排放了严重污染大气的尾气,需要用新研制的环保型Engine替换,就得要遍地寻找使用了原先落后技术制造的Engine,逐个更改……这无疑是个噩梦……

是时候让策略模式出场了,首先定义Wheel和Engine的抽象接口,然后将Wheel和Engine分别实现不同的制造方法,再改变下Transport抽象类:

IWheel和IEngine的定义:

View Code
 1     public interface IWheel
 2     {
 3         string CreatWheel();
 4     }
 5 
 6 
 7     public interface IEngine
 8     {
 9         string CreatEngine();
10     }

Engine和Wheel分别分开实现各自的系列算法:

View Code
 1     public class HeatEngine:IEngine
 2     {
 3         public string CreatEngine()
 4         {
 5             return "Engine From Heat";
 6         }
 7     }
 8 
 9 
10 
11     public class HuManEngine:IEngine
12     {
13         public string CreatEngine()
14         {
15             return "Engine From People";
16         }
17     }
View Code
 1     public class SpecialWheel:IWheel
 2     {
 3         public string CreatWheel()
 4         {
 5             return "Special Wheel";
 6         }
 7     }
 8 
 9 
10     public class GeneralWheel:IWheel
11     {
12         public string CreatWheel()
13         {
14             return "General Wheel";
15         }
16     }

修改下Transport抽象类:

View Code
 1     public abstract class Transport
 2     {
 3         public IEngine _engine;
 4         public IWheel _wheel;
 5 
 6         public void SetEngine(IEngine engine)
 7         {
 8             this._engine = engine;
 9         }
10 
11         public void SetWheel(IWheel wheel)
12         {
13             this._wheel = wheel;
14         }
15 
16         /// <summary>
17         /// 制造引擎
18         /// </summary>
19         /// <returns></returns>
20         public string Engine()
21         {
22             return this._engine.CreatEngine();
23         }
24 
25         /// <summary>
26         /// 制造轮子
27         /// </summary>
28         /// <returns></returns>
29         public string Wheel()
30         {
31             return this._wheel.CreatWheel();
32         }
33 
34         /// <summary>
35         /// 车外形
36         /// </summary>
37         /// <returns></returns>
38         public abstract string Display();
39     }

Car、MotorCycle、Bicycle继承Transport:(因为都类似,只例举其一)

View Code
1     public class Bicycle : Transport
2     {
3         public override string Display()
4         {
5             return "With Blue Color";
6         }
7     }

上述类和接口关系如下:

如图所示,可以动态扩展不同的Wheel和Engine。例如新增加了电动车,使用ElectricEngine和GeneralWheel,只需要新增一个ElectricEngine继承自IEngine如下:

View Code
1     public class ElectricEngine:IEngine
2     {
3         public string CreatEngine()
4         {
5             return "Engine From Electric";
6         }
7     }

然后客户端引用IEngine的dll,不需要额外改动任何地方即可动态更改:

View Code
 1         static void Main(string[] args)
 2         {
 3             Transport ts = new Car();
 4             ts.SetEngine(new HeatEngine());
 5             ts.SetWheel(new SpecialWheel());
 6             Console.WriteLine("====================================");
 7             Console.WriteLine(ts.Engine() + " " + ts.Wheel() + " " + ts.Display());
 8             Console.WriteLine("====================================");
 9             Console.WriteLine("Electric Engine :");
10             ts.SetEngine(new ElecricEngine());
11             ts.SetWheel(new GeneralWheel());
12             Console.WriteLine(ts.Engine() + " " + ts.Wheel() + " " + ts.Display());            
13 
14             Console.ReadKey();
15         }

 程序运行结果如下图所示:

=====================================================

欢迎大家指正~

原文地址:https://www.cnblogs.com/yangyp/p/3018548.html