定义
软件复用(SoftWare Reuse)是将已有软件的各种有关知识用于建立新的软件,以缩减软件开发和维护的花费。软件复用是提高软件生产力和质量的一种重要技术。早期的软件复用主要是代码级复用,被复用的知识专指程序,后来扩大到包括领域知识、开发经验、设计决定、体系结构、需求、设计、代码和文档等一切有关方面。
为什么需要复用?
- 降低成本和开发时间
- 产生可靠的软件
- 实现标准化,在不同应用中保持一致
两种类型
白盒复用
- 源代码可见,可修改和扩展,复制已有代码当正在开发的系统,进行修改
- 优点:可定制化程度高
- 缺点: 对其修改增加了软件的复杂度,且需要对其内部充分的了解
黑盒复用
- 源代码不可见,不能修改,只能通过API接口来使用,无法修改代码
- 优点:简单清晰
- 缺点:适应性差
下面主要从软件复用的三个层面进行分析:
- 模块级别
- 库级别
- 系统级别
一、模块级:类和接口
类的重用即继承和委托
继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
继承的特性
子类拥有父类非private的属性,方法。子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。子类可以用自己的方式实现父类的方法。Java的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如A类继承B类,B类继承C类,所以按照关系就是C类是B类的父类,B类是A类的父类。
提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系)。
继承可以使用 extends 和implements 这两个关键字来实现继承,而且所有的类都是继承于java.lang.Object,当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类。
二、库级别
【API和库】
- API是程序员最重要的资产和“荣耀”,吸引外部用户,提高声誉。
- 建议:始终以开发API的标准面对任何开发任务;面向“复用”编程而不是面向“应用”编程。
- 难度:要有足够良好的设计,一旦发布就无法再自由改变。
- 编写一个API需要考虑以下方面:
- API应该做一件事,且做得很好
- API应该尽可能小,但不能太小
- Implementation不应该影响API
- 记录文档很重要
- 考虑性能后果
- API必须与平台和平共存
- 类的设计:尽量减少可变性,遵循LSP原则
- 方法的设计:不要让客户做任何模块可以做的事情,及时报错
三、系统级
【框架】(内容参考白盒框架与黑盒框架)
链接: link.
-
框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面而后者是从目的方面给出的定义。
-
为了增加代码的复用性,可以使用委派和继承机制。同时,在使用这两种机制增加代码复用的过程中,我们也相应地在不同的类之间增加了关系(委派或继承关系)。而对于一个项目而言,各个不同类之间的依赖关系就可以看做为一个框架。一个大规模的项目可能由许多不同的框架组合而成。
-
框架与设计模式:
-
框架、设计模式这两个概念总容易被混淆,其实它们之间还是有区别的。构件通常是代码重用,而设计模式是设计重用,框架则介于两者之间,部分代码重用,部分设计重用,有时分析也可重用。在软件生产中有三种级别的重用:内部重用,即在同一应用中能公共使用的抽象块;代码重用,即将通用模块组合成库或工具集,以便在多个应用和领域都能使用;应用框架的重用,即为专用领域提供通用的或现成的基础结构,以获得最高级别的重用性。
-
框架与设计模式虽然相似,但却有着根本的不同。设计模式是对在某种环境中反复出现的问题以及解决该问题的方案的描述,它比框架更抽象;框架可以用代码表示,也能直接执行或复用,而对模式而言只有实例才能用代码表示;设计模式是比框架更小的元素,一个框架中往往含有一个或多个设计模式,框架总是针对某一特定应用领域,但同一模式却可适用于各种应用。可以说,框架是软件,而设计模式是软件的知识。
-
-
框架分为白盒框架和黑盒框架。
- 白盒框架:
- 白盒框架是基于面向对象的继承机制。之所以说是白盒框架,是因为在这种框架中,父类的方法对子类而言是可见的。子类可以通过继承或重写父类的方法来实现更具体的方法。
- 虽然层次结构比较清晰,但是这种方式也有其局限性,父类中的方法子类一定拥有,要么继承,要么重写,不可能存在子类中不存在的方法而在父类中存在。
- 软件构造课程中有关白盒框架的例子:
- 白盒框架:
public abstract class PrintOnScreen {
public void print() {
JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame, textToShow());
frame.dispose();
}
protected abstract String textToShow();
}
public class MyApplication extends PrintOnScreen {
@Override protected String textToShow() {
return "printing this text on " + "screen using PrintOnScreen " + "white Box Framework";
}
}
-
-
- 通过子类化和重写方法进行扩展(使用继承);
- 通用设计模式:模板方法;
- 子类具有主要方法但对框架进行控制。
- 允许扩展每一个非私有方法
- 需要理解父类的实现
- 一次只进行一次扩展
- 通常被认为是开发者框架
-
-
-
黑盒框架:
- 黑盒框架时基于委派的组合方式,是不同对象之间的组合。之所以是黑盒,是因为不用去管对象中的方法是如何实现的,只需关心对象上拥有的方法。
- 这种方式较白盒框架更为灵活,因为可以在运行时动态地传入不同对象,实现不同对象间的动态组合;而继承机制在静态编译时就已经确定好。
- 黑盒框架与白盒框架之间可以相互转换,具体例子可以看一下,软件构造课程中有关黑盒框架的例子,更改上面的白盒框架为黑盒框架:
-
public interface TextToShow {
String text();
}
public class MyTextToShow implements TextToShow {
@Override
public String text() {
return "Printing";
}
}
public final class PrintOnScreen {
TextToShow textToShow;
public PrintOnScreen(TextToShow tx) {
this.textToShow = tx;
}
public void print() {
JFrame frame = new JFrame();
JOptionPane.showMessageDialog(frame, textToShow.text());
frame.dispose();
}
}
-
-
- 通过实现插件接口进行扩展(使用组合/委派);
- 常用设计模式:Strategy, Observer ;
- 插件加载机制加载插件并对框架进行控制。
- 允许在接口中对public方法扩展
- 只需要理解接口
- 通常提供更多的模块
- 通常被认为是终端用户框架,平台
-