代码复用是绝大多数程序员所期望的,也是OO的目标之一。总结我多年的编码经验,为了使代码能够最大程度上复用,应该特别注意以下几个方面。
对接口编程
"对接口编程"是面向对象设计(OOD)的第一个基本原则。它的含义是:使用接口和同类型的组件通讯,即,对于所有完成相同功能的组件,应该抽象出一个接口,它们都实现该接口。具体到JAVA中,可以是接口(interface),或者是抽象类(abstract class),所有完成相同功能的组件都实现该接口,或者从该抽象类继承。我们的客户代码只应该和该接口通讯,这样,当我们需要用其它组件完成任务时,只需要替换该接口的实现,而我们代码的其它部分不需要改变!
当现有的组件不能满足要求时,我们可以创建新的组件,实现该接口,或者,直接对现有的组件进行扩展,由子类去完成扩展的功能。
优先使用对象组合,而不是类继承
"优先使用对象组合,而不是类继承"是面向对象设计的第二个原则。并不是说继承不重要,而是因为每个学习OOP的人都知道OO的基本特性之一就是继承,以至于继承已经被滥用了,而对象组合技术往往被忽视了。下面分析继承和组合的优缺点:
类继承允许你根据其他类的实现来定义一个类的实现。这种通过生成子类的复用通常被称为白箱复用(white-box reuse)。术语"白箱"是相对可视性而言:在继承方式中,父类的内部细节对子类可见。
对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组合对象来获得。对象组合要求对象具有良好定义的接口。这种复用风格被称为黑箱复用(black-box reuse),因为被组合的对象的内部细节是不可见的。对象只以"黑箱"的形式出现。
继承和组合各有优缺点。类继承是在编译时刻静态定义的,且可直接使用,类继承可以较方便地改变父类的实现。但是类继承也有一些不足之处。首先,因为继承在编译时刻就定义了,所以无法在运行时刻改变从父类继承的实现。更糟的是,父类通常至少定义了子类的部分行为,父类的任何改变都可能影响子类的行为。如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。
对象组合是通过获得对其他对象的引用而在运行时刻动态定义的。由于组合要求对象具有良好定义的接口,而且,对象只能通过接口访问,所以我们并不破坏封装性;只要类型一致,运行时刻还可以用一个对象来替代另一个对象;更进一步,因为对象的实现是基于接口写的,所以实现上存在较少的依赖关系。
优先使用对象组合有助于你保持每个类被封装,并且只集中完成单个任务。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物(这正是滥用继承的后果)。另一方面,基于对象组合的设计会有更多的对象(但只有较少的类),且系统的行为将依赖于对象间的关系而不是被定义在某个类中。
注意:理想情况下,我们不用为获得复用而去创建新的组件,只需要使用对象组合技术,通过组装已有的组件就能获得需要的功能。但是事实很少如此,因为可用的组件集合并不丰富。使用继承的复用使得创建新的组件要比组装已有的组件来得容易。这样,继承和对象组合常一起使用。然而,正如前面所说,千万不要滥用继承而忽视了对象组合技术。
相关的设计模式有: Bridge、Composite、Decorator、Observer、Strategy等。
下面的例子演示了这个规则,它的前提是:我们对同一个数据结构,需要以任意的格式输出。
第一个例子,我们使用基于继承的框架,可以看到,它很难维护和扩展。
abstract class AbstractExampleDocument
{
// skip some code ...
public void output(Example structure)
{
if( null != structure )
{
this.format( structure );
}
}
protected void format(Example structure);
}
第二个例子,我们使用基于对象组合技术的框架,每个对象的任务都清楚的分离开来,我们可以替换、扩展格式类,而不用考虑其它的任何事情。
class DefaultExampleDocument
{
// skip some code ...
public void output(Example structure)
{
ExampleFormatter formatter =
(ExampleFormatter) manager.lookup(Roles.FORMATTER);
if( null != structure )
{
formatter.format(structure);
}
}
}
这里,用到了类似于"抽象工厂"的组件创建模式,它将组件的创建过程交给manager来完成;ExampleFormatter是所有格式的抽象父类;
将可变的部分和不可变的部分分离
"将可变的部分和不可变的部分分离"是面向对象设计的第三个原则。如果使用继承的复用技术,我们可以在抽象基类中定义好不可变的部分,而由其子类去具体实现可变的部分,不可变的部分不需要重复定义,而且便于维护。如果使用对象组合的复用技术,我们可以定义好不可变的部分,而可变的部分可以由不同的组件实现,根据需要,在运行时动态配置。这样,我们就有更多的时间关注可变的部分。
对于对象组合技术而言,每个组件只完成相对较小的功能,相互之间耦合比较松散,复用率较高,通过组合,就能获得新的功能。
减少方法的长度
通常,我们的方法应该只有尽量少的几行,太长的方法会难以理解,而且,如果方法太长,则应该重新设计。对此,可以总结为以下原则:
☆ 三十秒原则:如果另一个程序员无法在三十秒之内了解你的函数做了什么(What),如何做(How)以及为什么要这样做(Why),那就说明你的代码是难以维护的,必须得到提高;
☆ 一屏原则:如果一个函数的代码长度超过一个屏幕,那么或许这个函数太长了,应该拆分成更小的子函数;
☆ 一行代码尽量简短,并且保证一行代码只做一件事:那种看似技巧性的冗长代码只会增加代码维护的难度。
分享到:
相关推荐
### 第5章 函数和代码复用 #### 知识点概述 本章节主要围绕着函数的概念、定义、使用以及代码复用的方式展开讨论。针对Delphi环境下的Python语言程序设计,深入剖析了如何利用函数实现更高效、灵活的编程实践。 #...
【摘要分析】 本文主要探讨了针对Linux操作...综上所述,这篇文章提出了一个有效的内核级代码复用攻击检测技术,利用控制流完整性、编译器插桩和Hypervisor层的验证,实现了对内核安全的强化,同时兼顾了系统的性能。
qt,c++告警规则 demo仅供参考,代码复用
自.NET Framework 2.0起,可以使用`System.EventHandler<TEventArgs>`泛型委托,以避免为每个特定事件创建新的委托类型,提高了代码的复用性和灵活性。 5. **CA1004:泛型方法应提供类型参数推理** 泛型方法应该...
在Python编程中,函数和代码复用是核心概念,它们有助于编写简洁、高效且易于维护的代码。以下是根据提供的文件内容解析出的相关知识点: 1. **递归函数**: - 递归函数是一种在其定义中调用自己的函数。 - **基...
Yii2扩展开发与代码复用是当前流行的PHP开发框架Yii2的一个重要实践领域,特别是在资源包的开发和复用方面,本文将深入探讨如何利用资源包来管理和维护前端资源,以及如何通过扩展的形式实现代码的复用。 在Yii2...
在 PHP 语言中,代码复用是一个重要的编程原则,它有助于提高代码的效率和可维护性。自 PHP 5.4.0 版本起,PHP 引入了一种新的代码复用机制,称为 Traits。Traits 是一种为了解决单继承限制而设计的特性,它允许...
【标题】"rulz可复用的JUnit规则" 是一个专门为Java开发人员设计的测试框架扩展,它提供了丰富的JUnit规则库,使得单元测试更加灵活和可维护。JUnit是Java领域广泛使用的自动化测试框架,而rulz则进一步提升了其功能...
本测验主要围绕函数和代码复用的主题展开,涵盖了一些基本的函数使用规则和递归的概念。 1. **函数的作用**: - **复用代码**:函数的主要优点之一就是可以避免重复代码,提升开发效率。 - **降低编程复杂度**:...
在实际应用中,通常通过STM32CubeMX这类工具或直接在代码中设置寄存器来配置这些复用功能,以达到设计要求。正确使用这些高级特性,可以在硬件资源有限的情况下,扩展微控制器的应用范围,提高系统的灵活性和性能。
这部分强调代码复用的原则和方法,提高开发效率并减少重复代码。 - **DRY原则**:代码复用应尽量避免重复。 - **SHY原则**:指的是在代码复用中要慎用继承。 - **可变与不可变分离**:分离程序中的可变和不可变部分...
### 书写和存储可复用的Fortran90Style代码准则 #### 1. 引言 本准则旨在为欧洲气象组织提供一个统一的Fortran 90编程框架,以促进不同组织间代码的交流与复用。通过建立一套标准化的文档规范与代码编写准则,不仅...
9. **模块化编程**:可能采用了模块化设计,如ES6的import/export,便于代码管理和复用。 10. **错误处理**:适当的错误检测和处理,确保代码的健壮性。 学习并理解这个代码,对于提升前端开发者在动态效果和用户...
在缩略语和术语方面,标准中详细界定了面向5G前传的无源彩光粗波分复用设备的组成部分和光模块的应用代码,包括网络位置、设备管理、光模块分类以及应用代码的详细描述。 技术要求部分,包括了极限要求、推荐工作...
总的来说,liteFlow作为一个全面的规则引擎和流程引擎,集成了众多高级特性,如DSL规则表达式、组件复用、同步/异步编排、动态编排等,旨在帮助开发者构建灵活、高效且易于维护的业务流程。在程序开发领域,尤其是...
代码复用是最基础的层次,通过直接使用或修改已有的源代码或目标代码。设计复用涉及复用设计模式和模板,减少了对实现环境的依赖。分析复用则更进一步,复用的是对问题域的理解和解决方案,抽象程度更高。 复用技术...
以上只是VB编码规范的一部分要点,实践中还会涉及更多细节,如代码复用、异常处理策略、代码审查等。遵循这些规范,可以使VB代码更易于理解,更健壮,同时也为团队合作提供了统一的标准。通过不断学习和实践,开发者...
在AngularJS中,创建可复用组件是一种提升代码效率和可维护性的重要方式。本教程将以创建一个名为“rn-stepper”的自定义步长选择Directive为例,深入讲解如何实现AngularJS中的可复用组件。 首先,理解AngularJS的...