成长的烦恼(续)
2006-05-12 17:05
246 查看
又一年……
镜头切换……
因为小王平时的出色表现,现在小王也是小小的项目经理了。而身边又多了一本书《重构:改善改善既有代码的设计》。排序的算法也相对稳定下来,排序也成为一个独立的模块,很多的地方中都使用到了。然而需求又变了,说要使用冒泡排序算法。“我的天啊,为何不早说呢?现在这么多地方都用到了。”小王查找了一下,总共有15处使用了相同的代码。代码的腐臭味。“以后还要增加,怎么办?以后还要换排序算法怎么办?”毕竟现在的小王不是以前的水平了,遇到问题都会三思而后行。一个声音在呼唤:“用工厂方法(Factory Method)吧。”长痛不如短痛,对代码进行重构。UML图如下:
在客户端程序一开始就初始化工厂:
CSortFactory* pSortFactory = new CBubbleSortFactory;
然后把所有调用的地方改成如下的代码:
CSort *pSort = pSortFactory->Create();
CCompareType *pType = new CNameCompare;
pSort->SetType(pType);
pSort->Sort(pList);
化了半个小时,把15处地方都修改过来。这样做的好处你知道了吗?以后如果发展到50处地方使用,难道你还一处一处去修改吗?Keep in your mind,需求是不断变化的。现在如果要改算法,只要修改一处就行,就是把CBubbleSortFactory替换掉。
这样真的彻底地解决问题了吗?掌握主动权就是掌握了命运。经过三年的磨练,小王处处长了个心眼,防患与未然。
这里有一个不稳定的因素就是Compare Type,难道它不会变化了?其实上面的代码应该是这样的:
CSort *pSort = pSortFactory->Create();
if(nType == SortName)
CCompareType *pType = new CNameCompare;
else if(nType == SortDate)
CCompareType *pType = new CDateCompare;
else
CCompareType *pType = new CSizeCompare;
pSort->SetType(pType);
pSort->Sort(pList);
小王不能容忍这种隐患,使用一个简单工厂模式(Simple Factory)吧。“发现变化,封装它。”UML图如下:
把if-else,switch移到CSimpleCompareFactory的Create函数中去吧。在客户端程序初始化代码加上一句:
CSimpleCompareFactory *pSimpleFactory = new CSimpleCompareFactory;
调用地方的代码改为:
CSort *pSort = pSortFactory->Create();
CCompareType *pType = pSimpleFactory ->Create(nSortName);
pSort->SetType(pType);
pSort->Sort(pList);
“if-else,switch语句不是还在吗?”一个声音在问。
“怎么这么多问题?难道if-else,switch语句不能用吗?”有时不必强求,只要做到改动最小就行了,程序的代码在大部分情况下是能做修改的。
上面的设计已经能解决大部分的扩展的。
然而日子还在继续,客户还在提需求,小王还在继续自己的梦想。
不变的只有变化。
镜头切换……
因为小王平时的出色表现,现在小王也是小小的项目经理了。而身边又多了一本书《重构:改善改善既有代码的设计》。排序的算法也相对稳定下来,排序也成为一个独立的模块,很多的地方中都使用到了。然而需求又变了,说要使用冒泡排序算法。“我的天啊,为何不早说呢?现在这么多地方都用到了。”小王查找了一下,总共有15处使用了相同的代码。代码的腐臭味。“以后还要增加,怎么办?以后还要换排序算法怎么办?”毕竟现在的小王不是以前的水平了,遇到问题都会三思而后行。一个声音在呼唤:“用工厂方法(Factory Method)吧。”长痛不如短痛,对代码进行重构。UML图如下:
在客户端程序一开始就初始化工厂:
CSortFactory* pSortFactory = new CBubbleSortFactory;
然后把所有调用的地方改成如下的代码:
CSort *pSort = pSortFactory->Create();
CCompareType *pType = new CNameCompare;
pSort->SetType(pType);
pSort->Sort(pList);
化了半个小时,把15处地方都修改过来。这样做的好处你知道了吗?以后如果发展到50处地方使用,难道你还一处一处去修改吗?Keep in your mind,需求是不断变化的。现在如果要改算法,只要修改一处就行,就是把CBubbleSortFactory替换掉。
这样真的彻底地解决问题了吗?掌握主动权就是掌握了命运。经过三年的磨练,小王处处长了个心眼,防患与未然。
这里有一个不稳定的因素就是Compare Type,难道它不会变化了?其实上面的代码应该是这样的:
CSort *pSort = pSortFactory->Create();
if(nType == SortName)
CCompareType *pType = new CNameCompare;
else if(nType == SortDate)
CCompareType *pType = new CDateCompare;
else
CCompareType *pType = new CSizeCompare;
pSort->SetType(pType);
pSort->Sort(pList);
小王不能容忍这种隐患,使用一个简单工厂模式(Simple Factory)吧。“发现变化,封装它。”UML图如下:
把if-else,switch移到CSimpleCompareFactory的Create函数中去吧。在客户端程序初始化代码加上一句:
CSimpleCompareFactory *pSimpleFactory = new CSimpleCompareFactory;
调用地方的代码改为:
CSort *pSort = pSortFactory->Create();
CCompareType *pType = pSimpleFactory ->Create(nSortName);
pSort->SetType(pType);
pSort->Sort(pList);
“if-else,switch语句不是还在吗?”一个声音在问。
“怎么这么多问题?难道if-else,switch语句不能用吗?”有时不必强求,只要做到改动最小就行了,程序的代码在大部分情况下是能做修改的。
上面的设计已经能解决大部分的扩展的。
然而日子还在继续,客户还在提需求,小王还在继续自己的梦想。
不变的只有变化。
相关文章推荐
- 【转】一位技术人员成长的烦恼及我的分析
- 软件企业成长的烦恼――多个并行软件项目研发管理策略(2)--原因分析
- 敏捷无敌之成长的烦恼(16)
- Growing Pains(成长的烦恼主题曲)-----As Long As We Got Each Other
- 一位技术人员成长的烦恼及我的分析
- 坚果云的成长烦恼:互联网巨头乌云笼罩(1年多时间, 坚果云已经拥有接近百万注册用户)
- [个人管理]一位技术人员成长的烦恼【转载】
- 成长的烦恼
- 百度上市周年记:“东方神话”的“成长烦恼”
- 手机杂志:成长的烦恼
- 软件企业成长的烦恼――多个并行软件项目研发管理策略(1)--成长烦恼
- 敏捷无敌之成长的烦恼(14)
- 成长烦恼之多 (2011-06-02 20:54:36)
- 情人节被逼婚,成长的烦恼
- 程序江湖:第八章 释放成长的烦恼
- 一位技术人员成长的烦恼及我的分析
- 一个新手成长的烦恼 文/谷雨霖
- CDSN 开始记录成长的烦恼
- 想知道关键词怎么确定--SEO成长不烦恼, 让你走出困境
- 成长的烦恼