动机 :
前一篇 [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模式,扩展了对象的属性数据,但其实可以看成,处理了强行别扩展对象进出系统边界的责任。以此模式为基础发展,理论上可以设计出能无限扩充属性数据的应用系统架构。