西行漫记(15):重构到模式

今天的问题有点意思:我们有停车场(ParkingLot),还有停车小弟(Attendant)。一个停车小弟要管理多个停车场,然后帮客人把车子泊到有空位的停车场去。然后老板说了,要有不同的策略来选择停车场:有时候要选到空位最多的,有时候要选到车子最少的,大老板的车要停到最贵的,熟客的车要停到最便宜的……

熟悉面向对象的程序员第一印象会想到Strategy模式。不过我不是,因为目前不是熟悉面向对象的程序员,熟悉函数要更多一些……(寒一下)。第一印象想起的是,停车小弟知道的多个停车场,其实就是一个list;给定一个条件从list里头挑出一个东西来,其实就是accumulate。所以,第一个想到的做法就是,先实现一个Accumulator,然后用一个binary functor来走accumulate,走完结果就出来了。Strategy是第二个念头冒出来……

问题在于这只是一个感觉,可是光凭感觉编程是不够的。感觉有可能会错,也有可能YAGNI(前面我已经overkill过一次了)。而且就像Jane说的,我们是consultant,是要把知识share给别人的。Strategy模式倒也罢了,若是一步跨上来就是一个accumulate,估计大半人都得晕菜了事——这个不是危言耸听,上次在项目里写了一个map和filter,连Andy都几乎晕菜,事后说是“clever code”,clever这就不是什么好词。fancy design不是毛病,但得有理由,而且得让客户也明白这个理由,不然客户就得说我们TWer拿着他们的钱在这边玩编码游戏。

所以今天很认真地跟着老师的步伐走……老实说不是很认真,不过大致是差不多的。于是一次一次地闻到了bad smell。先是logic switch,抓住它,把变化的和不变的分开,抽取出来,得到Strategy模式;然后是遍历列表的操作,抓住它,变化的部分抽取出来就是“两个停车场之间的比较”,于是用IComparer来实现比较算法,用ArrayList提供的Sort()方法一排序,取出第一个元素就OK。果然,最初的想法虽说大致不差,还是overkill了:这个需求底下,binary functor可以用IComparer来表达,accumulate也不用自己写的。

重构还没有做完,明天先把上面说的最后部分搞定,然后把Strategy删掉,就得到了符合我第一审美印象并且更加清晰和简单的代码。今天大概是TWU以来学得第二多的一天……学得最多的是业务流程建模和story那天,都语无伦次了。

今天另一个发现是Prefactoring:这是一本好书。仍然以今天的课来说,如果没有老师的引导,那么就要靠第一审美印象来引导了。当然smell也是引导,但big picture同样是很重要的。而且就像refactoring可以训练一样,big picture同样是可以训练的。恰好现在大好时机,很久没有时间和心情来看这种“基础”的书,真是享受。

