关于手表的记忆仿佛很遥远,自从有了手机,我就没想过要买一只手表。最近不知怎么回事,突然觉得买一只手表很有必要,现在的智能手机很容易没电,要是外出之后找不到充电器,也就不知道了时间,这岂不是很糟糕?今天和大家说说手表的故事。
印象很深的一句话是这样说的:“拥有手表不是为了记住时间,而是可以暂时忘记时间!”如果你仔细想想,就会发现确实是这样的。有了手表我们就可以更专注于手头的工作,把计时或者提醒吃饭的活儿交给手表,而不需要每时每刻都默数时间,而是在空闲或关键的时刻,抬起胳膊看看手表,于是,时间又回来了!
好吧,为了短暂的忘记而不是时刻记住!这个东西如此奇妙,它自然不会把自己困在“手表”里。我想你猜到到了,就比如做软件,我们都知道有种东西叫做“设计模式”,这些条条目目被很多人奉为神,认为它们是正确的不能再正确的真理,今天我要说它们只是一块“手表”。
可不可以忘记该谁上场?考虑以下代码:
class="code_img_closed" src="/Upload/Images/2014032610/0015B68B3C38AA5B.gif" alt="" />logs_code_hide('1d34ebb2-ff7e-47d9-b8d6-4ac4993d182c',event)" src="/Upload/Images/2014032610/2B1B950FA3DF188F.gif" alt="" />1 class Program 2 { 3 static void Main(string[] args) 4 { 5 //客户端喊口号:来一个! 6 var p = People.sendOne(); 7 } 8 } 9 10 11 abstract class People 12 { 13 public static People sendOne() 14 { 15 //这里决定派谁上场 16 return new Huluwa(); 17 } 18 public abstract string getName(); 19 } 20 21 22 class Huluwa : People 23 { 24 public override string getName() 25 { 26 return "葫芦娃"; 27 } 28 } 29 30 class Chaoren : People 31 { 32 public override string getName() 33 { 34 return "超人"; 35 } 36 }View Code
在设计模式的语言里,把类似这种的设计叫做:“工厂方法”,抽象类People就是一个工厂,它有若干个子类,这些子类谁会被派出去代表自己,完全由sendOne这个方法决定。如果派谁上场视具体情况而定,还可以给sendOne加上一个参数。当然了,这是最简单的形式,还有很多的变种,比如:咖啡用咖啡匙搅拌,鸡汤用汤匙搅拌,取完食物后该拿哪个“匙”,如何只需执行getShi而不会拿错呢?好吧,我想这种自动配对的关系难不倒你(参考“抽象工厂”)。
可不可以忘记上场顺序?考虑以下代码:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Actor a = new Chaoren(); 6 a.doAction(); 7 } 8 } 9 10 abstract class Actor 11 { 12 public void doAction() 13 { 14 //这里固定了这个顺序 15 //除了这里,没其他地方关心这个顺序 16 sayHello(); 17 play(); 18 sayGoodBye(); 19 } 20 21 protected abstract void sayHello(); 22 protected abstract void play(); 23 protected abstract void sayGoodBye(); 24 } 25 26 class Huluwa : Actor 27 { 28 protected override void sayHello() 29 { 30 Console.WriteLine("大家好,我是葫芦娃"); 31 } 32 33 protected override void play() 34 { 35 Console.WriteLine("今天我为大家表演:照葫芦画瓢"); 36 } 37 38 protected override void sayGoodBye() 39 { 40 Console.WriteLine("谢谢大家"); 41 } 42 } 43 44 class Chaoren : Actor 45 { 46 protected override void sayHello() 47 { 48 Console.WriteLine("大家好,我是超人"); 49 } 50 51 protected override void play() 52 { 53 Console.WriteLine("今天我为大家表演:超人男人用超能"); 54 } 55 56 protected override void sayGoodBye() 57 { 58 Console.WriteLine("衣服洗好了,谢谢大家"); 59 } 60 }View Code
在设计模式的语言里,把类似这种的设计叫做:“模版方法”,抽象类Actor固定每个演员出场后进行项目的顺序,也就是打招呼、表演、谢幕,关于这点,具体的演员无需关心,客户端调用时,也不需要知道。在此基础上,他们总结出了“建造者模式”,比上述方法要更加完整一些。
还有很多,我全都敲出代码来也对说明问题无益!比如“单例模式”是为了忘记某个对象是否创建过,而又不会重复创建它们!“迭代器模式”(被foreach给淘汰了?)是为了忘记怎么不重复不遗漏的访问每一个项目!“观察者模式”是为了让客体忘记什么时候该更新,只需等待主体发出通知即可!“策略模式”是为了忘记具体该整哪个算法!“职责链模式”是为了忘记下一步该怎么办,是我的就处理,不是我的就扔了即可!“状态模式”是把问题分解为位置和反应,所谓在其位谋其政,让对象发生变化时自动站到相应的位置上去,于是就没有了复杂逻辑,我们只需知道具体的位置对具体的情况如何做出反应即可!“中介者模式”最好理解了,找过中介公司租过房子的就知道可以忘记很多细节!等等等等。
说到这里,我想多说一句:设计模式不是什么好东西!他们试图用固定的格式来扼杀想象力,就像中国的八股文,或许我们可以说“23股代码”?要知道,八股文的设计初衷是让人无需太高深的文学素养,也能写出工整无比的文章来,看看,像不像设计模式!
所以,强烈建议大家从另一个视角看待设计模式,也许把它们称为“写给大家看的23种优秀软件设计实践”,嘿嘿,是不是瞬间像国产书籍的名称了哈!或者像我一样理解:无论什么王八羔子的模式,都是为了忘记点什么!
来吧,现在时刻9点40分!