通过提高代码复用提高可维护性_第1页
通过提高代码复用提高可维护性_第2页
通过提高代码复用提高可维护性_第3页
通过提高代码复用提高可维护性_第4页
通过提高代码复用提高可维护性_第5页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1 通过提高代码复用提高可维护性 通过提高代码复用提高可维护性 我曾经遇到过这样一件事 我要维护的一个系统因为应用范围的扩大 它 对机关级次的计算方式需要改变一种策略 如果这个项目统一采用一段公用方 法来计算机关级次 这样一个修改实在太简单了 就是修改这个公用方法即可 但是 事实却不一样 对机关级次计算的代码遍布整个项目 甚至有些还写入 到了那些复杂的 SQL 语句中 在这样一种情况下 这样一个需求的修改无异于 需要遍历这个项目代码 这样一个实例显示了一个项目代码复用的重要 然而 不幸的是 代码无法很好复用的情况遍布我们所有的项目 代码复用的道理十 分简单 但要具体运作起来非常复杂 它除了需要很好的代码规划 还需要持 续地代码重构 对整个系统的整体分析与合理规划可以根本地保证代码复用 系统分析师 通过用例模型 领域模型 分析模型的一步一步分析 最后通过正向工程 生 成系统需要设计的各种类及其各自的属性和方法 采用这种方法 功能被合理 地划分到这个类中 可以很好地保证代码复用 采用以上方法虽然好 但技术难度较高 需要有高深的系统分析师 并不 是所有项目都能普遍采用的 特别是时间比较紧张的项目 通过开发人员在设 计过程中的重构 也许更加实用 当某个开发人员在开发一段代码时 发现该 功能与前面已经开发功能相同 或者部分相同 这时 这个开发人员可以对前 面已经开发的功能进行重构 将可以通用的代码提取出来 进行相应地改造 使其具有一定的通用性 便于各个地方可以使用 一些比较成功的项目组会指定一个专门管理通用代码的人 负责收集和整 理项目组中各个成员编写的 可以通用的代码 这个负责人同时也应当具有一 定的代码编写功力 因为将专用代码提升为通用代码 或者以前使用该通用代 码的某个功能 由于业务变更 而对这个通用代码的变更要求 都对这个负责 人提出了很高的能力要求 虽然后一种方式非常实用 但是它有些亡羊补牢的味道 不能从整体上对 项目代码进行有效规划 正因为两种方法各有利弊 因此在项目中应当配合使 用 2 利用设计模式提高可变更性 利用设计模式提高可变更性 对于初学者 软件设计理论常常感觉晦涩难懂 一个快速提高软件质量的 捷径就是利用设计模式 这里说的设计模式 不仅仅指经典的 32 个模式 是一 切前人总结的 我们可以利用的 更加广泛的设计模式 a if else 这个我也不知道叫什么名字 最早是哪位大师总结的 它出现在 Larman 的 UML 与模式应用 也出现在出现在 Mardin 的 敏捷软件开发 它是 这样描述的 当你发现你必须要设计这样的代码 if elseif elseif else 时 你应当想到你的代码应当重构一下了 我们先看看这样的代码有怎样的特点 Java 代码 1 if var equals A 2 doA 3 else if var equals B 4 doB 5 else if var equals C 6 doC 7 else 8 doD 9 这样的代码很常见 也非常平常 我们大家都写过 但正是这样平常才隐藏着 我们永远没有注意的问题 问题就在于 如果某一天这个选项不再仅仅是 A B C 而是增加了新的选项 会怎样呢 你也许会说 那没有关系 我把 代码改改就行 然而事实上并非如此 在大型软件研发与维护中有一个原则 每次的变更尽量不要去修改原有的代码 如果我们重构一下 能保证不修改原 有代码 仅仅增加新的代码就能应付选项的增加 这就增加了这段代码的可维 护性和可变更性 提高了代码质量 那么 我们应当如何去做呢 经过深入分析你会发现 这里存在一个对应关系 即 A 对应 doA B 对 应 doB 如果将 doA doB doC 与原有代码解耦 问题就解 决了 如何解耦呢 设计一个接口 X 以及它的实现 A B C 每个类都包 含一个方法 doX 并且将 doA 的代码放到 A doX 中 将 doB 的代码放到 B doX 中 经过以上的重构 代码还是这些代码 效果却完全不一样了 我们只需要这样写 Java 代码 1 X x factory getBean var 2 x doX 这样就可以实现以上的功能了 我们看到这里有一个工厂 放着所有的 A B C 并且与它们的 key 对应起来 并且写在配置文件中 如果出现 新的选项时 通过修改配置文件就可以无限制的增加下去 这个模式虽然有效提高了代码质量 但是不能滥用 并非只要出现 if else 就需要使用 由于它使用了工厂 一定程度上增加了代码复杂度 因 此仅仅在选项较多 并且增加选项的可能性很大的情况下才可以使用 另外 要使用这个模式 继承我在附件中提供的抽象类 XmlBuildFactoryFacade 就可以 快速建立一个工厂 如果你的项目放在 spring 或其它可配置框架中 也可以快 速建立工厂 设计一个 Map 静态属性并使其 V 为这些 A B C 这个工 厂就建立起来了 b b 策略模式策略模式 也许你看过策略模式 strategy model 的相关资料但没有留下太多的印象 一个简单的例子可以让你快速理解它 如果一个员工系统中 员工被分为临时 工和正式工并且在不同的地方相应的行为不一样 在设计它们的时候 你肯定 设计一个抽象的员工类 并且设计两个继承类 临时工和正式工 这样 通过 下塑类型 可以在不同的地方表现出临时工和正式工的各自行为 在另一个系 统中 员工被分为了销售人员 技术人员 管理人员并且也在不同的地方相应 的行为不一样 同样 我们在设计时也是设计一个抽象的员工类 并且设计数 个继承类 销售人员 技术人员 管理人员 现在 我们要把这两个系统合并 起来 也就是说 在新的系统中 员工既被分为临时工和正式工 又被分为了 销售人员 技术人员 管理人员 这时候如何设计 如果我们还是使用以往的 设计 我们将不得不设计很多继承类 销售临时工 销售正式工 技术临时工 技术正式工 如此的设计 在随着划分的类型 以及每种类型的选项的增 多 呈笛卡尔增长 通过以上一个系统的设计 我们不得不发现 我们以往学 习的关于继承的设计遇到了挑战 解决继承出现的问题 有一个最好的办法 就是采用策略模式 在这个应 用中 员工之所以要分为临时工和正式工 无非是因为它们的一些行为不一样 比如 发工资时的计算方式不同 如果我们在设计时不将员工类分为临时工类 和正式工类 而仅仅只有员工类 只是在类中增加 工资发放策略 当我们 创建员工对象时 根据员工的类型 将 工资发放策略 设定为 临时工策略 或 正式工策略 在计算工资时 只需要调用策略类中的 计算工资 方法 其行为的表现 也设计临时工类和正式工类是一样的 同样的设计可以放到销 售人员策略 技术人员策略 管理人员策略中 一个通常的设计是 我们将某 一个影响更大的 或者选项更少的属性设计成继承类 而将其它属性设计成策 略类 就可以很好的解决以上问题 使用策略模式 你同样把代码写活了 因为你可以无限制地增加策略 但 是 使用策略模式你同样需要设计一个工厂 策略工厂 以上实例中 你需 要设计一个发放工资策略工厂 并且在工厂中将 临时工 与 临时工策略 对应起来 将 正式工 与 正式工策略 对应起来 c c 适配器模式适配器模式 我的笔记本是港货 它的插头与我们常用的插座不一样 所有我出差的时 候我必须带一个适配器 才能使用不同地方的插座 这是一个对适配器模式最 经典的描述 当我们设计的系统要与其它系统交互 或者我们设计的模块要与 其它模块交互时 这种交互可能是调用一个接口 或者交换一段数据 接受方 常常因发送方对协议的变更而频繁变更 这种变更 可能是接受方来源的变更 比如原来是 A 系统 现在变成 B 系统了 也可能是接受方自身的代码变更 如 原来的接口现在增加了一个参数 由于发送方的变更常常导致接受方代码的不 稳定 即频繁跟着修改 为接受方的维护带来困难 遇到这样的问题 一个有经验的程序员马上想到的就是采用适配器模式 在设计时 我方的接口按照某个协议编写 并且保持固定不变 然后 在与真 正对方接口时 在前段设计一个适配器类 一旦对方协议发生变更 我可以换 个适配器 将新协议转换成原协议 问题就解决了 适配器模式应当包含一个 接口和它的实现类 接口应当包含一个本系统要调用的方法 而它的实现类分 别是与 A 系统接口的适配器 与 B 系统接口的适配器 我曾经在一个项目中需要与另一个系统接口 起初那个系统通过一个数据 集的方式为我提供数据 我写了一个接收数据集的适配器 后来改为用一个 XML 数据流的形式 我又写了一个接收 XML 的适配器 虽然为我提供数据的 方式不同 但是经过适配器转换后 输出的数据是一样的 通过在 spring 中的 配置 我可以灵活地切换到底是使用哪个适配器 d d 模板模式模板模式 32 个经典模式中的模板模式 对开发者的代码规划能力提出了更高的要求 它要求开发者对自己开发的所有代码有一个相互联系和从中抽象的能力 从各 个不同的模块和各个不同的功能中 抽象出其过程比较一致的通用流程 最终 形成模板 譬如说 读取 XML 并形成工厂 是许多模块常常要使用的功能 它们虽然有各自的不同 但是总体流程都是一样的 读取 XML 文件 解析 XML 数据流 形成工厂 正因为有这样的特征 它们可以使用共同的模板 那 么 什么是模板模式呢 模板模式 Template Model 通常有一个抽象类 在这个抽象类中 通常 有一个主函数 按照一定地顺序去调用其它函数 而其它函数往往是某这个连 续过程中的各个步骤 如以上实例中的读取 XML 文件 解析 XML 数据流 形 成工厂等步骤 由于这是一个抽象类 这些步骤函数可以是抽象函数 抽象类 仅仅定义了整个过程的执行顺序 以及一些可以通用的步骤 如读取 XML 文 件和解析 XML 数据流 而另一些比较个性的步骤 则由它的继承类自己去 完成 如上例中的 形成工厂 由于各个工厂各不一样 因此由各自的继承 类自己去决定它的工厂是怎样形成的 各个继承类可以根据自己的需要 通过重载重新定义各个步骤函数 但是 模板模式要求不能重载主函数 因此正规的模板模式其主函数应当是 final 虽 然我们常常不这么写 另外 模板模式还允许你定义的这个步骤中 有些步 骤是可选步骤 对与可选步骤 我们通常称为 钩子 hood 它在编写时 在抽象类中并不是一个抽象函数 但却是一个什么都不写的空函数 继承类在 编写时 如果需要这个步骤则

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论