目 录
代序..............四大发明之活字印刷——面向对象思想的胜利
第一章............面试受挫——代码无错就是好?
第二章............代码规范、重构
第三章............复制 VS 复用
第四章............业务的封装
第五章............体会简单工厂模式的美妙
第六章............工厂不好用了?
第七章............用“策略模式”是一种好策略
第八章............反射——程序员的快乐!
第九章............会修电脑不会修收音机?——聊设计模式原则
第十章............三层架构,分层开发
第十一章..........无熟人难办事?——聊设计模式迪米特法则
第十二章.......... 有 了 门 面 , 程序员的程序会更加体面
第十三章..........设计模式不能戏说!设计模式怎就不能戏说?
四大发明之活字印刷——面向对象思想的胜利(代序)
话说三国时期,曹操带领百万大军攻打东吴,大军在长江赤壁驻扎,军船连成一片,眼看就要灭掉东吴,统一天
下,曹操大悦,于是大宴众文武,在酒席间,曹操诗性大发,不觉吟道:“喝酒唱歌,人生真爽。…………”。众文武
齐呼:“丞相好诗!”于是一臣子速命印刷工匠刻版印刷,以便流传天下。
样张出来给曹操一看,曹操感觉不妥,说道:“喝与唱,此话过俗,应改为‘对酒当歌’较好!”,于是此臣就命工
匠重新来过。工匠眼看连夜刻版之工,彻底白费,心中叫苦不喋。只得照办。
样张再次出来请曹操过目,曹操细细一品,觉得还是不好,说:“人生真爽太过直接,应改问语才够意境,因此应
改为‘对酒当歌,人生几何?…………’!” 当 臣 转告工匠之时,工匠晕倒…………!
可惜三国时期活字印刷还未发明,所以类似事情应该时有发生,如果是有了活字印刷。则只需更改四个字就可,
其余工作都未白做。实在妙哉。
第一,要改,只需更改要改之字,此为可维护;第二,这些字并非用完这次就无用,完全可以在后来的印刷中重
复使用,此乃可复用;第三,此诗若要加字,只需另刻字加入即可,这是可扩展;第四,字的排列其实有可能是竖有
可能是横排,此时只需将活字移动就可做到满足排列需求,此是灵活性好。
而在活字印刷术之前,上面的四种特性都无法满足,要修改,必须重刻,要加字,必须重刻,要重新排列,必须
重刻,印完这本书后,此版已无任何可再利用价值。
小时候,我一直奇怪,为何火药、指南针、造纸术都是从无到有,从未知到发现的伟大发明,而活字印刷仅仅
是从刻版印刷到活字印刷的一次技术上的进步,为何不是评印刷术为四大发明之一呢?
做了软件开发几年后,经历了太多的客户(曹操)改变需求,更改最初想法的事件,才逐渐明白当中的道理。
其实客观的说,客户的要求也并不过份(改几个字而已),但面对已完成的程序代码,却是需要几乎重头来过的尴尬,
这实在是痛苦不堪。说白了,原因就是因为我们原先所写的程序,不容易维护,灵活性差,不容易扩展,更谈不上复
用,因此面对需求变化,加班加点,对程序动大手术的那种无耐也就非常正常的事了。
之后当我学习了面向对象分析设计编程思想,开始考虑通过封装、继承、多态把程序的耦合度降低(传统印刷
术的问题就在于所有的字都刻在同一版面上造成耦合度太高所制),开始用设计模式使得程序更加的灵活,容易修改,
并且易于复用。体会到面向对象带来的好处,那种感觉应该就如同是一中国酒鬼第一次喝到了茅台,西洋酒鬼第一次
喝到了 XO 一样,怎个爽字可形容呀。
再次回顾中国古代的四大发明,另三种应该都是科技的进步,伟大的创造或发现。而唯有活字印刷,实在是思
想的成功,面向对象的胜利。不知您是否也有所感呢?
第一章 面试受挫——代码无错就是好?
小菜今年计算机专业大四了,学了不少软件开发方面的东西,也学着编了些小程序,踌躇满志,一心要找一个好
单位。当投递了无数份简历后,终于收到了一个单位的面试通知,小菜欣喜若狂。
到了人家单位,前台小姐给了他一份题目,上面写着,“ 请用 C++、Java、C#或 VB.NET 任意一种面向对象语言实
现一个计算器控制台程序,要求输入两个数和运算符号,得到结果。”
小菜一看,这个还不简单,三下五除二,
10
分钟不到,小菜写完了,感觉也没错误。交卷后,单位说一周内等通
知吧。于是小菜只得耐心等待。可是半个月过去了,什么消息也没有,小菜很纳闷,我的代码实现了呀,为什么不给
我机会呢。
小菜找到工作三年的师哥大鸟,请教原因,大鸟问了题目和了解了小菜代码的细节以后,哈哈大笑,说道:“ 小 菜
呀 小 菜 , 你 上 当了,人家单位出题的意思,你完全都没明白,当然不会再联系你了”。
小菜说:“ 我 的 代码有错吗?单位题目不就是要我实现一个计算器的代码吗,我这样写有什么问题。”
class Program
{
static void Main(string[] args)
{
Console.Write("请输入数字 A:");
string A = Console.ReadLine();
Console.Write("请选择运算符号(+、-、*、/):");
string B = Console.ReadLine();
Console.Write("请输入数字 B:");
string C = Console.ReadLine();
string D = "";
if (B == "+")
D = Convert.ToString(Convert.ToDouble(A) + Convert.ToDouble(C));
if (B == "-")
D = Convert.ToString(Convert.ToDouble(A) - Convert.ToDouble(C));
if (B == "*")
D = Convert.ToString(Convert.ToDouble(A) * Convert.ToDouble(C));
if (O == "/")
D = Convert.ToString(Convert.ToDouble(A) / Convert.ToDouble(C));
Console.WriteLine("结果是:" + D);
}
}
小菜的代码有什么问题呢?