本书开创性地深入揭示了重构模式这两种软件开发关键技术之间的联系,说明了通过重构实现模式改善既有的设计,往往优于在新的设计早期使用模式。本书不仅展示了一种应用模式重构的创新方法,而且有助于读者结合实战深入理解重构模式。书中讲述了27种重构方式。 本书适于面向对象软件开发人员阅读,也可作为高校计算机专业、软件工程专业师生的参考读物。 第1章 本书的写作缘由 1 1.1 过度设计 1 1.2 模式万灵丹 2 1.3 设计不足 2 1.4 测试驱动开发和持续重构 3 1.5 重构模式 5 1.6 演进式设计 6 第2章 重构 7 2.1 何谓重构 7 2.2 重构的动机 8 2.3 众目睽睽 9 2.4 可读性好的代码 10 2.5 保持清晰 11 2.6 循序渐进 11 2.7 设计欠账 12 2.8 演变出新的架构 13 2.9 复合重构与测试驱动的重构 13 2.10 复合重构的优点 15 2.11 重构工具 15 第3章 模式 17 3.1 何谓模式 17 3.2 模式痴迷 18 3.3 实现模式的方式不止一种 20 3.4 通过重构实现、趋向和去除模式 22 3.5 模式是否会使代码更加复杂 24 3.6 模式知识 25 3.7 使用模式的预先设计 26 第4章 代码坏味 29 4.1 重复代码(Duplicated Code) 31 4.2 方法过长(Long Method) 31 4.3 条件逻辑太复杂(Conditional Complexity) 32 4.4 基本类型迷恋(Primitive Obsession) 33 4.5 不恰当的暴露(Indecent Exposure) 33 4.6 解决方案蔓延(Solution Sprawl) 34 4.7 异曲同工的类(Alternative Classes with Different Interfaces) 34 4.8 冗赘类(Lazy Class) 34 4.9 类过大(Large Class) 34 4.10 分支语句(Switch Statement) 35 4.11 组合爆炸(Combinatorial Explosion) 35 4.12 怪异解决方案(Oddball Solution) 35 第5章 模式导向的重构目录 37 5.1 重构的格式 37 5.2 本目录中引用的项目 38 5.2.1 XML Builder 39 5.2.2 HTML Parser 39 5.2.3 贷款风险计算程序 40 5.3 起点 40 5.4 学习顺序 41 第6章 创建 43 6.1 用Creation Method替换构造函数 44 6.1.1 动机 44 6.1.2 做法 46 6.1.3 示例 46 6.1.4 变体 51 6.2 将创建知识搬移到Factory 52 6.2.1 动机 53 6.2.2 做法 55 6.2.3 示例 56 6.3 用Factory封装类 61 6.3.1 动机 62 6.3.2 做法 63 6.3.3 示例 63 6.3.4 变体 66 6.4 用Factory Method引入多态创建 68 6.4.1 动机 68 6.4.2 做法 69 6.4.3 示例 71 6.5 用Builder封装Composite 74 6.5.1 做法 76 6.5.2 示例 77 6.5.3 变体 87 6.6 内联Singleton 90 6.6.1 动机 90 6.6.2 做法 92 6.6.3 示例 93 第7章 简化 97 7.1 组合方法 98 7.1.1 动机 98 7.1.2 做法 100 7.1.3 示例 100 7.2 用Strategy替换条件逻辑 103 7.2.1 动机 103 7.2.2 做法 105 7.2.3 示例 106 7.3 将装饰功能搬移到Decorator 115 7.3.1 动机 115 7.3.2 做法 119 7.3.3 示例 120 7.4 用State替换状态改变条件语句 134 7.4.1 动机 134 7.4.2 做法 135 7.4.3 示例 136 7.5 用Composite替换隐含树 144 7.5.1 动机 144 7.5.2 做法 147 7.5.3 示例 148 7.6 用Command替换条件调度程序 155 7.6.1 动机 156 7.6.2 做法 157 7.6.3 示例 158 第8章 泛化 165 8.1 形成Template Method 166 8.1.1 动机 167 8.1.2 做法 168 8.1.3 示例 168 8.2 提取Composite 173 8.2.1 动机 173 8.2.2 做法 174 8.2.3 示例 175 8.3 用Composite替换一/多之分 181 8.3.1 动机 181 8.3.2 做法 183 8.3.3 示例 184 8.4 用Observer替换硬编码的通知 191 8.4.1 动机 191 8.4.2 做法 192 8.4.3 示例 193 8.5 通过Adapter统一接口 200 8.5.1 动机 200 8.5.2 做法 201 8.5.3 示例 202 8.6 提取Adapter 209 8.6.1 动机 209 8.6.2 做法 211 8.6.3 示例 211 8.6.4 变体 217 8.7 用Interpreter替换隐式语言 218 8.7.1 动机 218 8.7.2 做法 220 8.7.3 示例 221 第9章 保护 231 9.1 用类替换类型代码 232 9.1.1 动机 232 9.1.2 做法 234 9.1.3 示例 235 9.2 用Singleton限制实例化 240 9.2.1 动机 240 9.2.2 做法 241 9.2.3 示例 241 9.3 引入Null Object 243 9.3.1 动机 244 9.3.2 做法 245 9.3.3 示例 246 第10章 聚集操作 251 10.1 将聚集操作搬移到Collecting Parameter 252 10.1.1 动机 252 10.1.2 做法 253 10.1.3 示例 254 10.2 将聚集操作搬移到Visitor 258 10.2.1 动机 258 10.2.2 做法 262 10.2.3 示例 266 第11章 实用重构 273 11.1 链构造函数 274 11.1.1 动机 274 11.1.2 做法 275 11.1.3 示例 275 11.2 统一接口 277 11.2.1 动机 277 11.2.2 做法 278 11.2.3 示例 278 11.3 提取参数 279 11.3.1 动机 279 11.3.2 做法 279 11.3.3 示例 280 跋 281 参考文献 283 索引 287
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值