对象关系的设计及C++实现规则.doc_第1页
对象关系的设计及C++实现规则.doc_第2页
对象关系的设计及C++实现规则.doc_第3页
对象关系的设计及C++实现规则.doc_第4页
对象关系的设计及C++实现规则.doc_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

对象关系的设计及C+实现规则一:设计时可以使用的关系1、继承2、关联3、包含二:关联和包含(聚集)关系的设计约束1、对于关联关系可以使用一对一、一对多、多对多;2、对于包含关系可以使用一对一、一对多;3、对于关联关系可以使用双向导航,也可以使用单向导航;4、对于包含关系可以使用双向导航,也可以使用从整体到部分的单向导航;5、对于关联和包含,可导航端(ROLE)必须命名,非导航端不要命名;6、对于关联关系,单向导航适用于在运行过程中导航端保持不变的类。如下图中的关联(1-N),如果A-B之间的关联经常发生变化,特别是B的实例被删除的情况,将有可能导致没有通知A,最终发生非法引用的情况;当然如果不使用引用来标示则是允许的(如通过关键域值来标示对端),但要记住标示可能会代表一个无效的关联。7、对于包含关系,只允许从整体端到部分端的单向导航,并且要保证所有对于部分端的删除操作都是通过整体端来实现的;8、尽量不使用多重继承。三:对于关联和包含关系的实现:无论是关联关系还是包含关系,关系的两端可以分别作为对端的属性,该属性具有私有的属性,对类外部提供包括查找、遍历的函数接口;如图中,A类有一个roleB的属性,B类有一个roleA的属性。1、对于关联,一端的实现方式可以是引用(指针),多端的实现方式可以是引用链表、引用数组或hash表。2、对于包含,包含关系的整体端(A)的实现方式可以是引用(如上图包含关系中,B中有一个pRoleA的属性)。包含关系的部分端(B)如果是一端的,实现方式可以是引用,或者直接是值(A类直接包含一个B的实例),如果是多端的则可以通过引用链表、引用数据或hash表来实现。3、无论是关联还是包含关系,对于一端如果使用指针方式,建议角色命名的时候前缀为p,否则不带前缀。对于多端,则通过后缀表示实现方式,带List后缀表示使用链表实现,带Array后缀表示使用数组实现,带Map后缀表示使用hash表实现。对于通过Map方式实现的需要有关键值的说明。4、对于某些特殊情况,如果不能够通过引用实现,可以通过关键域值方式实现,表示方法如上图。在使用关键域值的时候要保证关键域值的唯一性(一个关键域值只能与唯一一个实例对应,包含B实例的容器类要提供基于关键域值查找实例的查找方法)。但要注意一点,如果B的实例是可以动态创建并删除的,有可能发生通过关键域值无法找到对应的实例的情况。普通关联关系的实现规则1、一对一双向导航关联实现规则ClassAClassB关系名称:RelationAB角色A名称: RoleA角色B名称 :RoleB定义如下:ClassAprivate:ClassB* m_pRoleB;public:ClassA()/析构函数指导写法.if( m_pRoleB )m_pRoleB-DisassociateXZAndY(this, FALSE).BOOL AssociateXYAndZ(ClassB* pRoleB,BOOL bDirection=TRUE)/X为关系名称;Y为角色A名称;Z为角色B名称/bDirection表示在执行本端Associate操作是否执行对端的Associate操作/后同此注释ASSERT(pRoleB);if( pRoleB = NULL )return FALSE;if( m_pRoleB )/ 如果有老关系, 要先清除DisassociateXYAndZ(m_pRoleB);m_pRoleB = pRoleB;if (pRoleB)pRoleB-AssociateXZAndY( this, FALSE);return TRUE;BOOL DisassociateXYAndZ(ClassB* pRoleB,BOOL bDirection=TRUE)ASSERT(pRoleB=m_pRoleB);if( m_pRoleB != pRoleB )return FALSE;m_pRoleB = null ;if (bDirection)pRoleB-DisassociateXZAndY(this,FALSE);return TRUE;ClassB* GetZ(void)return m_pRoleB ;ClassBprivate:ClassA* m_pRoleA;public:ClassB()/析构函数指导写法.if( m_pRoleA )m_pRoleA-DisassociateXYAndZ(this, FALSE).BOOL AssociateXZAndY(ClassA* pRoleA,BOOL bDirection=TRUE)ASSERT(pRoleA);if( pRoleA = NULL )return FALSE;If( m_pRoleA )/ 如果有老关系, 要先清除DisassociateXZAndY(m_pRoleA);m_pRoleA = pRoleA;if (pRoleA)pRoleA-AssociateXYAndZ( this, FALSE);return TRUE;BOOL DisassociateXZAndY(ClassA* pRoleA,BOOL bDirection=TRUE)ASSERT(pRoleA=m_pRoleA);if( m_pRoleA != pRoleA )return FALSE;m_pRoleA = null ;if (bDirection)pRoleA-DisassociateXYAndZ(this,FALSE);return TRUE;ClassA* GetY(void)return m_pRoleA ;2、一对多关联规则双向导航ClassAClassB1n一端角色名称:RoleA多端角色名称:RoleB关系名称:RelationAB当关系导航为Array方式时:ClassAprivate:CObArraym_RoleBArray ;public:ClassA()/析构函数指导写法.DisassociateAllXYAndZ().BOOLAssociateXYAndZ(ClassB* pRoleB,BOOL bDirection=TRUE)ASSERT(pRoleB); if( pRoleB = NULL )return FALSE;/这里需要对是否重复添加进行检查if( pRoleB-GetRoleA() = this )return FALSE; /关系已经存在else if( pRoleB-GetRoleA() )pRoleB-GetRoleA()-DisassociateXYAndZ(pRoleB);m_RoleBArray.Add(pRoleB) ;if (bDirection)pRoleB-AssociateXZAndY(this,FALSE);return TRUE ;BOOL DisassociateXYAndZ(ClassB* pRoleB,BOOL bDirection=TRUE)ASSERT(pRoleB); if( pRoleB = NULL )return FALSE;if (pRoleB-GetRoleA() != this)return FALSE;for (int i=0;m_RoleBArray.GetSize();i+)ClassB* pClassB = m_RoleBArray.GetAt(i) ;if (pClassB = pRoleB)m_RoleBArray.RemoveAt(i);if (bDirection)pRoleB-DisassociateXZAndY(this,FALSE);return TRUE;return FALSE;void DisassociateAllXYAndZ()for (int i=0;m_RoleBArray.GetSize();i+)ClassB* pClassB = m_RoleBArray.GetAt(i) ;pRoleB-DisassociateXZAndY(this,FALSE);m_RoleBArray.RemoveAll();int GetZCount(void)return m_RoleBArray.GetSize();ClassB* GetZAt(int nIndex)return m_RoleBArray.GetAt(nIndex);当关系导航为MAP表方式时:ClassAprivate:CMapKeytypeToPtrm_RoleBMap ;/以KeyValue为键值的Map表/注意:CMapKeytypeToPtr要求支持对象的串行化操作,在/MFC类中只有CMapStringToOb和CMapWorkToOb类支持,如果/需要用到别的KeyType的Map表,还需要单独定义其串行化操作/函数以支持对象的串行化public:ClassA()/析构函数指导写法.DisassociateAllXYAndZ().BOOLAssociateXYAndZ(ClassB* pRoleB,BOOL bDirection=TRUE)ASSERT(pRoleB); if( pRoleB = NULL )return FALSE;/这里需要对是否重复添加进行检查if( pRoleB-GetRoleA() = this )return FALSE; /关系已经存在else if( pRoleB-GetRoleA() )pRoleB-GetRoleA()-DisassociateXYAndZ(pRoleB);m_RoleBMap.SetAt(pRoleB-GetKeyValue(), pRoleB) ;if (bDirection)pRoleB-AssociateXZAndY(this,FALSE);return TRUE ;BOOL DisassociateXYAndZ(ClassB* pRoleB,BOOL bDirection=TRUE)ASSERT(pRoleB); if( pRoleB = NULL )return FALSE;if (pRoleB-GetRoleA() != this)return FALSE;if (bDirection)pRoleB-DisassociateXZAndY(this,FALSE);VERIFY(m_RoleBMap.RemoveKey(pRoleB-GetKeyValue() );return TRUE;void DisassociateAllXYAndZ()/清除所有RoleB关系POSITION pos=m_RoleBMap.GetStartPosition();while (pos)KeyType keyValue;ClassB* pRoleB ;m_RoleBMap.GetNextAssoc(pos,keyValue,pRoleB);ASSERT(pRoleB);pRoleB-DisassociateXZAndY(this, FALSE);m_RoleBMap.RemoveAll();/遍历有关的方法定义int GetZCount(void)return m_RoleBMap.GetCount();ClassB* GetZAt(KeyType keyValue)/KeyValue是ClassB中暴露出来可供检索用的值域,ClassB要提供此手段/KeyValue也可以是类的指针类型ClassB* pB=NULL ;m_RoleBMap.Lookup(keyValue,pB) ;return pB ;/取得pRoleB在Map表中的Next元素ClassB* GetNextZ(ClassB* pRoleB)KeyType keyValue;POSITION pos ;ClassB* pB ;if (!pRoleB)/取得第一个元素pos=m_RoleBMap.GetStartPosition();m_RoleBMap.GetNextAssoc(pos, keyValue,pB) ;return pB;pos=m_RoleBMap.GetStartPosition();while (pos)m_RoleBMap.GetNextAssoc(pos,keyValue,pB);if (pB= pRoleB)m_RoleBMap.GetNextAssoc(pos,keyValue,pB);break;if (!pos)return NULL ;return pB;ClassBprivate:ClassA* m_pRoleA;public:ClassB()/析构函数指导写法.if( m_pRoleA )m_pRoleA-DisassociateXYAndZ(this, FALSE).BOOL AssociateXZAndY(ClassA* pRoleA,BOOL bDirection=TRUE)ASSERT(pRoleA);if( pRoleA = NULL )return FALSE;if( m_pRoleA )/ 如果有老关系, 要先清除DisassociateXZAndY(m_pRoleA);m_pRoleA = pRoleA ;if (bDirection)pRoleA-AssociateXYAndZ(this,FALSE);return TRUE;BOOL DisassociateXZAndY(ClassA* pRoleA,BOOL bDirection=TRUE)ASSERT(pRoleA=m_pRoleA);if( m_pRoleA != pRoleA )return FALSE;m_pRoleA = null ;if (bDirection)pRoleA-DisassociateXYAndZ(this,FALSE) ;return TRUE;ClassA* GetY(void)return m_pRoleA ;/注意:GetKeyValue()是个假设的方法,可能实际方法名字不是这样,/但肯定得有这么一个东东,这里的定义是不严格的KeyType GetKeyValue(void)return . ;3、一对一关联规则单向导航ClassAClassB1- 1关系名称:RelationAB角色A名称: RoleA角色B名称: RoleBClassAprivate:ClassB* m_pRoleB;public:BOOL SetZ(ClassB* pRoleB)m_pRoleB = pRoleB ;return TRUE ;ClassB* GetZ(void)return m_pRoleB ;4、一对多关联规则单向导航ClassAClassB 1- n关系名称:Re

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论