动机 :
前一篇 [Application Architecture] : Entity Expansion模式,介绍了一种扩展对象属性数据的模式。本文延续上一篇的动机,介绍一个Entity Profile模式。
Entity Profile模式主要是定义一组,数据对象(Entity)以及边界对象(Repository)的生成、结构、行为模式,用来扩展对象的属性数据。实作这个模式,可以为系统加入增加式程序代码累积的能力。
基础平台 :
结构
参与者
Page Shell
-页面的壳层,可以透过设定数据,动态挂载系统页面的系统。
范例程序
Page Shell依照开发平台的不同,会有不同的选择。 例如以ASP.NET的平台来说,可以直接套用ASP.NET的页面机制,然后再另外建立一个索引页面,用修改索引页面的方式来达成动态挂载系统页面的需求。
基础项目 :
结构
参与者
UserManagePage
-User管理页面,提供新增、修改、删除、查询 User的功能。
-使用例如 Spring.Net、Provider Pattern来反射生成 IUserProfileRepository。
-使用生成的 IUserProfileRepository生成 UserRepository。
-使用 UserRepository新增、修改、删除、查询 User。
UserProfile
-进出系统边界的数据对象。
IUserProfileRepository
-数据对象 UserProfile进出系统边界的接口。
-提供新增、修改、删除、查询等功能。
User
-系统运作使用的数据对象。
-属性数据存放于 UserProfile。
UserRepository
-数据对象 User进出系统边界的接口。
-使用 IUserProfileRepository,处理自数据对象 User取得的 UserProfile。
-提供新增、修改、删除、查询等功能。
范例程序
namespace CLK.EntityProfile
{
public class UserManagePage
{
public void ShowUser()
{
// GetData
IUserProfileRepository userProfileRepository = null; // 使用例如Spring.Net、Provider Pattern来反射生成。(Base专案生成、Ex专案生成,均生成同一个 IUserProfileRepository)
UserRepository userRepository = new UserRepository(userProfileRepository);
IEnumerable<User> userCollection = userRepository.GetAll();
// Show
this.ShowUser(userCollection);
}
private void ShowUser(IEnumerable<User> userCollection)
{
//.....
}
}
public class UserProfile : Dictionary<string, string>
{
public Guid UserID { get; set; }
}
public interface IUserProfileRepository
{
// Methods
void Add(UserProfile item);
void Modify(UserProfile item);
void Remove(Guid id);
UserProfile GetByID(Guid id);
IEnumerable<UserProfile> GetAll();
}
public class User
{
// Properties
protected internal UserProfile Profile { get; private set; }
public Guid UserID
{
get
{
return this.Profile.UserID;
}
set
{
this.Profile.UserID = value;
}
}
public string Name
{
get
{
return Convert.ToString(this.Profile["Name"]);
}
set
{
this.Profile["Name"] = value;
}
}
public string Description
{
get
{
return Convert.ToString(this.Profile["Description"]);
}
set
{
this.Profile["Description"] = value;
}
}
// Constructor
public User()
{
this.Profile = new UserProfile();
this.UserID = Guid.Empty;
this.Name = string.Empty;
this.Description = string.Empty;
}
}
public class UserRepository
{
// Properties
private readonly IUserProfileRepository _userProfileRepository = null;
// Constructor
public UserRepository(IUserProfileRepository userProfileRepository)
{
#region Require
if (userProfileRepository == null) throw new ArgumentNullException();
#endregion
_userProfileRepository = userProfileRepository;
}
// Methods
private User CreateUser(UserProfile userProfile)
{
#region Require
if (userProfile == null) throw new ArgumentNullException();
#endregion
User user = new User();
user.UserID = userProfile.UserID;
foreach (string key in userProfile.Keys)
{
user.Profile.Add(key, userProfile[key]);
}
return user;
}
private UserProfile CreateUserProfile(User user)
{
#region Require
if (user == null) throw new ArgumentNullException();
#endregion
return user.Profile;
}
public void Add(User item)
{
#region Require
if (item == null) throw new ArgumentNullException();
#endregion
_userProfileRepository.Add(this.CreateUserProfile(item));
}
public void Modify(User item)
{
#region Require
if (item == null) throw new ArgumentNullException();
#endregion
_userProfileRepository.Modify(this.CreateUserProfile(item));
}
public void Remove(Guid id)
{
#region Require
if (id == Guid.Empty) throw new ArgumentNullException();
#endregion
_userProfileRepository.Remove(id);
}
public User GetByID(Guid id)
{
#region Require
if (id == Guid.Empty) throw new ArgumentNullException();
#endregion
return this.CreateUser(_userProfileRepository.GetByID(id));
}
public IEnumerable<User> GetAll()
{
List<User> itemCollection = new List<User>();
foreach (UserProfile userProfile in _userProfileRepository.GetAll())
{
itemCollection.Add(this.CreateUser(userProfile));
}
return itemCollection;
}
}
}
扩展专案 :
结构
参与者
ExUserManagePage
-ExUser管理页面,提供新增、修改、删除、查询 User的功能。
-使用例如 Spring.Net、Provider Pattern来反射生成 IUserProfileRepository。
-使用生成的 IUserProfileRepository生成 ExUserRepository。
-使用 ExUserRepository新增、修改、删除、查询 ExUser。
ExUser
-系统运作使用的数据对象。
-属性数据存放于 UserProfile。
ExUserRepository
-数据对象 ExUser进出系统边界的接口。
-使用 IUserProfileRepository,处理自数据对象 ExUser取得的 UserProfile。
-提供新增、修改、删除、查询等功能。
范例程序
namespace CLK.EntityProfile.Expanded
{
public class ExUserManagePage
{
public void ShowExUser()
{
// GetData
IUserProfileRepository userProfileRepository = null; // 使用例如Spring.Net、Provider Pattern来反射生成。(Base专案生成、Ex专案生成,均生成同一个 IUserProfileRepository)
ExUserRepository exUserRepository = new ExUserRepository(userProfileRepository);
IEnumerable<ExUser> exUserCollection = exUserRepository.GetAll();
// Show
this.ShowExUser(exUserCollection);
}
private void ShowExUser(IEnumerable<ExUser> exUserCollection)
{
//.....
}
}
public class ExUser : User
{
// Properties
public string Address
{
get
{
return Convert.ToString(this.Profile["Address"]);
}
set
{
this.Profile["Address"] = value;
}
}
// Constructor
public ExUser()
: base()
{
this.Address = string.Empty;
}
}
public class ExUserRepository
{
// Properties
private readonly IUserProfileRepository _userProfileRepository = null;
// Constructor
public ExUserRepository(IUserProfileRepository userProfileRepository)
{
#region Require
if (userProfileRepository == null) throw new ArgumentNullException();
#endregion
_userProfileRepository = userProfileRepository;
}
// Methods
private ExUser CreateExUser(UserProfile userProfile)
{
#region Require
if (userProfile == null) throw new ArgumentNullException();
#endregion
ExUser exUser = new ExUser();
exUser.UserID = userProfile.UserID;
foreach (string key in userProfile.Keys)
{
exUser.Profile.Add(key, userProfile[key]);
}
return exUser;
}
private UserProfile CreateUserProfile(ExUser exUser)
{
#region Require
if (exUser == null) throw new ArgumentNullException();
#endregion
return exUser.Profile;
}
public void Add(ExUser item)
{
#region Require
if (item == null) throw new ArgumentNullException();
#endregion
_userProfileRepository.Add(this.CreateUserProfile(item));
}
public void Modify(ExUser item)
{
#region Require
if (item == null) throw new ArgumentNullException();
#endregion
_userProfileRepository.Modify(this.CreateUserProfile(item));
}
public void Remove(Guid id)
{
#region Require
if (id == Guid.Empty) throw new ArgumentNullException();
#endregion
_userProfileRepository.Remove(id);
}
public ExUser GetByID(Guid id)
{
#region Require
if (id == Guid.Empty) throw new ArgumentNullException();
#endregion
return this.CreateExUser(_userProfileRepository.GetByID(id));
}
public IEnumerable<ExUser> GetAll()
{
List<ExUser> itemCollection = new List<ExUser>();
foreach (UserProfile userProfile in _userProfileRepository.GetAll())
{
itemCollection.Add(this.CreateExUser(userProfile));
}
return itemCollection;
}
}
}
结语 :
本文范例简单的说就是,基础项目的 User与扩展项目的 ExUser,转为统一的 UserProfile,使用共同的一个IUserProfileRepository进出系统边界。(*UserProfile有各种的实作方法)
本文介绍的Entity Profile模式,扩展了对象的属性数据,但其实可以看成,处理了强行别扩展对象进出系统边界的责任。以此模式为基础发展,理论上可以设计出能无限扩充属性数据的应用系统架构。


