[Architecture] Context

[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; }
}
期許自己
能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。