分析模式ORM实现系列——Accountability模式
2006-11-20 09:34
211 查看
本文为分析模式ORM实现系列文章之一。本系列文章使用NBearV3的ORM组件演示Martin Fowler《分析模式——可复用对象模型》一书中列举的可复用分析模型在ORM中的典型实现。本文讨论Accountability模式。
注:本文演示的ORM实现及全部相关源码,基于即将发布的NBearV3正式版实现,该正式版预计在2006年11月内发布。
Accountability模式要解决的问题
在复杂系统中,对象与对象间的关联关系将会非常频繁复杂,参与关联的对象类型可以是人,组织和如合同、职位这样的辅助对象,并且,往往关联关系还有时间约束和其他一些约束规则。例如,员工可以属于一个组织,组织可以由一个人(Leader)负责,人也可以由一个组织负责,人可以有电子邮件,组织也可以有电子邮件等等;再如,对于一个员工属于一个公司这样一个所属关系,它在员工的用工合同有效期间成立,超出合同期限,则失效。
Accountability模式如何解决这样的复杂关联关系对象的建模呢?
首先,因为人、组织或辅助对象可能有一些共性的属性,比如,电子邮件,电话,地址等,并且,这些对象互相之间可以有上下级关联,我们可以首先将所有这些共性抽象出一个Party基类。这样Party一方面可以描述所有对象的共性属性,另一方面,可以将对象间的各种关联关系,转化为Party和Party的有约束的自关联。
接着,因为Party和Party的自关联是有约束的(比如,有效时间约束,上下级关系类型约束等),普通的基于外键关联的1对1、1对多关联无法方便的描述这些约束条件,因此,我们可以引入一个Accoutability对象,专门用来描述一个关联关系。换句话说,一个Accountability对象的实例,描述的是一个二元关联关系,它不仅仅记录关联关系的两端,而且记录关联关系上的约束条件。比较直观的举个例子,它类似我们数据库中常用的带权值的多对多关联,关联关系的约束条件,就相当于权值。
采用这样一个模型,我们就能很清晰的描述人、组织和辅助对象间带约束的各种复杂关联关系,并且,具有良好的可扩展性。
ORM实现
下面,我们使用NBearV3的ORM模块来实现Accountability模式。
在VS2005 IDE的类图中,我们设计描述了该模式模型的如下框图:
我们可以看到,首先,Party基类作为Person,Organization和Post这三类对象的基类。XXXData这样的属性,简单的代表任意的属性。Accoutability用于描述有约束条件的关联关系。它有两个主要的约束条件:一个是BeginTime和EndTime——约束了关联关系的有效时间;第二个是Type——约束了这个关联关系的含义,他关联的对象应该各是什么类型。同时,因为我们抽象了Party作为所有对象的基类来描述各种关系,Accoutability的用于描述关联关系的两端的Responsible和Commissioner属性,都是一个Party。
作为举例,这里还定义了三个Accoutability类型:PersonInOrg代表一个Person在一个Org里;PersonLeadOrg代表Person领导一个Org;PersonOwnPost代表Person拥有的Post。注意,此时,Person的InOrg属性,OwnedPost属性和Organization的OrgLeader属性的类型都是一个Accoutability,因为该属性不仅指定了关联的对象,还包含了关联的约束条件。
Oranization本身的上下级关联,如果没有约束条件的话,我们可以直接采用自关联来描述。
下面,您就能看到使用NBear来实现该模型的ORM映射的优势,因为NBear直接基于模型来设计实体关系,我们只需要在以上的模型的对象上,设置描述关联及约束的条件,就能完成所有的OR映射工作,不需要手动写任何XML配置文件,设置几个Attribute就行了。
我们为所有的实体对象设置如下的Attribute:
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
5
using NBear.Common.Design;
6
7
namespace AnalysisPatterns.Accountability
8
{
9
public interface Party : Entity
10
{
11
[PrimaryKey]
12
int ID
13
{
14
get;
15
}
16
17
[SqlType("ntext")]
18
string PartyData
19
{
20
get;
21
set;
22
}
23
}
24
25
public interface Person : Party
26
{
27
[SqlType("ntext")]
28
string PersonData
29
{
30
get;
31
set;
32
}
33
34
[FkQuery("Commissioner", AdditionalWhere="getdate() >= {BeginTime} AND getdate() < {EndTime} AND {Type} = 1")]
35
Accoutability InOrg
36
{
37
get;
38
set;
39
}
40
41
[FkQuery("Responsible", AdditionalWhere = "getdate() >= {BeginTime} AND getdate() < {EndTime} AND {Type} = 3")]
42
Accoutability OwnedPost
43
{
44
get;
45
set;
46
}
47
}
48
49
public interface Organization : Party
50
{
51
[SqlType("ntext")]
52
string OrgData
53
{
54
get;
55
set;
56
}
57
58
[FkReverseQuery]
59
Organization ParentOrg
60
{
61
get;
62
set;
63
}
64
65
[FkQuery("ParentOrg")]
66
Organization[] ChildOrgs
67
{
68
get;
69
set;
70
}
71
72
[FkQuery("Responsible", AdditionalWhere = "getdate() >= {BeginTime} AND getdate() < {EndTime} AND {Type} = 2")]
73
Accountability OrgLeader
74
{
75
get;
76
set;
77
}
78
}
79
80
public interface Post : Party
81
{
82
[SqlType("ntext")]
83
string PostData
84
{
85
get;
86
set;
87
}
88
}
89
90
public interface Accountability : Entity
91
{
92
DateTime BeginTime
93
{
94
get;
95
set;
96
}
97
98
DateTime EndTime
99
{
100
get;
101
set;
102
}
103
104
[PrimaryKey]
105
int ID
106
{
107
get;
108
}
109
110
AccountabilityType Type
111
{
112
get;
113
set;
114
}
115
116
[FkReverseQuery]
117
Party Commissioner
118
{
119
get;
120
set;
121
}
122
123
[FkReverseQuery]
124
Party Responsible
125
{
126
get;
127
set;
128
}
129
}
130
131
public enum AccountabilityType
132
{
133
PersonInOrg = 1,
134
PersonLeadOrg = 2,
135
PersonOwnPost = 3,
136
OtherTypes = 4,
137
}
138
}
您可以注意到,Person的InOrg属性,OwnedPost属性和Organization的OrgLeader属性的Attribute中,描述了读取关联属性时的约束条件。其他Attribute的含义,请参考NBearV3——ORM实体关系设计速查手册。
设置完以上的实体关系和Attribute,就可以使用NBear提供的NBear.Tools.EntityDesignToEntity.exe工具,生成全部的数据库创建脚本和实体代码了。你接下来的所有精力就只需要关注您的业务逻辑,而无需担心ORM过程的细节了。
//正文结束
//本文结束
注:本文演示的ORM实现及全部相关源码,基于即将发布的NBearV3正式版实现,该正式版预计在2006年11月内发布。
Accountability模式要解决的问题
在复杂系统中,对象与对象间的关联关系将会非常频繁复杂,参与关联的对象类型可以是人,组织和如合同、职位这样的辅助对象,并且,往往关联关系还有时间约束和其他一些约束规则。例如,员工可以属于一个组织,组织可以由一个人(Leader)负责,人也可以由一个组织负责,人可以有电子邮件,组织也可以有电子邮件等等;再如,对于一个员工属于一个公司这样一个所属关系,它在员工的用工合同有效期间成立,超出合同期限,则失效。
Accountability模式如何解决这样的复杂关联关系对象的建模呢?
首先,因为人、组织或辅助对象可能有一些共性的属性,比如,电子邮件,电话,地址等,并且,这些对象互相之间可以有上下级关联,我们可以首先将所有这些共性抽象出一个Party基类。这样Party一方面可以描述所有对象的共性属性,另一方面,可以将对象间的各种关联关系,转化为Party和Party的有约束的自关联。
接着,因为Party和Party的自关联是有约束的(比如,有效时间约束,上下级关系类型约束等),普通的基于外键关联的1对1、1对多关联无法方便的描述这些约束条件,因此,我们可以引入一个Accoutability对象,专门用来描述一个关联关系。换句话说,一个Accountability对象的实例,描述的是一个二元关联关系,它不仅仅记录关联关系的两端,而且记录关联关系上的约束条件。比较直观的举个例子,它类似我们数据库中常用的带权值的多对多关联,关联关系的约束条件,就相当于权值。
采用这样一个模型,我们就能很清晰的描述人、组织和辅助对象间带约束的各种复杂关联关系,并且,具有良好的可扩展性。
ORM实现
下面,我们使用NBearV3的ORM模块来实现Accountability模式。
在VS2005 IDE的类图中,我们设计描述了该模式模型的如下框图:
我们可以看到,首先,Party基类作为Person,Organization和Post这三类对象的基类。XXXData这样的属性,简单的代表任意的属性。Accoutability用于描述有约束条件的关联关系。它有两个主要的约束条件:一个是BeginTime和EndTime——约束了关联关系的有效时间;第二个是Type——约束了这个关联关系的含义,他关联的对象应该各是什么类型。同时,因为我们抽象了Party作为所有对象的基类来描述各种关系,Accoutability的用于描述关联关系的两端的Responsible和Commissioner属性,都是一个Party。
作为举例,这里还定义了三个Accoutability类型:PersonInOrg代表一个Person在一个Org里;PersonLeadOrg代表Person领导一个Org;PersonOwnPost代表Person拥有的Post。注意,此时,Person的InOrg属性,OwnedPost属性和Organization的OrgLeader属性的类型都是一个Accoutability,因为该属性不仅指定了关联的对象,还包含了关联的约束条件。
Oranization本身的上下级关联,如果没有约束条件的话,我们可以直接采用自关联来描述。
下面,您就能看到使用NBear来实现该模型的ORM映射的优势,因为NBear直接基于模型来设计实体关系,我们只需要在以上的模型的对象上,设置描述关联及约束的条件,就能完成所有的OR映射工作,不需要手动写任何XML配置文件,设置几个Attribute就行了。
我们为所有的实体对象设置如下的Attribute:
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
5
using NBear.Common.Design;
6
7
namespace AnalysisPatterns.Accountability
8
{
9
public interface Party : Entity
10
{
11
[PrimaryKey]
12
int ID
13
{
14
get;
15
}
16
17
[SqlType("ntext")]
18
string PartyData
19
{
20
get;
21
set;
22
}
23
}
24
25
public interface Person : Party
26
{
27
[SqlType("ntext")]
28
string PersonData
29
{
30
get;
31
set;
32
}
33
34
[FkQuery("Commissioner", AdditionalWhere="getdate() >= {BeginTime} AND getdate() < {EndTime} AND {Type} = 1")]
35
Accoutability InOrg
36
{
37
get;
38
set;
39
}
40
41
[FkQuery("Responsible", AdditionalWhere = "getdate() >= {BeginTime} AND getdate() < {EndTime} AND {Type} = 3")]
42
Accoutability OwnedPost
43
{
44
get;
45
set;
46
}
47
}
48
49
public interface Organization : Party
50
{
51
[SqlType("ntext")]
52
string OrgData
53
{
54
get;
55
set;
56
}
57
58
[FkReverseQuery]
59
Organization ParentOrg
60
{
61
get;
62
set;
63
}
64
65
[FkQuery("ParentOrg")]
66
Organization[] ChildOrgs
67
{
68
get;
69
set;
70
}
71
72
[FkQuery("Responsible", AdditionalWhere = "getdate() >= {BeginTime} AND getdate() < {EndTime} AND {Type} = 2")]
73
Accountability OrgLeader
74
{
75
get;
76
set;
77
}
78
}
79
80
public interface Post : Party
81
{
82
[SqlType("ntext")]
83
string PostData
84
{
85
get;
86
set;
87
}
88
}
89
90
public interface Accountability : Entity
91
{
92
DateTime BeginTime
93
{
94
get;
95
set;
96
}
97
98
DateTime EndTime
99
{
100
get;
101
set;
102
}
103
104
[PrimaryKey]
105
int ID
106
{
107
get;
108
}
109
110
AccountabilityType Type
111
{
112
get;
113
set;
114
}
115
116
[FkReverseQuery]
117
Party Commissioner
118
{
119
get;
120
set;
121
}
122
123
[FkReverseQuery]
124
Party Responsible
125
{
126
get;
127
set;
128
}
129
}
130
131
public enum AccountabilityType
132
{
133
PersonInOrg = 1,
134
PersonLeadOrg = 2,
135
PersonOwnPost = 3,
136
OtherTypes = 4,
137
}
138
}
您可以注意到,Person的InOrg属性,OwnedPost属性和Organization的OrgLeader属性的Attribute中,描述了读取关联属性时的约束条件。其他Attribute的含义,请参考NBearV3——ORM实体关系设计速查手册。
设置完以上的实体关系和Attribute,就可以使用NBear提供的NBear.Tools.EntityDesignToEntity.exe工具,生成全部的数据库创建脚本和实体代码了。你接下来的所有精力就只需要关注您的业务逻辑,而无需担心ORM过程的细节了。
//正文结束
//本文结束
相关文章推荐
- BlogEngine.Net架构与源代码分析系列part3:数据存储——基于Provider模式的实现
- BlogEngine.Net架构与源代码分析系列part3:数据存储——基于Provider模式的实现
- BlogEngine.Net架构与源代码分析系列part3:数据存储——基于Provider模式的实现
- BlogEngine.Net架构与源代码分析系列part3:数据存储——基于Provider模式的实现
- C#基础系列:实现自己的ORM(MiniORM的测试代码)
- 依赖注入(Dependency Injection)模式的特点分析与实现
- TCP/IP协议栈源码图解分析系列10:linux内核协议栈中对于socket相关API的实现
- 图像特征算子系列之灰度共生矩阵原理分析与实现
- Entity Framework技术系列之2:三种开发模式实现数据访问
- 设计模式系列6-----C++实现状态模式(State Pattern)
- 深入列表遍历问题,并分析spring和tomcat中观察者模式的实现
- 三种工厂模式的分析以及C++实现
- 分析模式系列读书笔记
- 设计模式之模板方法模式 c++实现和详细分析
- 用Java实现的设计模式系列(1)-Factory
- SaaS系列介绍之九: SaaS营销模式分析
- 【Java 并发系列】深入分析Volatile的实现原理
- 【iOS系列】-单例模式的实现
- C#基础系列:实现自己的ORM(ORM的基础概念)
- C#基础系列:实现自己的ORM(ORM的基础概念)