1、第九章 联系的实现,对象类型间通过属性的引用建立了对象实例间的联系本章重点研究对象间联系的语义及其实现方法对象间的联系可以是n元联系(n2)n个对象间通过一个联系进行联接其中最简单,常用的是二元联系(n=2)二元联系中,二个对象间的联系语义有1:1,1:N,N:1,N:M,9.1 没有属性的二元联系,一个二元联系本身没有任何属性,它只表达了二个对象类型间的联系联系的实现:通过设置进入点entry point来完成进入点设在Tleft处:Tleft类型增加一个引用对象Tright的属性,Tright类型无需增加属性进入点设在Tright处增加一个对象类型Rbin,它仅有二个元组属性,分别是Tle
2、ft类型和Tright类型,这种方法可以加载Rbin本身独特的属性,1:1的二元联系的实现,(一)无冗余的表达方式一个联系仅在一个对象属性中表达采用 (或者)方法应当从查询需求入手,选择查询频度高的一方作为进入点问题: 1)反向查询速度极慢:对一个特定的Tright实例,查其相应的Tleft实例时需要查过所有的Tleft实例集合2)即使正向查询,若存在联系的偶对集合很小,那么仍然费时,采用方法定义一个Rbin类型,Tr并由系统维护Tr集合,适用于Tr相对Tleft(Tright)较小时问题:1)需要二次查找才能定位2)当Tr集合仍然庞大是,寻找一组特定的偶对效率仍然很低需要建立索引,type
3、Tleft is body R:Tright; end type Tleft;,type Tright body R-1 :Tleft; end type Tright;,type TR is with extension is body left:Tleft; right:Tright;end type TR;,1:1的二元联系的实现(续),(二)冗余的表达方式1二个进入点在Tleft中建立R属性类型为Tright在Tright中建立R-1属性类型为Tleft优点:提高反向查询效率问题:当两个对象实例间的联系发生变更时,容易产生修改异常,生成对象库状态的一致性受到破坏,解决方法:重新定义R属
4、性的值接受操作refine R:Tright code setR;define setR(oright) isbegin oright.R-1 := self; self.R := oright;end define setR;由此,确保了R属性与.R-1属性的同步修改必须利用封装技术来控制不会单独修改.R-1 (.R-1只读),总结,利用封装技术重新定义关联属性的状态的修改特别注意不能在同一时间,以同样的方式修改类型Tright的.R-1的值接受操作,否则导致递归操作的无限循环即:重写Tleft,R的值接受操作隐藏Tright,.R-1 的值接受操作,使其为只读类型,(三)冗余表达方式2采用
5、显式的冗余方式用TR作为中间联系方法将二者显式相连查询为二次查询,但管理方便对R, R-1 的修改自然要遵照异常处理方式重定义VCO和做相应的隐藏,type Tleft is body R:TR; end type Tleft;,type TR is with extension is body left:Tleft; right:Tright;end type TR;,type Tright body R-1 :TR; end type Tright;,1:N 的二元 联系的实现,type Tleft is type Tright is type TR body body with exte
6、nsion is body R: Tright ; R-1: Tleft; left: Tleft ; right: Tright; end type Tleft; end type Tright ; end type TR ; 方式(1)方式(2)方式(3),1,N,其中唯有方式(2)能确保一致性约束,R-是单值的。方式(1)(3)均不能确保两对象间1:N的约束。对(1),必须重新定义R属性的值接受操作对(3),必须对TR的对象实例库进行一致性维护,即TR的insert操作进行一致性维护,N:M的二元联系的实现,type Tleft is type Tright is type TR bod
7、y body with extension is body R: Tright ; R-1: Tleft ; left: Tleft ; right: Tright; end type Tleft; end type Tright; end type TR ; 方式(1)方式(2)方式(3)采用原则:以最大查询频率为依据选择入口点可以采用组合冗余方法,但需要进行状态一致性维护,N,M,具有K个属性的二元联系的实现,1:1的联系:仍然可以采用方式(1)或(2),K个属性寄放在Tleft或Tright1:N的联系只能放在单值属性的对象类型方N:M的联系寄存在那一方均不合适,只能采用方式(3),定义
8、此属性的类型TR, TR具有K+2个元组属性,Tleft,a1,Tright,R,ak,Type TRwith extension isBodyleft: Tleft ; right: Tright;a1:T1R;ak:TkR; operationsdeclare TR: Tleft , Tright,T1R, , TkR - TR code initTR;implementationdefine initTR(Oleft ,Oright,O1,Ok) isbegin self.left := Oleft; self.right := Oright; self.a1 := O1; ; self
9、.ak := Ok ;end define initTRend type TR,N元联系的实现,只能采用方式(3)建立TR类型处理对初始化进行重定义,以保证约束的一致性。为了检索高效率,需要考虑受控的冗余建模。,T1,T2,a1,ak,Tn,R,type TRwith extension isBodyentitiy1: T1 ; entitiyn: Tn;a1:T1R;ak:TkR; operationsdeclare TR: T1 , , Tn,T1R, , TkR - TRimplementationend type TR,示例分析(一),1-1联系实例:工程师与他所占办公室的联系处理约束
10、条件:一个工程师一间办公室type Engineer is type Office is bodybody resideIn: Office; isOccupied: Engineer; end type Engineer ; end type Office; 先有工程师,再分 经常查询某办公室的工程师是谁配房间,1,1,用方式(1)和(2)组合建模下冗余的一致性维护,联系更新时一般的方式(1)If (thePenthouse.isOccupiedby != NULL)thePenthouse.isOccupiedby.residesIn :=NULL; (2)If (leonardo.res
11、idesIn != NULL ) leonardo.residesIn. isOccupiedby :=NULL; (3) leonardo.residesIn := thePenthouse;(4) thePenthouseis.Occupiedby := leonardo;,设计操作moveToOffice来维护一致性状态define moveToOffice(newResidence ) isbegin if (newResidence.isOccupiedBy != NULL)newResidence.isOccupiedBy.residesIn := NULL; if (self.r
12、esidesIn != NULL )self.residesIn.isOccupiedBy := NULL; self.residesIn := newResidence; newResidence. isOccupiedBy := self;end define moveToOffice;,示例分析(二),工程师与部门间的1:N的联系type Engineer is type Division is body body worksfor: Division; employs: EngineerSet; end type Engineer ; end type Division; type E
13、ngineerSet is body Engineer end type EngineerSet;,N,1,控制类型冗余模型的两个操作,hiredefine hire(newEng) isBeginself.employs.insert(newEng);newEng.worksFor := self; end define hire;Firedefine fire(badEng) isBeginself.employs.remove(badEng);badEng.worksFor := NULL; end define hire;聘用和辞退两个操作可以保持DB的完整性约束。,递归的1:N的关系
14、,产品与产品间具有递归的组合联系E-R图的展开可以有两种描述模式,A:通过Super属性表达了is.part-of的语义关系:即:一个产品属于上层产品的一个部件type Product is body super: Product ; end type Product ;适用范围:查找某种产品被组装在什么部件中。沿part-of路径进行导航或访问,Super:,Super:,Super:,Super:,Super:,Super:,Super:,Super:,B:通过Sub属性表达了partlist的语义关系:即:一个部件由几个子部件所组成type Product is body sub: Pr
15、oductSet ; end type Product ;type ProductSet is body Product end type ProductSet ;适用范围:查找组成某部件的所有子部件,Sub:,Sub:,Sub:,Sub:,Sub:,Sub:,Sub:,Sub:,应用示例,操作partlist:输出组成某个产品的所有部件采用结构Idefine partList isvar resultSet: ProductSet;beginresultSet.create;!create an empty setresultSet.insert( self );foreach ( part
16、 in ext( Product ) if ( part.super = self )resultSet.setUnion(part.partList);!recursive call of partListreturn resultSetend define partList,采用结构IIdefine partList isvar resultSet: ProductSet;beginresultSet.create;resultSet.insert( self );foreach (part in self.sub) resultSet.setUnion(part.partList);!r
17、ecursive call of partListreturn resultSet;end define partList;该程序是高效的。,操作is part of:采用结构Idefine isPartOf(theSuperPart) is !is self a subpart of theSuperPart?var part: ProductBeginpart := self;while ( part != NULL )If ( part = theSuperPart )return true;else part := part.super;return false;end define
18、isPartOf;高效,只需沿self向上查找到根一条路径,采用结构IIdefine isPartOf(theSuperPart) is var isUsed: bool := false;Beginforeach ( part in theSuperPart.partList)If ( part = self ) isUsed := true;!we could already exit the loop herereturn isUsed;end define isPartOf;低效,需到theSuperPart节点的所有组件中寻找self,第III种冗余组合模式,type product
19、 is body super:Product; sub:ProductSet; end type product 该模式的使用中,重要的是维护DB的一致性,N:M关系举例,方式一,采用组合的冗余表达方式 type Engineer is type Product is body body designs: ProductSet; designedBy: EngineerSet; end type Engineer ; end type Product; type EngineerSet is type ProductSet is body Engineer body Product end t
20、ype EngineerSet; end type ProductSet;,N,M,方式二,采用单独定义的TR类型表示联系type Designswith extension is bodytheParticipatingEngineer:Engineer;theProduct:Productend type Designs,互逆联系的实现,问题的提出:在用冗余表达对象间的联系时,如何用系统来自动维护修改的一致性?互逆联系:对称的联系偶对,由inverse显示标识。系统将按照用户标识指定的互逆联系的修改进行自动的一致性维护。,(一)1:1的单值逆属性,示例:关于婚姻的一致性控制,没有两个类型及
21、其冗余的联系: type Man istype Woman is body body wife:Woman husband:Man . ; ; end type Man; end type Woman,mickeyMouse.wife := miniMouse; miniMouse.husbnd:=donaldDuck;控制婚姻联系的一致性约束条件为: w.husband =m; 当且仅当 m.wife = w如果上面的约束由系统自动维护,则需要用户显示的指明互逆联系,type Man is wife : Woman inverse Woman$husband; end type Man; t
22、ype Woman is husband : Man inverse Man$wife; end type Woman;mickeyMouse.wife := miniMouse;miniMouse.husband:=donaldDuck;,(二)多值逆属性,利用多值(集合)逆属性来实现对象间1:N联系的冗余表示,例如递归组合属性super与sub(多值)间的互逆的联系。示例:用户界面窗口的设计(无重叠的全包含窗口) 窗口:用一个矩形框表示 窗口之间是全包含的联系,r1,r11,r112,其中: r1包含r11、r12 且r11r1 r1不直接包含 r111, r111被r11直接包含,r11
23、1,r12,type Rectangle is body height,length:float; contains:Rectangle ; end type Rectangle; 其中联系属性contains是一个多值集合属性,其元素为矩形框对象。,现定义contains的一个逆关系containsIn,其约束为: 若两个窗口对象r,r具有r contains r,则 r containsIn r, 即 containsIn(r)=r| rcontains(r) 最多仅由一个矩形r直接包含r。,r1,r12,r11,r112,r111,包含一对互逆联系属性的窗口类型定义如下: type Re
24、ctangle is body height,length:float; contains:Rectangle inverse Rectangle$containedIn; containedIn:Rectangle inverse Rectangle$contains; ; end type Rectangle;,9.6 复合对象引用的支持,GOM支持对象间引用的更复杂的语义描述引用的分类 弱引用: (weak reference)两个对象o1,o2除了它们之间存在一个引用联系外,没有任何其它的语义约束,即它们在同一个语义层次上是独立的两个实体,则称o1,o2间是一个弱引用 复合对象引用:(
25、composite reference) 复合对象对部分对象的引用具有复杂的语义约束。,复合对象引用的语义分类,依赖/独立 Dependent/Independent专有/共享 Exclusive/Shared它们组合成了四种复合对象的引用语义,依赖专有复合对象引用(最严格的语义引用),语义表示:该引用保证部分对象仅仅可能是一个复合对象的成份一致性约束:部分对象当且仅当它所依赖的一个复合对象存在时才存在,约束的实现 复合对象与部分对象的删除要捆绑进行示例:,1. type computer is body cpu: dependent exclusive processor; ; end ty
26、pe computer; 说明:cpu芯片与某主板共存亡,不被共享 不排除处理器主板上还可以有其他器件,如内存片则不是依赖主板的器件 2. 大楼与大楼内房间的关系,独立 专有复合对象引用,语义表示:部分对象仅与一个复合对象关联,但它有自己的独立性一致性约束:部分对象不允许共享;当主对象删除时,部分对象允许在对象库中独立存在例:,type Automobile is body engine : independent exclusive Motor ; ; end type Automobile;说明:汽车引擎只为一台汽车所专用 引擎可以被复用(由一台汽车转到另一台),依赖 共享复合对象的引用,
27、语义表示:部分对象可以共享,但它仍然是依赖于被关联的复合对象的存在而存在一致性约束:部分对象的删除取决于所有引用它的复合对象的删除示例:,1. type Document is body chapter : dependent shared Chapter; ; end type Document;说明:文档的“章”可以共享,但当所有引用它的章被删除时,“章”的内容也自然不再存在2. 客户档案依赖合同而存在 依赖 一个客户可以签多份合同 共享 当所有合同到期后,该客户也就不再出现,独立 共享复合对象的引用,语义表示:部分对象即是共享的也是独立的(约束最弱)示例:发动机设计图 共享的部分对象可以用在不同的汽车设计中;当汽车型号更新换代了,发动机设计仍然需要保存 type CarDesign is body engineDesign : independent shared MotorDesihn; . end type CarDesign;,