编写优质软件——代码可扩展性的几种实施方式

代码可扩展性的几种实施方式

《ThePragmaticProgrammer》(Addison-Wesley,1999)一书的作者DaveThomas和AndyHunt曾经说过,所有编程工作都是维护的一种形式。一个类在首次键入几分钟后就会进入无限的维护循环。大多数时候,维护要求把现有代码库重构成模式或者更简洁的设计。然而,维护的能力具备代码扩展的特性,即用新的函数扩展现有代码,且很好地整合现有代码。

DonaldKnuth对优化的说法几乎也同样适用于代码扩展性:过早实施是刀恶之源。很多开发者都渴望写出易于扩展的代码。这可能导致过度设计。

当可扩展特性是基础特性时,你可能需要在你的代码里考虑以下3个方面:基于接口的设计,插件架构和状态机。

重要:大多数时候,你需要找出证据证明你需要一个更可扩展、更灵活的设计。对更抽象、更灵活的设计的需要通常是重构过程的结果。一个更可扩展的设计也可以出现在冲刺的早期阶段,此时你可能正要实现一个新的特性。

基于接口的设计

接口代表两个软件组件之间的契约。当一个软件组件,如一个类,声明它能处理特定接口时,意味着它可以使用任何暴露相同接口的其他组件,不管是现有的还是将来会写的。这个理念就是可扩展代码的基础。

这个方案的关键是你应该设计成可扩展的软件组件的数量。把所有类都设计成可扩展的,且对于它们需要处理的每个逻辑都采用接口是非常不切实际的。在这点上没把握好就会导致你过度设计。

这里的挑战就是弄清何时从一个策略提取接口并在多个组件之间共享,这才是真正体现你更多价值的地方。相信我们,这是一个严峻的挑战。

插件架构

在提及可扩展性这个词时,很多人就想到插件。插件是一个外部组件,向现有应用程序添加原本没有的特定特性。为了实现这点,宿主应用程序必须设计成能够发现并处理插件。
宿主应用程序指定插件的编程接口,单方面地决定插件加载时接受什么数据,并指定它们何时调用以及应该放在何处才能识别出来。宿主应用程序也需要一个特殊的代码层,处理可用插件的加载和卸载。

写一个基于插件的架构有很多种方式。MartinFowler通过Plugin模式的描述很好地总结了这样一个架构的基本内容。你的代码会在某个时刻(被称为扩展点)使用一个组件执行一项特定的任务。这个任务会被抽象成一个接口或者基类。这个类使用专门的层从集中配置信息读取己注册的插件,然后通过工厂实例化它们。插件架构的典型例子是使用控制反转(IoC)框架并把配置信息集中放在web.config文件的网站。

当你有一个插件架构时,你有时候会面临的一个问题是把应用程序的状态共享给插件。如果所有插件只使用特定扩展点的方法注入的数据,那么问题可能不会出现。如果这种简单的方案行不通,你就应该考虑把系统的数据模型集中起来,以便所有插件可以平等获取这些数据。

状态机

状态机是把复杂任务分解成可管理步骤,实现某种精细行为的常见方式。状态机的最简形式是switch语句。在switch语句里,你很容易添加一个额外的分支,并放入相关的代码,简单、有效。当你发现可以展开一块代码整合多个任务和分支时,把它包装到一个状态机里,或者更一般地说,把它包装到某种黑盒里,你就朝可扩展性迈出扎实的一步了。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr___Ray

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值