[Architecture Pattern] 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内,有功能却不需要进出边界的服务对象。

 

范例程序

*范例只包含关键片段的程序代码

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
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; }
}
posted @   Clark159  阅读(369)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示