软件构造-构件复用

本文探讨了可复用构件在软件复用中的核心地位,详细介绍了COM、JavaBean和CORBA等主流技术流派。同时,文章阐述了设计可复用的类和库的原则,包括子类型多态、利斯科夫替换原则以及委托和组合,强调了在设计过程中遵循的原则。最后,讨论了API和框架在软件复用中的作用,指出框架是可复用设计的重要组成部分,区分了白盒框架和黑盒框架的特点。
摘要由CSDN通过智能技术生成

可复用构件与软件复用的关系

1.可复用构件的定义及特征

   构件是指应用系统中可以明确辨识的有机构成成分,它具有相对独立性、互换性和功能性的特征。可复用构件则是指具有相对独立的功能和可复用价值的构件。
   可复用构件应具备以下特征:

  • 有用性,必须提供有用的功能;
  • 可用性,必须易于理解和使用;
  • 可靠性 ,构件自身及其变形必须能正确工作;
  • 适应性,应易于通过参数化等方式在不同语境中进行配置;
  • 可移植性,能在不同的硬件平台和软件环境中工作。

   随着对软件复用理解的深入,构件的概念已经不再局限于源代码构件,而是延伸到系统和软件的需求规约、系统和软件的构架、文档测试计划、测试案例和数据,以及其他对开发活动有用的信息,这些信息都可以称为可复用软件构件。

2.软件复用的核心是可复用构件

   可复用构件技术是支持软件复用的核心技术,是近几年来迅速发展并受到高度重视的一个学科分支。随着软件产业工业化的发展,也许未来会出现这样一种产业模式:构件生产商专门生产构件,然后再由零售商等构件管理者将它们拿到市场上销售。系统集成商则根据自己应用系统的需求进行构件的采购、集成和组装。

可复用构件的主要技术流派

   目前,软件构件技术流派主要有三种:

1.COM

   COM构件实现规范由微软提出,它使开发人员可以利用其中的通信机制,组装不同开发商的构件。COM的核心是一组应用程序调用接口,该接口提供了创建构件组建构件的功能。为支持网络环境,微软对COM进行了扩充,这就是DCOM。COM规范具有以下特点:

  • 构件间的互操作基于指针进行,依赖于操作系统的API;
  • 对 Windows的依赖性强,对其他操作系统支持相对不足;
  • 构件运行环境的提供者仅限于微软,但支持COM规范的开发工具较多,如VC+ +、VB和Builder等。
2.JavaBean

   JavaBean构件实现规范是由SUN公司在Java语言的基础上提出的。由于Java是一种纯对象式语言,因此JavaBean构件规范比较完备、简洁。JavaHBean规范具有以下特点:

  • 构件模型比较完备;
  • 仅支持Java语言;
  • 构件运行环境有SUN支持,其他厂商也可提供运行环境。支持该模型的开发工具较多,如Visual Cafe、Visual age for Java等。
3.CORBA

   CORBA实现规范由OMG提出。OMG首先发布了OMA(对象管理体系结构) ,提出了构件互操作的软总线——ORB (Object Request Broker) ,并将构件分为三类:公共对象服务COS、面向领域的公共设施CF和应用对象AF。CORBA规范具有以下特点:

  • 构件间的复用以 ORB为中介,对处理机、操作系统、语言的异构性支持性强;
  • 充分借鉴JavaBean的构件原型;
  • 提供构件运行环境的厂商较多,对开发支持的工具相对较少,通常需要传统开发工具的支持等。

设计可复用的类

1.子类型多态和利斯科夫替换原则

   子类型多态:客户端可用统一的方式处理不同类型的对象,例如:

Animal a = new Animal(); 
Animal c1 = new Cat(); 
Cat c2 = new Cat();

   在可以使用a的场景,都可以用c1和c2代替而不会有任何问题(但反过来不行,即不能用父类来实例化一个子类引用)

  1. java静态类型检查中的规则:
    1. 子类型可以增加方法,但不可删父类原有的方法
    2. 子类型需要实现抽象类型中的所有未实现方法
    3. 子类型中重写的方法必须有相同或子类型的返回值
    4. 子类型中重写的方法必须使用同样类型的参数(或该类型的父类型,但java中不支持,会自动默认为重载)
    5. 子类型中重写的方法不能抛出额外的异常
  2. 规约上的准则:
    1. 更强的不变量
    2. 更弱的前置条件
    3. 更强的后置条件
  3. 里氏替换原则的主要作用就是规范继承时子类的一些书写规则。其主要目的就是保持父类方法不被覆盖。
    含义:
       子类必须完全实现父类的方法
       子类可以有自己的个性
       覆盖或实现父类的方法时输入参数可以被放大
       覆盖或实现父类的方法时输出结果可以被缩小
    利斯科夫替换原则本质是强行为子类型化,其要求为:
    1. 前置条件不能强化
    2. 后置条件不能弱化
    3. 不变量要保持
    4. 子类型方法参数:逆变
    5. 子类型方法的返回值:协变
    6. 异常类型:协变
  4. 协变:子类型方法的返回值是其父类型方法的返回值的子类型,即子类型及其方法的返回值在各自的继承树上的相对位置是协同的
  5. 逆变:子类型参数的类型是其父类型方法的返回值的父类型,即子类型及其方法的参数在各自的继承树上的相对位置是相反的
  • 逆变与协变综述:如果A、B表示类型,f(⋅)表示类型转换,≤表示继承关系(比如,A≤B表示A是由B派生出来的子类):
    f(⋅)是逆变(contravariant)的,当A≤B时有f(B)≤f(A)成立;
    f(⋅)是协变(covariant)的,当A≤B时有f(A)≤f(B)成立;
    f(⋅)是不变(invariant)的,当A≤B时上述两个式子均不成立,即f(A)与f(B)相互之间没有继承关系。
  • 协变(Co-variance):
    父类型->子类型:越来越具体(specific)。
    在LSP中,返回值和异常的类型:不变或变得更具体 。
    例子:
    在这里插入图片描述
  • 逆变(Contra-variance):
    父类型->子类型:越来越抽象。
    参数类型:要相反的变化,不变或越来越抽象。
    例子:
    在这里插入图片描述
    但这在Java中是不允许的,因为它会使重载规则复杂化。
    总结:
    在这里插入图片描述
    (1.子类型(属性、方法)关系;2.不变性,重写方法;3.协变,方法返回值变具体;4.逆变,方法参数变抽象;5.协变,参数变的更具体,协变不安全)
  1. java遇到逆变时,当作overload(重载)处理
  2. 实例:数组类型
    数组是协变的:一个数组T[ ] ,可能包含了T类型的实例或者T的任何子类型的实例
    即子类型的数组可以赋予父类型的数组进行使用,但数组的类型实际为子类型。
    下面报错的原因是myNumber指向的还是一个Integer[] 而不是Number[]
Number[] numbers = new 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值