Head First Design patterns笔记-Strategy Patterns (从不同的人使用不同的交通工具上班看策略模式)

定义Strategy pattern define a family of algorithms, encapsulate each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.(保留原汁原味吧!木有翻译。)

 小故事生活在北京,每天早晨当我骑着自行车走在上班的路上的时候都能看到和我一样行色匆匆的路人,自行车族还是占相当大的比例的,偶尔会有摩托车呼啸着从身边飞过,相当的嚣张。不过摩托车碰到满街的奥迪,宝马之类的就相形见绌了。开车也有抓瞎的时候,比如堵车了,我们自行车族完全可以绕着走或者从车缝里穿过去,基本不会有太多的影响,你们小轿车就得一直等到交通疏散开才可以,有本事你给我也从车缝里挤过去看看。^_^。交通工具一般能和人的职位头衔相对应起来,像我这样一穷二白的ITer大概也只能骑自行车了,稍微有点钱的可以弄个摩托车跑跑,当然一般老板都有自己的私家轿车。本文的例子就是讲老板,项目经理(我假定他们比较有钱,完全可以支付起使用摩托车的费用)和我们普通ITer选择自己的交通工具去上班。当然老板完全可以也骑自行车,这是合法的也是可行的。

VS自动生成的类图:




实例代码

  1using System;
  2using System.Collections.Generic;
  3using System.Text;
  4using System.Diagnostics;
  5
  6namespace StrategyDemo
  7{
  8    /// <summary>
  9    /// Base class for Boss, TeamMember and PM (let's call them workers).
 10    /// </summary>

 11    public abstract class Worker
 12    {
 13        protected IVehicle _vehicle;
 14
 15        //Base class may provide a lot of fields that subclass can inherit.
 16        protected string m_Name;
 17
 18        public string Name
 19        {
 20            get return m_Name; }
 21            set { m_Name = value; }
 22        }

 23
 24        /// <summary>
 25        /// The behavior may quite differnt based on different vehicles,
 26        /// so encapsulate into  classes that implement IVehicle. 
 27        /// </summary>

 28        public void GoToWork()
 29        {
 30            Debug.Assert(null != _vehicle, "Please choose your vehicle before you go to work!");
 31            _vehicle.Go();
 32        }

 33
 34        /// <summary>
 35        /// Choose your own vehicle.
 36        /// </summary>
 37        /// <param name="vehicle"></param>

 38        public void SetVehicle(IVehicle vehicle)
 39        {
 40            _vehicle = vehicle;
 41        }

 42
 43    }

 44
 45    subclasses of Worker
 77
 78
 79    /// <summary>
 80    /// Every vehicle has to implement this interface.
 81    /// Notice that every differnt vehicle has its own behavior.
 82    /// </summary>

 83    public interface IVehicle
 84    {
 85        void Go();
 86    }

 87
 88    Vehicles that implement IVehicle
112
113
114    class Program
115    {
116        static void Main(string[] args)
117        {
118            Boss boss = new Boss("someone");
119            boss.SetVehicle(new Car());
120            boss.GoToWork();
121            Console.WriteLine("**********************************************************");
122            TeamMember teamMember = new TeamMember();
123            teamMember.SetVehicle(new MiniBike());
124            teamMember.GoToWork();
125            Console.WriteLine("**********************************************************");
126            PM pm = new PM();
127            pm.SetVehicle(new MotorMike());
128            pm.GoToWork();
129
130            Console.ReadKey();
131        }

132    }

133}

134

运行结果图:


本例引出的面向对象原则:
封装变化的部分(Encapsulate what varies).
本例中不同的人使用不同的交通工具,操作可能不尽相同,开车和骑摩托车肯定不一样,骑自行车和骑摩托车也不会一样,至少骑摩托车不用使劲去蹬,交通工具可能只适用用特定的人群,像我就不会开车。这部分是变化的,所以可以从类中抽取出来单独放到一个类中,注意这个类只封装了一一些操作,并不一定有成员变量。

优先选择组合而不是继承(Favor composition over inheritance)。
对于本例来说显然在work类中添加GoToWork的实现代码让子类使用是不合适的,因为不同的人到公司上班的方式是不一样的。在work中实现一个抽象类供子类override是不是可以呢?只能解决一部分问题,如果打算运行是改变行为呢?对于本例来说加入一天老板突然想骑自行车上班怎么办?
Boss boss = new Boss("someone");
boss.SetVehicle(new MiniBike());
boss.GoToWork();
这样就可以了,这也是定义中提到的“encapsulates each one and makes them interchangeable”的意义所在。


