[Architecture] : Context
動機
在設計物件導向應用程式的時候,簡單的分層會將系統分為Presentation Layer(PL)、 Business Logic Layer(BLL)、Data Access Layer(DAL)。但是三層之間的物件生成、依賴注入等等的設計會是一件很複雜的事情。例如:PL物件該怎麼去生成BLL的物件、DAL的物件該怎麼注入BLL。
本文介紹一個簡單的Context模式,用來框出一個物件導向應用程式的架構,讓每一層的物件設計有可循的規範。
結構
參與者
UserReportPage
-使用者介面,呈現使用者資料的報表。
-使用ContextContainer的靜態屬性取得Context。
-使用Context底下掛載的各種View、Repository,來做BLL邊界的資料物件進出。
ContextContainer
-提供Context統一存放的物件。
-使用ContextFactory來生成Context以及底下掛載的各種View、Repository。
ContextFactory
-生成Context以及底下掛載的各種View、Repository。
-使用例如Spring.Net、Provider Pattern來反射生成DAL的各種View、Repository。
Context
-提供掛載的各種Repository,來做BLL邊界的資料物件進出。
User
-進出BLL邊界的資料物件。
IUserRepository
-資料物件進出BLL邊界的介面。
-單純的新增、修改、刪除、查詢。
SqlUserRepository
-資料物件進出BLL邊界的介面IUserRepository的實作。
-依靠ContextFactory生成。
-將資料物件存入SQL資料庫。
*也可實做OracleUserRepository將資料物件存入Oracle資料庫。
OtherService
-BLL內,有功能卻不需要進出邊界的服務物件。
範例程式
*範例只包含關鍵片段的程式碼
public class UserReportPage
{
// Methods
public void ShowAllUser()
{
// 透過BLL邊界取得資料物件
IEnumerable<User> userCollection = ContextContainer.CurrentContext.UserRepository.GetAll();
// Show
this.ShowUser(userCollection);
}
private void ShowUser(IEnumerable<User> userCollection)
{
//.....
}
}
public class ContextContainer
{
// Properties
private static Context _currentContext = null;
public static Context CurrentContext
{
get
{
if (_currentContext == null)
{
ContextFactory contextFactory = new ContextFactory();
_currentContext = contextFactory.CreateContext();
}
return _currentContext;
}
}
}
public class ContextFactory
{
// Methods
public Context CreateContext()
{
IUserRepository userRepository = null; // 使用例如Spring.Net、Provider Pattern來反射生成。
return new Context(userRepository);
}
}
public class Context
{
// Constructor
public Context(IUserRepository userRepository)
{
this.UserRepository = userRepository;
}
// Properties
public IUserRepository UserRepository { get; set; }
}
public interface IUserRepository
{
// Methods
void Add(User item);
void Modify(User item);
void Remove(Guid id);
User GetByID(Guid id);
IEnumerable<User> GetAll();
}
public class User
{
// Properties
public Guid UserID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。