如标题所述,本文面向于软考高级,具体来说是系统架构师。
有些概念,如生命周期,开发的几个阶段,不同的教程有些许出入。
本文偏理论,要在理解的基础上加以记忆,用于应付软考,有些地方注意抠字眼。
概念
Component Develop Model,构件开发模型,也可翻译为组件开发模型。
Component Based Development Model,基于构件的模型。
Component Oriented Programming,简称COP,面向构件的编程。
实际上是一个意思,表述不同而已。
构件
软件构件,或简称构件(Component,组件),是软件系统中具有一定意义的、相对独立的可重用单元。与对象相比,构件可以基于对象实现,也可以不作为对象实现。构件需要在容器中管理并获取容器提供的服务;客户程序可以在运行状态下利用接口动态确定构件所支持的功能并调用。
软件构件是部署、版本控制和替换的基本单位。构件是一组通常需要同时部署的原子构件。原子构件通常成组地部署,但是它也能够被单独部署。构件与原子构件的区别在于,大多数原子构件永远都不会被单独部署,尽管它们可以被单独部署。大多数原子构件都属于一个构件家族,一次部署往往涉及整个家族。一个模块是不带单独资源的原子构件。
构件技术就是利用某种编程手段,将一些人们所关心的,但又不便于让最终用户去直接操作的细节进行封装,同时对各种业务逻辑规则进行实现,用于处理用户的内部操作细节。构件是可复用的软件组成成份,可被用来构造其他软件。它可以是被封装的对象类、类树、一些功能软件工程中的构件模块、软件框架、软件构架(或体系结构)、文档、分析件、设计模式等。
构件的特性:
- 每一个构件都是
独立
的部署单元; - 作为第三方的组装单元;
- 没有(外部的)可见状态
一个构件可以包含多个类元素,但一个类元素只能属于一个构件。构件的部署必须能跟它所在的环境及其他构件完全分离;构件作为一个部署单元是不可拆分的;在一个特定进程中只能存在一个特定构件的拷贝;对于不影响构件功能的某些属性可以对外部可见。
对象的特性:
- 一个实例单元,具有唯一的标志
- 可能具有状态,此状态外部可见
- 封装自己的状态和行为
构件的具体例子,如:动态链接库.dll
,浏览器插件。
分类
在基于构件的软件开发中:
- 逻辑构件模型:用功能包描述系统的抽象设计,用接口描述每个服务集合,以及功能之间如何交互以满足用户需求,它作为系统的设计蓝图以保证系统提供适当的功能;
- 物理构件模型:用技术设施产品、硬件分布和拓扑结构,以及用于绑定的网络和通信协议描述系统的物理设计,这种架构用于了解系统的性能、吞吐率等许多
非功能性属性
。
在仓库风格中,有两种不同的构件:
- 中央数据结构:说明当前状态
- 独立构件:在中央数据存储上执行
构件开发模型
基于可重用构件的开发模型利用模块化
方法将整个系统模块化,并在一定构件模型的支持下复用构件库中的一个或多个软件构件,通过组合手段髙效率、髙质量地构造应用软件系统的过程。基于构件的开发模型融合螺旋模型
的许多特征,本质上是演化形的,开发过程是迭代的。
系统构件组装分为三个不同的层次:定制(Customization)、集成(Integration)、扩展(Extension)。这三个层次对应于构件组装过程中的不同任务。
COP关注于如何支持建立面向构件的解决方案,基于一般OOP风格,COP需要下列基本的支持:
- 多态性(可替代性)
- 模块封装性(高层次信息的隐藏)
- 后期的绑定和装载(部署独立性)
- 安全性(类型和模块安全性)
COP,仍然缺乏完善的方法学支持。现有的方法学只关注于单个构件本身,并没有充分考虑由于构件的复杂交互而带来的诸多困难,其中的一些问题可以在编程语言和编程方法的层次上进行解决。
生命周期
也可理解为几个阶段。
基于构件的开发模型包括2部分:系统开发、构件开发与维护。
系统开发的几个阶段:
- 需求分析
- 构件检索与分析:从构件库中选取符合需求的构件
- 然后基于需求分析和选取的构件进行体系结构设计
- 在实现阶段复用和集成构件
- 系统测试
- 系统维护
构件开发阶段的四个阶段:
另有一说,基于构件的开发模型由软件的需求分析定义、体系结构设计、构件库建立、应用软件构建、测试和发布5个阶段组成。
优点
- 软件复用
- 降低开发成本和风险,加快开发进度,提高软件质量
缺点
- 模型复杂
- 商业构件不能修改,会导致修改需求,进而导致系统不能完全符合客户需求
- 商业构件通常不能修改,会导致修改需求,也导致了无法完全控制所开发系统的演化
- 项目划分的好坏直接影响项目结果的好坏
适用场合:采用复用思想,故适用于系统之间有共性的情况。
失配
失配是指在软件复用的过程中,由于待复用构件对最终系统的体系结构和环境的假设(assumption)与实际状况不同而导致的冲突。在构件组装阶段失配问题主要包括:
- 由构件引起的失配,包括由于系统对构件基础设施、构件控制模型和构件数据模型的假设存在冲突引起的失配;
- 由连接子引起的失配,包括由于系统对构件交互协议、连接子数据模型的假设存在冲突引起的失配;
- 由于系统成分对全局体系结构的假设存在冲突引起的失配等。
要解决失配问题,首先需要检测出失配问题,并在此基础上通过适当的手段消除检测出的失配问题。
构件和需求不匹配?
有两种选择:
- 修改构件:商用构件通常不能修改;
- 修改需求:修改需求可能会导致最终产品和用户要求不完全一致,需和用户协商。
流派
构件模型是对构件本质特征的抽象描述。已形成三个主要流派,分别是OMG的CORBA、Sun的EJB和Microsoft的DCOM。这些实现模型将构件的接口与实现进行有效的分离,提供构件交互的能力,从而增加重用的机会,并适应目前网络环境下大型软件系统的需要。
CORBA
OMG,Object Management Group,对象管理组织,一个国际性非盈利组织,其职责是为应用开发提供一个公共框架,制订工业指南和对象管理规范,加快对象技术的发展。
CORBA,Common Object Request Broker Architecture,公共对象请求代理体系结构,通用对象请求代理架构是软件构建的一个标准。之所以称为抽象的,是因为并没有硬性规定CORBA对象的实现机制。由于独立于程序设计语言和特定ORB产品,一个CORBA对象的引用又称可互操作的对象引用(Interoperable Object Reference)。从客户程序的角度看,IOR中包含对象的标识、接口类型及其他信息以查找对象实现。
CORBA构件模型
- Object Adapter:对象适配器,用于屏蔽ORB内核的实现细节,为服务器对象的实现者提供抽象接口,以便他们使用ORB内部的某些功能。在底层传输平台与接收调用并返回结果的对象实现之间进行协调。目前采用的对象适配器规范是POA(Portable Object Adapter,可移植对象适配器),替代传统的BOA(Basic Object Adapter,基本对象适配器)
- Servant:伺服对象,CORBA对象的真正实现,负责完成客户端请求。指具体程序设计语言的对象或实体,通常存在于一个服务程序进程之中。
- Adapter Activator:适配器激活器,
- Object Request Broker:对象请求代理,解释调用并负责查找实现该请求的对象,将参数传给找到的对象,并调用方法返回结果。客户方不需要了解服务对象的位置、通信方式、实现、激活或存储机制
- 伺服对象定位器:
- 伺服对象激活器:
- 伺服对象管理器:伺服对象定位器和伺服对象激活器,用来提供CORBA服务端的对象查找服务,活动对象映射表用来保存已注册的CORBA对象标识和伺服对象之间的映射关系
CORBA体系结构是OMG为解决分布式处理环境中硬件和软件系统的互连而提出的一种解决方案,CORBA的核心是对象请求代理ORB(Object Request Broker,对象请求代理),它提供对象定位、对象激活和对象通讯的透明机制。客户发出要求服务的请求,而对象则提供服务,ORB把请求发送给对象、把输出值返回给客户。ORB的服务对客户而言是透明的,客户不知道对象驻留在网络中何处、对象是如何通讯、如何实现以及如何执行的,只要他持有对某对象的对象引用,就可以向该对象发出服务请求。
CORBA使用IDL(Interface Description Language,接口定义语言)用于描述组件将呈现出来的接口。
IDL文件包含六种不同的元素:模块定义、类型定义、常量定义、异常、接口描述和值类型。接口描述是一个IDL文件最核心的内容,模块定义将被映射为Java语言中的包或C++语言中的命名空间。
CORBA又规定从IDL到特定程序语言,如C++或Java,实现的映射。这个映射精确的描述CORBA资料类型是如何被用户端和服务器端实现的。标准映射的有C、C++、Java以及Python。
客户程序通过对象引用发出的请求经过ORB担当中介角色,转换为对特定的伺服对象的调用。在一个CORBA对象的生命期中,它可能与多个伺服对象相关联,因而对该对象的请求可能被发送到不同的伺服对象。
对象标识(Object ID)是一个用于在POA中标识一个CORBA对象的字符串。
它既可由程序员指派,也可由对象适配器自动分配,这两种方式都要求对象标识在创建它的对象适配器中必须具有唯一性。
POA是对象实现与ORB其他组件之间的中介,它将客户请求传送到伺服对象,按需创建子POA,提供管理伺服对象的策略。
OMG基于CORBA基础设施定义四种构件标准:
- Entity:实体构件需要长期持久化并主要用于事务性行为,由容器管理其持久化
- Process:加工构件同样需要容器管理其持久化,但没有客户端可访问的主键
- Session:会话构件不需要容器管理其持久化,其状态信息必须由构件自身管理
- Service:服务构件是无状态的
EJB
Enterprise Java Bean,企业级Java组件,EJB是SUN的服务器端组件模型,最大用处是部署多层结构、分布式、面向对象的应用程序。凭借Java跨平台的优势,用EJB技术部署的分布式系统可以不限于特定的平台。是J2EE的一部分,定义一个用于开发基于组件的企业多重应用程序的标准。
EJB可分为Session Bean,Entity Bean和Message Driven Bean:
- Session Bean:会话Bean,用于实现业务逻辑,可以是有状态、无状态的。每当客户端请求时,容器就会选择一个Session Bean来为客户端服务。可以直接访问数据库,但更多情况下会通过Entity Bean实现数据访问。负责完成服务端和客户端的交互
- Entity Bean:实体Bean,域模型对象,用于实现O/R映射,负责将数据库中的表记录映射为内存中的Entity对象。事实上,创建一个Entity Bean对象相当于新建一条记录,删除一个Entity Bean会同时从数据库中删除对应记录,修改一个Entity Bean时,容器会自动将Entity Bean的状态和数据库同步。
- Message Driven Bean:消息驱动Bean,EJB 3.0中引入的企业Bean,基于JMS(Java Message Service,Java消息服务)消息,只能接收客户端发送的JMS消息然后处理。MDB实际上是一个异步无状态Session Bean,客户端调用MDB后无需等待立刻返回,MDB将异步处理客户请求。这适合于需要异步处理请求的场合,比如订单处理,这样就能避免客户端长时间的等待一个方法调用直到返回结果。
DCOM
Component Object Model,简称COM,可翻译为组件对象模型,构件对象模型;
Distribute Component Object Model,简称DCOM,分布式构件对象模型。
Microsoft的COM定义构件和它们的客户之间互相作用的方式,使得构件和客户端无需任何中介构件就能相互联系。
DCOM扩展COM,使其能够支持在局域网、广域网甚至Internet上不同计算机的对象之间的通信。使用DCOM,应用系统就可以在位置上达到分布性,从而满足客户和应用的需求。因为DCOM是COM的无缝扩展,所以可将基于COM的应用、构件、工具和知识转移到标准化的分布式计算领域中。在做分布式计算时,DCOM处理网络协议的低层次的细节问题,从而使开发人员能够集中精力解决用户所要求的问题。
DCOM具有语言无关性,任何语言都可以用来创建COM构件。DCOM具有位置独立性,即DCOM使得构件的位置对用户来说完全透明,用户无需知道构件的具体位置,无论构件是位于客户的同一个进程中,还是位于地球的另一端。在任何情况下,客户连接和调用构件的方法都是一样的。DCOM不仅无需改变源码,而且无需重新编译程序。仅仅使用一个简单的再配置动作,就可以改变构件之间相互连接的方式。
DCOM是一系列微软的概念和程序接口,利用这个接口,客户端程序对象能够请求来自网络中另一台计算机上的服务器程序对象。Microsoft的DCOM扩展COM,使其能够支持在局域网、广域网甚至Internet上不同计算机的对象之间的通讯。使用DCOM,应用程序就可以在位置上达到分布性。
COM+
COM+并不是COM的新版本,可理解为COM的新发展,或COM更高层次上的应用。COM+的底层结构仍然以COM为基础,几乎包容COM的所有内容。COM+倡导一种新的概念,它把COM组件软件提升到应用层而不再是底层的软件结构,它通过操作系统的各种支持,使组件对象模型建立在应用层上,把所有组件的底层细节留给操作系统。COM+不再局限于COM的组件技术,更加注重于分布式网络应用的设计和实现,已经成为Microsoft系统平台策略和软件发展策略的一部分。COM+继承COM几乎全部的优势,同时又避免COM实现方面的一些不足。COM+紧紧地与操作系统结合起来,通过系统服务为应用程序提供全面的服务。
COM对象重用
为实现对象重用,COM支持两种形式的对象组装:
- 包含:Containment,一个外部对象拥有指向一个内部对象的唯一引用,外部对象只是把请求转发给内部对象;
- 聚集:Aggregation,直接把内部对象的接口引用传给外部对象的客户,而不再转发请求。
COM不支持任何形式的实现继承,COM没有定义或考虑单独的构件从内部如何去实现。构件可以由使用实现继承的类组成。无论何种情况,缺少实现继承并不意味着缺少对重用的支持。
包含就是一种简单的对象组装技术,即一个对象拥有指向另一个对象的引用。从概念上来说,前者(外部对象)包含后者(内部对象)。外部对象只是把请求转发给内部对象。转发,就是调用内部对象的方法,以实现对某个外部对象方法的调用。
包含能重用内含于其他构件的实现。特别是,对于使用外部对象的客户程序,包含是完全透明的。调用接口函数的客户无法辨别调用是由提供接口的对象处理,还是被转发给另一个对象处理。如果包含层次较深,或者被转发的方法本身相对简单,包含会存在性能上的问题,因此COM定义第二类重用形式,即聚集。聚集的基本思想很简单,直接把内部对象的接口引用传给外部对象的客户,而不再转发请求。对此接口的调用将直接到达内部对象,从而省去转发的代价。当然,只有在外部对象不希望截取调用以执行诸如过滤等额外处理时聚集。还有,保持透明性是很重要的,因为外部对象的客户无法辨别哪个特定接口是从内部对象聚集而来的。