针对接口编程而不是实现(Program to interface not implementation)。
这个就很简单了,正因为在worker类中有 protected IVehicle _vehicle,才可以实现运行时改变对象行为,对于本例来说就是可以老板愿意他可以选择骑自行车(当然他得有自行车,^_^。)

代码下载:
StrategyDemo.zip

posted on 2007-04-25 22:57 zhanqiangz(闲云野鹤) 阅读(2323) 评论(10)  编辑 收藏 所属分类: CSharp读书笔记Design Patterns

评论

#1楼  2007-04-26 09:01 唉。。。。 [未注册用户]

本来不想说什么,看了代码后,禁不住想问?

如下伪码:

Page添加 :TextBox
Page添加: Image

Page显示。。。。。

用户控件添加: TextBox
用户控件添加 Image

用户控件显示....

用户控件可以选择添加别的东西。。。。。   回复  引用    

#2楼  2007-04-26 09:02 你说的东西, [未注册用户]

不是天天在用么?

  回复  引用    

#3楼  2007-04-26 19:12 随风流月      

对,是可以再添加控件的。   回复  引用  查看    

#4楼  2007-04-26 22:04 GerryJiang      

Head first design patterns 是一本很有趣的书,你的读书笔记没写出任何书中的味道   回复  引用  查看    

#5楼  2007-04-26 22:38 zhanqiangz(闲云野鹤) [未注册用户]

@GerryJiang
你所谓的有趣大概是你博客里提到的http://www.cnblogs.com/justinw/archive/2006/11/28/574585.html
这位兄弟翻译的设计模式系列文章吧,现在只有目录和第一章。

但是他的是翻译,并不是笔记。我写这些东西主要是为了加深我对模式的理解,本来也没打算模仿原作者那样写的有趣。
  回复  引用    

#6楼  2007-04-26 22:40 zhanqiangz(闲云野鹤) [未注册用户]

@唉。。。。
我不知道这位兄弟想问什么?
你说的自然用到了策略模式,但是和我写这片文章有什么必然联系吗?为什么“本来不想说什么”看了我的文章“禁不住想问”呢?^_^。   回复  引用    

#7楼  2007-05-11 06:28 Justin      

@zhanqiangz(闲云野鹤)
hi!偶然看了到了你的一些评论,感觉你对我哪个系列文章有些误解!每篇文章的故事内容取材于<Head First Design Patterns>,根据故事情节不同,一般占整篇文章的1/3~1/2,故事只是为了引入每个模式的感念,况且也不是直白的翻译那么简单的引用,其后还有“应用场景和优缺点”,“.NET框架里的应用”等都是基于具体的模式引申出来的,可以说每篇都要花很大功夫的。
而且目前完成的也不是目录和第一章,开篇是“开篇-模式和原则”,那不是目录,关于翻译可以看这里的说明,http://www.cnblogs.com/justinw/archive/2006/05/09/395666.aspx

不管怎么样,希望你的评论能更客观一些!
  回复  引用  查看    

#8楼 [楼主] 2007-05-11 09:22 zhanqiangz(闲云野鹤)      

@Justin
我当时看的不够详细,大致看到了两章,现在回去看了看,是有很多,抱歉.^_^.

我也没有说你的写作不花费功夫,只是我感觉引用了上面的例子看起来更似乎是用汉语的东西把原作表述出来,虽然不是一字一句的译,当然你在写作的过程中肯定是动了脑筋的,加入了自己的东西.你这样写的难度要比我这样的大得多,^_^.
我只是跟着GerryJiang 兄弟的评论进入了你的自留地,如言语不当,请原谅.其实我在我的第二篇里也写到了一些关于写作动机之类的东西.每个人写作的目的可能并不完全相同,而且也都有自己的风格.

我自己还是认为你翻译的成分比较多,当然不是完全的翻译,说是笔记也不是不可以.做技术的不用为这点小时较真了,^_^.我自己博客上也有几篇翻译的文章,也加入了自己的东西,但是我认为这是翻译.
  回复  引用  查看    

#9楼  2007-05-14 06:39 Justin      

@zhanqiangz(闲云野鹤)
it's ok!不用在意了   回复  引用  查看    

#10楼  2007-12-04 21:46 nihao [未注册用户]

支持一下 感觉不错的   回复  引用    


标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-05-01 11:14 编辑过
 
另存  打印
 


<2007年4月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

导航

统计

公告

如转载本博客的相关资料敬请注明出处.谢谢合作!

与我联系

常用链接

留言簿(6)

我参与的团队

我的标签

随笔分类(51)

随笔档案(49)

文章分类(7)

文章档案(5)

收藏夹(3)

.NET

BizTalk