moklgy's blog moklgy's blog
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 后端文章

    • 技术题
  • .netcore

    • 《asp.netcore》笔记
    • 《设计模式》
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

moklgy docs

全栈初级开发工程师
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 后端文章

    • 技术题
  • .netcore

    • 《asp.netcore》笔记
    • 《设计模式》
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 对象之间的关系
  • SOLID原则
  • 创建型
    • 创建型模式
      • 1. 工厂方法模式
      • 2. 抽象工厂模式
      • 3. 生成器/建造者模式
      • 4. 原型模式
      • 5. 单例模式
  • 结构型
  • 行为型一
  • 行为型二
  • 其他模式与组合使用
  • 《设计模式》
moklgydocs
2025-10-12
目录

创建型

# C#设计模式全面指南

# 创建型模式

# 1. 工厂方法模式

原理:
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类的实例化推迟到子类中进行。

思路:

  1. 创建一个抽象产品类
  2. 创建具体产品类继承抽象产品类
  3. 创建抽象工厂类,定义工厂方法
  4. 创建具体工厂类实现工厂方法

前辈经验:

  • 当你不确定系统将来需要创建什么类型的对象时,工厂方法是理想选择
  • 在需要创建的对象类型较多的情况下,工厂方法可以简化创建过程
  • 遵循"开闭原则",当需要添加新产品时,只需添加新的产品类和对应的工厂类
  • 避免在客户端代码中直接使用new关键字创建对象,减少代码耦合度

业务场景:
电商系统的支付模块,需要支持多种支付方式(支付宝、微信支付、银行卡支付等),且未来可能会增加新的支付方式。

简单实现:

// 抽象产品 - 支付接口
public interface IPayment
{
    bool Pay(decimal amount);
}

// 具体产品 - 支付宝
public class AlipayPayment : IPayment
{
    public bool Pay(decimal amount)
    {
        Console.WriteLine($"使用支付宝支付{amount}元");
        return true;
    }
}

// 具体产品 - 微信支付
public class WeChatPayment : IPayment
{
    public bool Pay(decimal amount)
    {
        Console.WriteLine($"使用微信支付{amount}元");
        return true;
    }
}

// 简单工厂方法
public class PaymentFactory
{
    public static IPayment CreatePayment(string paymentType)
    {
        return paymentType.ToLower() switch
        {
            "alipay" => new AlipayPayment(),
            "wechat" => new WeChatPayment(),
            _ => throw new ArgumentException($"不支持的支付类型: {paymentType}")
        };
    }
}

// 客户端代码
public class Client
{
    public static void Main()
    {
        // 创建并使用支付方式
        IPayment payment = PaymentFactory.CreatePayment("alipay");
        payment.Pay(100.00m);
        
        payment = PaymentFactory.CreatePayment("wechat");
        payment.Pay(200.00m);
    }
}
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

复杂实现:

// 抽象产品 - 支付接口
public interface IPayment
{
    bool Pay(decimal amount);
    bool Refund(decimal amount);
    string GetTransactionInfo();
}

// 具体产品 - 支付宝
public class AlipayPayment : IPayment
{
    public bool Pay(decimal amount)
    {
        Console.WriteLine($"使用支付宝支付{amount}元");
        return true;
    }
    
    public bool Refund(decimal amount)
    {
        Console.WriteLine($"支付宝退款{amount}元");
        return true;
    }
    
    public string GetTransactionInfo()
    {
        return "支付宝交易信息";
    }
}

// 具体产品 - 微信支付
public class WeChatPayment : IPayment
{
    public bool Pay(decimal amount)
    {
        Console.WriteLine($"使用微信支付{amount}元");
        return true;
    }
    
    public bool Refund(decimal amount)
    {
        Console.WriteLine($"微信退款{amount}元");
        return true;
    }
    
    public string GetTransactionInfo()
    {
        return "微信交易信息";
    }
}

// 抽象工厂
public abstract class PaymentFactory
{
    public abstract IPayment CreatePayment();
    
    // 可以提供一些与创建过程相关的公共方法
    public void LogPaymentCreation(string paymentType)
    {
        Console.WriteLine($"创建{paymentType}支付实例");
    }
}

// 具体工厂 - 支付宝工厂
public class AlipayFactory : PaymentFactory
{
    public override IPayment CreatePayment()
    {
        LogPaymentCreation("支付宝");
        return new AlipayPayment();
    }
}

// 具体工厂 - 微信支付工厂
public class WeChatPaymentFactory : PaymentFactory
{
    public override IPayment CreatePayment()
    {
        LogPaymentCreation("微信");
        return new WeChatPayment();
    }
}

// 客户端代码
public class Client
{
    public static void Main()
    {
        // 使用支付宝工厂
        PaymentFactory alipayFactory = new AlipayFactory();
        IPayment alipay = alipayFactory.CreatePayment();
        alipay.Pay(100.00m);
        
        // 使用微信工厂
        PaymentFactory wechatFactory = new WeChatPaymentFactory();
        IPayment wechat = wechatFactory.CreatePayment();
        wechat.Pay(200.00m);
        wechat.Refund(50.00m);
    }
}
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

业务场景结合:

// 支付相关数据传输对象
public class PaymentDTO
{
    public string OrderId { get; set; }
    public decimal Amount { get; set; }
    public string Currency { get; set; }
    public string UserId { get; set; }
    public Dictionary<string, string> AdditionalInfo { get; set; }
}

// 支付结果
public class PaymentResult
{
    public bool Success { get; set; }
    public string TransactionId { get; set; }
    public string Message { get; set; }
    public DateTime PaymentTime { get; set; }
}

// 抽象产品 - 支付接口
public interface IPaymentProvider
{
    PaymentResult ProcessPayment(PaymentDTO paymentData);
    PaymentResult RefundPayment(string transactionId, decimal amount);
    PaymentResult QueryPaymentStatus(string transactionId);
}

// 具体产品 - 支付宝
public class AlipayProvider : IPaymentProvider
{
    private readonly ILogger _logger;
    private readonly IAlipayApiClient _alipayClient;
    
    public AlipayProvider(ILogger logger, IAlipayApiClient alipayClient)
    {
        _logger = logger;
        _alipayClient = alipayClient;
    }
    
    public PaymentResult ProcessPayment(PaymentDTO paymentData)
    {
        try
        {
            _logger.LogInformation($"开始处理支付宝支付,订单ID: {paymentData.OrderId}");
            
            // 调用支付宝API进行支付
            var apiResult = _alipayClient.Pay(paymentData.OrderId, paymentData.Amount, paymentData.AdditionalInfo);
            
            return new PaymentResult
            {
                Success = apiResult.Success,
                TransactionId = apiResult.TransactionId,
                Message = apiResult.Message,
                PaymentTime = DateTime.Now
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"支付宝支付过程中发生错误: {ex.Message}");
            return new PaymentResult
            {
                Success = false,
                Message = $"支付处理失败: {ex.Message}",
                PaymentTime = DateTime.Now
            };
        }
    }
    
    public PaymentResult RefundPayment(string transactionId, decimal amount)
    {
        // 实现退款逻辑
        _logger.LogInformation($"处理支付宝退款,交易ID: {transactionId}, 金额: {amount}");
        var refundResult = _alipayClient.Refund(transactionId, amount);
        
        return new PaymentResult
        {
            Success = refundResult.Success,
            TransactionId = refundResult.RefundId,
            Message = refundResult.Message,
            PaymentTime = DateTime.Now
        };
    }
    
    public PaymentResult QueryPaymentStatus(string transactionId)
    {
        // 查询支付状态
        var statusResult = _alipayClient.QueryStatus(transactionId);
        
        return new PaymentResult
        {
            Success = true,
            TransactionId = transactionId,
            Message = $"支付状态: {statusResult.Status}",
            PaymentTime = statusResult.PaymentTime
        };
    }
}

// 具体产品 - 微信支付
public class WeChatPayProvider : IPaymentProvider
{
    private readonly ILogger _logger;
    private readonly IWeChatPayClient _wechatClient;
    
    public WeChatPayProvider(ILogger logger, IWeChatPayClient wechatClient)
    {
        _logger = logger;
        _wechatClient = wechatClient;
    }
    
    // 类似AlipayProvider的实现,但调用微信支付API
    public PaymentResult ProcessPayment(PaymentDTO paymentData)
    {
        // 微信支付实现...
        _logger.LogInformation($"开始处理微信支付,订单ID: {paymentData.OrderId}");
        var apiResult = _wechatClient.CreatePayment(paymentData.OrderId, paymentData.Amount);
        
        return new PaymentResult
        {
            Success = apiResult.IsSuccessful,
            TransactionId = apiResult.TransactionId,
            Message = apiResult.ResultMessage,
            PaymentTime = DateTime.Now
        };
    }
    
    public PaymentResult RefundPayment(string transactionId, decimal amount)
    {
        // 微信退款实现...
        return new PaymentResult();
    }
    
    public PaymentResult QueryPaymentStatus(string transactionId)
    {
        // 微信查询实现...
        return new PaymentResult();
    }
}

// 抽象工厂
public interface IPaymentProviderFactory
{
    IPaymentProvider CreatePaymentProvider();
}

// 具体工厂 - 支付宝工厂
public class AlipayProviderFactory : IPaymentProviderFactory
{
    private readonly ILogger _logger;
    private readonly IAlipayApiClient _alipayClient;
    
    public AlipayProviderFactory(ILogger logger, IAlipayApiClient alipayClient)
    {
        _logger = logger;
        _alipayClient = alipayClient;
    }
    
    public IPaymentProvider CreatePaymentProvider()
    {
        return new AlipayProvider(_logger, _alipayClient);
    }
}

// 具体工厂 - 微信支付工厂
public class WeChatPayProviderFactory : IPaymentProviderFactory
{
    private readonly ILogger _logger;
    private readonly IWeChatPayClient _wechatClient;
    
    public WeChatPayProviderFactory(ILogger logger, IWeChatPayClient wechatClient)
    {
        _logger = logger;
        _wechatClient = wechatClient;
    }
    
    public IPaymentProvider CreatePaymentProvider()
    {
        return new WeChatPayProvider(_logger, _wechatClient);
    }
}

// 支付服务 - 在实际应用中使用
public class PaymentService
{
    private readonly Dictionary<string, IPaymentProviderFactory> _paymentFactories;
    
    public PaymentService(
        AlipayProviderFactory alipayFactory,
        WeChatPayProviderFactory wechatFactory)
    {
        _paymentFactories = new Dictionary<string, IPaymentProviderFactory>
        {
            { "alipay", alipayFactory },
            { "wechat", wechatFactory }
        };
    }
    
    public PaymentResult ProcessPayment(string paymentMethod, PaymentDTO paymentData)
    {
        if (!_paymentFactories.TryGetValue(paymentMethod.ToLower(), out var factory))
        {
            return new PaymentResult
            {
                Success = false,
                Message = $"不支持的支付方式: {paymentMethod}",
                PaymentTime = DateTime.Now
            };
        }
        
        var paymentProvider = factory.CreatePaymentProvider();
        return paymentProvider.ProcessPayment(paymentData);
    }
    
    // 其他支付相关操作...
}

// 在ASP.NET Core应用中的使用示例(依赖注入)
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // 注册支付相关服务
        services.AddSingleton<IAlipayApiClient, AlipayApiClient>();
        services.AddSingleton<IWeChatPayClient, WeChatPayClient>();
        
        services.AddSingleton<AlipayProviderFactory>();
        services.AddSingleton<WeChatPayProviderFactory>();
        
        services.AddSingleton<PaymentService>();
    }
}

// 控制器示例
[ApiController]
[Route("api/[controller]")]
public class PaymentController : ControllerBase
{
    private readonly PaymentService _paymentService;
    
    public PaymentController(PaymentService paymentService)
    {
        _paymentService = paymentService;
    }
    
    [HttpPost]
    public IActionResult ProcessPayment([FromBody] PaymentRequest request)
    {
        var paymentData = new PaymentDTO
        {
            OrderId = request.OrderId,
            Amount = request.Amount,
            Currency = request.Currency,
            UserId = User.Identity.Name,
            AdditionalInfo = request.AdditionalInfo
        };
        
        var result = _paymentService.ProcessPayment(request.PaymentMethod, paymentData);
        
        if (result.Success)
        {
            return Ok(result);
        }
        
        return BadRequest(result);
    }
}
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266

# 2. 抽象工厂模式

原理:
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式将一组对象的实现细节与他们的一般使用分离开来。

思路:

  1. 创建抽象产品族(多个抽象产品)
  2. 创建具体产品实现类
  3. 创建抽象工厂接口,定义创建不同产品的方法
  4. 创建具体工厂实现类,生产一个产品族的所有产品

前辈经验:

  • 当系统需要处理多个产品族且这些产品族之间有内在联系时,抽象工厂是很好的选择
  • 相比工厂方法,抽象工厂适合处理多个产品系列的情况
  • 使用抽象工厂可以确保客户端只使用同一个产品族中的产品,不会混用
  • 遵循"依赖倒转原则",客户端依赖于抽象而不是具体实现

业务场景:
跨平台UI组件库,需要为不同操作系统(Windows、macOS、Linux)提供一致的UI组件(按钮、文本框、下拉菜单等),但每个平台的具体实现不同。

简单实现:

// 抽象产品 - 按钮
public interface IButton
{
    void Render();
    void HandleClick();
}

// 抽象产品 - 文本框
public interface ITextBox
{
    void Render();
    void HandleInput();
}

// 具体产品 - Windows按钮
public class WindowsButton : IButton
{
    public void Render()
    {
        Console.WriteLine("渲染Windows风格的按钮");
    }
    
    public void HandleClick()
    {
        Console.WriteLine("处理Windows按钮点击事件");
    }
}

// 具体产品 - Windows文本框
public class WindowsTextBox : ITextBox
{
    public void Render()
    {
        Console.WriteLine("渲染Windows风格的文本框");
    }
    
    public void HandleInput()
    {
        Console.WriteLine("处理Windows文本框输入");
    }
}

// 具体产品 - macOS按钮
public class MacOSButton : IButton
{
    public void Render()
    {
        Console.WriteLine("渲染macOS风格的按钮");
    }
    
    public void HandleClick()
    {
        Console.WriteLine("处理macOS按钮点击事件");
    }
}

// 具体产品 - macOS文本框
public class MacOSTextBox : ITextBox
{
    public void Render()
    {
        Console.WriteLine("渲染macOS风格的文本框");
    }
    
    public void HandleInput()
    {
        Console.WriteLine("处理macOS文本框输入");
    }
}

// 抽象工厂
public interface IGUIFactory
{
    IButton CreateButton();
    ITextBox CreateTextBox();
}

// 具体工厂 - Windows
public class WindowsFactory : IGUIFactory
{
    public IButton CreateButton()
    {
        return new WindowsButton();
    }
    
    public ITextBox CreateTextBox()
    {
        return new WindowsTextBox();
    }
}

// 具体工厂 - macOS
public class MacOSFactory : IGUIFactory
{
    public IButton CreateButton()
    {
        return new MacOSButton();
    }
    
    public ITextBox CreateTextBox()
    {
        return new MacOSTextBox();
    }
}

// 客户端代码
public class Application
{
    private readonly IButton _button;
    private readonly ITextBox _textBox;
    
    public Application(IGUIFactory factory)
    {
        _button = factory.CreateButton();
        _textBox = factory.CreateTextBox();
    }
    
    public void RenderUI()
    {
        _button.Render();
        _textBox.Render();
    }
    
    public void HandleUserInteraction()
    {
        _button.HandleClick();
        _textBox.HandleInput();
    }
}

public class Client
{
    public static void Main()
    {
        // 检测操作系统并选择工厂
        IGUIFactory factory;
        string os = GetOperatingSystem(); // 假设有这样一个方法
        
        if (os == "Windows")
        {
            factory = new WindowsFactory();
        }
        else
        {
            factory = new MacOSFactory();
        }
        
        var app = new Application(factory);
        app.RenderUI();
        app.HandleUserInteraction();
    }
    
    private static string GetOperatingSystem()
    {
        // 简化示例,实际应该检测真实操作系统
        return "Windows";
    }
}
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

复杂实现:

// 抽象产品 - 按钮
public interface IButton
{
    void Render();
    void HandleClick();
    bool IsEnabled { get; set; }
    string Label { get; set; }
}

// 抽象产品 - 文本框
public interface ITextBox
{
    void Render();
    void HandleInput();
    string Text { get; set; }
    bool IsReadOnly { get; set; }
}

// 抽象产品 - 下拉菜单
public interface IDropdown
{
    void Render();
    void Select(int index);
    IList<string> Items { get; set; }
    int SelectedIndex { get; set; }
}

// 抽象产品 - 窗口
public interface IWindow
{
    void Show();
    void Close();
    void Minimize();
    void Maximize();
    string Title { get; set; }
}

// Windows实现系列
public class WindowsButton : IButton
{
    public bool IsEnabled { get; set; } = true;
    public string Label { get; set; } = "Button";
    
    public void Render()
    {
        Console.WriteLine($"渲染Windows风格的按钮: {Label}, 状态: {(IsEnabled ? "启用" : "禁用")}");
    }
    
    public void HandleClick()
    {
        if (IsEnabled)
        {
            Console.WriteLine($"处理Windows按钮 '{Label}' 的点击事件");
        }
    }
}

public class WindowsTextBox : ITextBox
{
    public string Text { get; set; } = "";
    public bool IsReadOnly { get; set; } = false;
    
    public void Render()
    {
        Console.WriteLine($"渲染Windows风格的文本框: {(IsReadOnly ? "只读" : "可编辑")}");
    }
    
    public void HandleInput()
    {
        if (!IsReadOnly)
        {
            Console.WriteLine("处理Windows文本框输入");
        }
    }
}

public class WindowsDropdown : IDropdown
{
    public IList<string> Items { get; set; } = new List<string>();
    public int SelectedIndex { get; set; } = -1;
    
    public void Render()
    {
        Console.WriteLine("渲染Windows风格的下拉菜单");
        for (int i = 0; i < Items.Count; i++)
        {
            Console.WriteLine($"  {i}: {Items[i]} {(i == SelectedIndex ? "(selected)" : "")}");
        }
    }
    
    public void Select(int index)
    {
        if (index >= 0 && index < Items.Count)
        {
            SelectedIndex = index;
            Console.WriteLine($"在Windows下拉菜单中选择了: {Items[index]}");
        }
    }
}

public class WindowsWindow : IWindow
{
    public string Title { get; set; } = "Windows Window";
    
    public void Show()
    {
        Console.WriteLine($"显示Windows窗口: {Title}");
    }
    
    public void Close()
    {
        Console.WriteLine($"关闭Windows窗口: {Title}");
    }
    
    public void Minimize()
    {
        Console.WriteLine($"最小化Windows窗口: {Title}");
    }
    
    public void Maximize()
    {
        Console.WriteLine($"最大化Windows窗口: {Title}");
    }
}

// macOS实现系列
public class MacOSButton : IButton
{
    public bool IsEnabled { get; set; } = true;
    public string Label { get; set; } = "Button";
    
    public void Render()
    {
        Console.WriteLine($"渲染macOS风格的按钮: {Label}, 状态: {(IsEnabled ? "启用" : "禁用")}");
    }
    
    public void HandleClick()
    {
        if (IsEnabled)
        {
            Console.WriteLine($"处理macOS按钮 '{Label}' 的点击事件");
        }
    }
}

// 其他macOS组件实现类(省略详细代码)...
public class MacOSTextBox : ITextBox
{
    public string Text { get; set; } = "";
    public bool IsReadOnly { get; set; } = false;
    
    public void Render() { /* 实现细节 */ }
    public void HandleInput() { /* 实现细节 */ }
}

public class MacOSDropdown : IDropdown
{
    public IList<string> Items { get; set; } = new List<string>();
    public int SelectedIndex { get; set; } = -1;
    
    public void Render() { /* 实现细节 */ }
    public void Select(int index) { /* 实现细节 */ }
}

public class MacOSWindow : IWindow
{
    public string Title { get; set; } = "macOS Window";
    
    public void Show() { /* 实现细节 */ }
    public void Close() { /* 实现细节 */ }
    public void Minimize() { /* 实现细节 */ }
    public void Maximize() { /* 实现细节 */ }
}

// Linux实现系列(省略详细代码)...
public class LinuxButton : IButton { /* 实现细节 */ }
public class LinuxTextBox : ITextBox { /* 实现细节 */ }
public class LinuxDropdown : IDropdown { /* 实现细节 */ }
public class LinuxWindow : IWindow { /* 实现细节 */ }

// 抽象工厂
public interface IGUIFactory
{
    IButton CreateButton();
    ITextBox CreateTextBox();
    IDropdown CreateDropdown();
    IWindow CreateWindow();
    string GetPlatformName();
}

// 具体工厂 - Windows
public class WindowsFactory : IGUIFactory
{
    public IButton CreateButton() => new WindowsButton();
    public ITextBox CreateTextBox() => new WindowsTextBox();
    public IDropdown CreateDropdown() => new WindowsDropdown();
    public IWindow CreateWindow() => new WindowsWindow();
    public string GetPlatformName() => "Windows";
}

// 具体工厂 - macOS
public class MacOSFactory : IGUIFactory
{
    public IButton CreateButton() => new MacOSButton();
    public ITextBox CreateTextBox() => new MacOSTextBox();
    public IDropdown CreateDropdown() => new MacOSDropdown();
    public IWindow CreateWindow() => new MacOSWindow();
    public string GetPlatformName() => "macOS";
}

// 具体工厂 - Linux
public class LinuxFactory : IGUIFactory
{
    public IButton CreateButton() => new LinuxButton();
    public ITextBox CreateTextBox() => new LinuxTextBox();
    public IDropdown CreateDropdown() => new LinuxDropdown();
    public IWindow CreateWindow() => new LinuxWindow();
    public string GetPlatformName() => "Linux";
}

// 客户端代码
public class Application
{
    private readonly IGUIFactory _factory;
    private IWindow _mainWindow;
    private IButton _okButton;
    private IButton _cancelButton;
    private ITextBox _inputField;
    private IDropdown _optionsDropdown;
    
    public Application(IGUIFactory factory)
    {
        _factory = factory;
        CreateUI();
    }
    
    private void CreateUI()
    {
        _mainWindow = _factory.CreateWindow();
        _mainWindow.Title = $"{_factory.GetPlatformName()} Application";
        
        _okButton = _factory.CreateButton();
        _okButton.Label = "OK";
        
        _cancelButton = _factory.CreateButton();
        _cancelButton.Label = "Cancel";
        
        _inputField = _factory.CreateTextBox();
        
        _optionsDropdown = _factory.CreateDropdown();
        _optionsDropdown.Items = new List<string> { "Option 1", "Option 2", "Option 3" };
    }
    
    public void Run()
    {
        Console.WriteLine($"Starting application on {_factory.GetPlatformName()}");
        _mainWindow.Show();
        
        // 渲染UI组件
        _okButton.Render();
        _cancelButton.Render();
        _inputField.Render();
        _optionsDropdown.Render();
        
        // 模拟用户交互
        _okButton.HandleClick();
        _inputField.Text = "User input";
        _inputField.HandleInput();
        _optionsDropdown.Select(1);
        
        _mainWindow.Close();
    }
}

// 工厂提供者 - 根据环境创建合适的工厂
public static class GUIFactoryProvider
{
    public static IGUIFactory GetFactory()
    {
        // 检测当前操作系统并返回对应的工厂
        string osName = Environment.OSVersion.Platform.ToString();
        
        if (osName.Contains("Win"))
        {
            return new WindowsFactory();
        }
        else if (osName.Contains("Unix") || osName.Contains("Linux"))
        {
            return new LinuxFactory();
        }
        else if (osName.Contains("Mac"))
        {
            return new MacOSFactory();
        }
        else
        {
            // 默认使用Windows工厂
            return new WindowsFactory();
        }
    }
}

// 程序入口
public class Program
{
    public static void Main()
    {
        // 自动选择合适的工厂
        IGUIFactory factory = GUIFactoryProvider.GetFactory();
        var app = new Application(factory);
        app.Run();
    }
}
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

业务场景结合:

// 假设我们在开发一个支持多数据库的ORM框架
// 抽象产品 - 数据库连接
public interface IDbConnection
{
    bool Open(string connectionString);
    void Close();
    bool IsConnected { get; }
}

// 抽象产品 - 命令对象
public interface IDbCommand
{
    void SetSql(string sql);
    void AddParameter(string name, object value);
    void ClearParameters();
    IDbDataReader ExecuteReader();
    int ExecuteNonQuery();
    object ExecuteScalar();
}

// 抽象产品 - 数据读取器
public interface IDbDataReader
{
    bool Read();
    string GetString(int ordinal);
    int GetInt32(int ordinal);
    decimal GetDecimal(int ordinal);
    DateTime GetDateTime(int ordinal);
    bool IsDBNull(int ordinal);
    void Close();
}

// 抽象产品 - 事务
public interface IDbTransaction
{
    void Begin();
    void Commit();
    void Rollback();
    bool IsActive { get; }
}

// SQL Server实现
public class SqlConnection : IDbConnection
{
    private bool _isConnected;
    
    public bool Open(string connectionString)
    {
        Console.WriteLine($"打开SQL Server连接: {connectionString}");
        _isConnected = true;
        return true;
    }
    
    public void Close()
    {
        Console.WriteLine("关闭SQL Server连接");
        _isConnected = false;
    }
    
    public bool IsConnected => _isConnected;
}

public class SqlCommand : IDbCommand
{
    private string _sql;
    private Dictionary<string, object> _parameters = new Dictionary<string, object>();
    
    public void SetSql(string sql)
    {
        _sql = sql;
        Console.WriteLine($"SQL Server命令: {sql}");
    }
    
    public void AddParameter(string name, object value)
    {
        _parameters[name] = value;
        Console.WriteLine($"添加SQL Server参数: {name} = {value}");
    }
    
    public void ClearParameters()
    {
        _parameters.Clear();
        Console.WriteLine("清除SQL Server参数");
    }
    
    public IDbDataReader ExecuteReader()
    {
        Console.WriteLine($"执行SQL Server查询: {_sql}");
        return new SqlDataReader();
    }
    
    public int ExecuteNonQuery()
    {
        Console.WriteLine($"执行SQL Server非查询命令: {_sql}");
        return 1; // 假设影响了1行
    }
    
    public object ExecuteScalar()
    {
        Console.WriteLine($"执行SQL Server标量查询: {_sql}");
        return 0; // 假设返回0
    }
}

public class SqlDataReader : IDbDataReader
{
    private bool _hasMoreRows = true;
    private int _currentRow = -1;
    
    // 模拟数据
    private readonly List<Dictionary<int, object>> _data = new List<Dictionary<int, object>>
    {
        new Dictionary<int, object> { { 0, 1 }, { 1, "Row 1" }, { 2, 10.5m }, { 3, DateTime.Now } },
        new Dictionary<int, object> { { 0, 2 }, { 1, "Row 2" }, { 2, 20.5m }, { 3, DateTime.Now.AddDays(1) } }
    };
    
    public bool Read()
    {
        if (_currentRow < _data.Count - 1)
        {
            _currentRow++;
            return true;
        }
        
        _hasMoreRows = false;
        return false;
    }
    
    public string GetString(int ordinal) => _data[_currentRow][ordinal].ToString();
    public int GetInt32(int ordinal) => (int)_data[_currentRow][ordinal];
    public decimal GetDecimal(int ordinal) => (decimal)_data[_currentRow][ordinal];
    public DateTime GetDateTime(int ordinal) => (DateTime)_data[_currentRow][ordinal];
    public bool IsDBNull(int ordinal) => _data[_currentRow][ordinal] == null;
    
    public void Close()
    {
        Console.WriteLine("关闭SQL Server数据读取器");
    }
}

public class SqlTransaction : IDbTransaction
{
    private bool _isActive;
    
    public void Begin()
    {
        Console.WriteLine("开始SQL Server事务");
        _isActive = true;
    }
    
    public void Commit()
    {
        Console.WriteLine("提交SQL Server事务");
        _isActive = false;
    }
    
    public void Rollback()
    {
        Console.WriteLine("回滚SQL Server事务");
        _isActive = false;
    }
    
    public bool IsActive => _isActive;
}

// MySQL实现 - 类似地实现其他数据库产品
public class MySqlConnection : IDbConnection { /* 实现细节 */ }
public class MySqlCommand : IDbCommand { /* 实现细节 */ }
public class MySqlDataReader : IDbDataReader { /* 实现细节 */ }
public class MySqlTransaction : IDbTransaction { /* 实现细节 */ }

// PostgreSQL实现
public class PostgreSqlConnection : IDbConnection { /* 实现细节 */ }
public class PostgreSqlCommand : IDbCommand { /* 实现细节 */ }
public class PostgreSqlDataReader : IDbDataReader { /* 实现细节 */ }
public class PostgreSqlTransaction : IDbTransaction { /* 实现细节 */ }

// 抽象工厂
public interface IDatabaseFactory
{
    IDbConnection CreateConnection();
    IDbCommand CreateCommand();
    IDbTransaction CreateTransaction();
    string GetProviderName();
}

// 具体工厂 - SQL Server
public class SqlServerFactory : IDatabaseFactory
{
    public IDbConnection CreateConnection() => new SqlConnection();
    public IDbCommand CreateCommand() => new SqlCommand();
    public IDbTransaction CreateTransaction() => new SqlTransaction();
    public string GetProviderName() => "SQL Server";
}

// 具体工厂 - MySQL
public class MySqlFactory : IDatabaseFactory
{
    public IDbConnection CreateConnection() => new MySqlConnection();
    public IDbCommand CreateCommand() => new MySqlCommand();
    public IDbTransaction CreateTransaction() => new MySqlTransaction();
    public string GetProviderName() => "MySQL";
}

// 具体工厂 - PostgreSQL
public class PostgreSqlFactory : IDatabaseFactory
{
    public IDbConnection CreateConnection() => new PostgreSqlConnection();
    public IDbCommand CreateCommand() => new PostgreSqlCommand();
    public IDbTransaction CreateTransaction() => new PostgreSqlTransaction();
    public string GetProviderName() => "PostgreSQL";
}

// 数据访问层
public class DataAccess
{
    private readonly IDatabaseFactory _dbFactory;
    private readonly string _connectionString;
    
    public DataAccess(IDatabaseFactory dbFactory, string connectionString)
    {
        _dbFactory = dbFactory;
        _connectionString = connectionString;
    }
    
    // 查询示例
    public List<Customer> GetCustomers()
    {
        var customers = new List<Customer>();
        var connection = _dbFactory.CreateConnection();
        
        try
        {
            connection.Open(_connectionString);
            
            var command = _dbFactory.CreateCommand();
            command.SetSql("SELECT Id, Name, Balance, RegistrationDate FROM Customers");
            
            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    customers.Add(new Customer
                    {
                        Id = reader.GetInt32(0),
                        Name = reader.GetString(1),
                        Balance = reader.GetDecimal(2),
                        RegistrationDate = reader.GetDateTime(3)
                    });
                }
                
                reader.Close();
            }
        }
        finally
        {
            if (connection.IsConnected)
            {
                connection.Close();
            }
        }
        
        return customers;
    }
    
    // 事务示例
    public bool TransferMoney(int fromAccountId, int toAccountId, decimal amount)
    {
        var connection = _dbFactory.CreateConnection();
        IDbTransaction transaction = null;
        
        try
        {
            connection.Open(_connectionString);
            transaction = _dbFactory.CreateTransaction();
            transaction.Begin();
            
            var command = _dbFactory.CreateCommand();
            
            // 扣减源账户
            command.SetSql("UPDATE Accounts SET Balance = Balance - @Amount WHERE Id = @FromId");
            command.AddParameter("@Amount", amount);
            command.AddParameter("@FromId", fromAccountId);
            command.ExecuteNonQuery();
            
            // 增加目标账户
            command.ClearParameters();
            command.SetSql("UPDATE Accounts SET Balance = Balance + @Amount WHERE Id = @ToId");
            command.AddParameter("@Amount", amount);
            command.AddParameter("@ToId", toAccountId);
            command.ExecuteNonQuery();
            
            transaction.Commit();
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"转账失败: {ex.Message}");
            transaction?.Rollback();
            return false;
        }
        finally
        {
            if (connection.IsConnected)
            {
                connection.Close();
            }
        }
    }
}

// 实体类
public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Balance { get; set; }
    public DateTime RegistrationDate { get; set; }
}

// 在ASP.NET Core应用中使用
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // 从配置读取数据库类型
        string dbType = Configuration["DatabaseType"]; // 例如:"SqlServer", "MySQL", "PostgreSQL"
        string connectionString = Configuration.GetConnectionString("DefaultConnection");
        
        // 根据配置注册合适的工厂
        IDatabaseFactory databaseFactory = dbType.ToLower() switch
        {
            "sqlserver" => new SqlServerFactory(),
            "mysql" => new MySqlFactory(),
            "postgresql" => new PostgreSqlFactory(),
            _ => throw new ArgumentException($"不支持的数据库类型: {dbType}")
        };
        
        services.AddSingleton(databaseFactory);
        services.AddSingleton(provider => new DataAccess(
            provider.GetRequiredService<IDatabaseFactory>(),
            connectionString));
        
        // 注册其他服务...
    }
}

// 控制器示例
[ApiController]
[Route("api/[controller]")]
public class CustomersController : ControllerBase
{
    private readonly DataAccess _dataAccess;
    
    public CustomersController(DataAccess dataAccess)
    {
        _dataAccess = dataAccess;
    }
    
    [HttpGet]
    public ActionResult<IEnumerable<Customer>> GetCustomers()
    {
        try
        {
            var customers = _dataAccess.GetCustomers();
            return Ok(customers);
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"Internal server error: {ex.Message}");
        }
    }
    
    [HttpPost("transfer")]
    public ActionResult TransferMoney([FromBody] TransferRequest request)
    {
        if (request.Amount <= 0)
        {
            return BadRequest("转账金额必须大于零");
        }
        
        bool success = _dataAccess.TransferMoney(
            request.FromAccountId,
            request.ToAccountId,
            request.Amount);
            
        if (success)
        {
            return Ok(new { Message = "转账成功" });
        }
        else
        {
            return StatusCode(500, "转账失败,请查看日志了解详情");
        }
    }
}

public class TransferRequest
{
    public int FromAccountId { get; set; }
    public int ToAccountId { get; set; }
    public decimal Amount { get; set; }
}
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403

# 3. 生成器/建造者模式

原理:
建造者模式将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。它允许用户在不知道内部构建细节的情况下构建复杂对象。

思路:

  1. 创建一个产品类,包含多个组成部分
  2. 创建抽象建造者类,定义创建产品各个部分的抽象方法
  3. 创建具体建造者类,实现抽象方法
  4. 创建指挥者类,控制产品的创建过程

前辈经验:

  • 当创建复杂对象的算法应该独立于组成对象的部件及其装配方式时,使用建造者模式
  • 适用于构造过程复杂、需要多个步骤才能完成的对象创建
  • 可以避免"重叠构造函数"问题,使客户端代码更加清晰
  • 符合"单一职责原则",将复杂构造逻辑封装在建造者类中

业务场景:
订单系统中,需要创建包含多个部分的复杂订单文档(标题、客户信息、商品列表、支付信息、发票信息等)。

简单实现:

// 产品类 - 订单文档
public class OrderDocument
{
    public string Header { get; set; }
    public string CustomerInfo { get; set; }
    public string ProductList { get; set; }
    public string PaymentInfo { get; set; }
    public string Footer { get; set; }
    
    public void Display()
    {
        Console.WriteLine("订单文档:");
        Console.WriteLine($"头部: {Header}");
        Console.WriteLine($"客户信息: {CustomerInfo}");
        Console.WriteLine($"产品列表: {ProductList}");
        Console.WriteLine($"支付信息: {PaymentInfo}");
        Console.WriteLine($"页脚: {Footer}");
    }
}

// 建造者接口
public interface IOrderBuilder
{
    void BuildHeader();
    void BuildCustomerInfo();
    void BuildProductList();
    void BuildPaymentInfo();
    void BuildFooter();
    OrderDocument GetDocument();
}

// 具体建造者 - 标准订单
public class StandardOrderBuilder : IOrderBuilder
{
    private OrderDocument _document = new OrderDocument();
    
    public void BuildHeader()
    {
        _document.Header = "标准订单";
    }
    
    public void BuildCustomerInfo()
    {
        _document.CustomerInfo = "客户详细信息...";
    }
    
    public void BuildProductList()
    {
        _document.ProductList = "产品列表...";
    }
    
    public void BuildPaymentInfo()
    {
        _document.PaymentInfo = "支付信息...";
    }
    
    public void BuildFooter()
    {
        _document.Footer = "标准订单页脚";
    }
    
    public OrderDocument GetDocument()
    {
        return _document;
    }
}

// 具体建造者 - 高级订单
public class PremiumOrderBuilder : IOrderBuilder
{
    private OrderDocument _document = new OrderDocument();
    
    public void BuildHeader()
    {
        _document.Header = "高级订单 - 优先处理";
    }
    
    public void BuildCustomerInfo()
    {
        _document.CustomerInfo = "VIP客户详细信息...";
    }
    
    public void BuildProductList()
    {
        _document.ProductList = "高级产品列表,包含优惠信息...";
    }
    
    public void BuildPaymentInfo()
    {
        _document.PaymentInfo = "VIP支付通道信息...";
    }
    
    public void BuildFooter()
    {
        _document.Footer = "高级订单页脚,包含客户服务信息";
    }
    
    public OrderDocument GetDocument()
    {
        return _document;
    }
}

// 指挥者
public class OrderDirector
{
    public OrderDocument Construct(IOrderBuilder builder)
    {
        builder.BuildHeader();
        builder.BuildCustomerInfo();
        builder.BuildProductList();
        builder.BuildPaymentInfo();
        builder.BuildFooter();
        
        return builder.GetDocument();
    }
}

// 客户端代码
public class Client
{
    public static void Main()
    {
        OrderDirector director = new OrderDirector();
        
        // 创建标准订单文档
        IOrderBuilder standardBuilder = new StandardOrderBuilder();
        OrderDocument standardOrder = director.Construct(standardBuilder);
        standardOrder.Display();
        
        Console.WriteLine();
        
        // 创建高级订单文档
        IOrderBuilder premiumBuilder = new PremiumOrderBuilder();
        OrderDocument premiumOrder = director.Construct(premiumBuilder);
        premiumOrder.Display();
    }
}
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

复杂实现:

// 产品类 - 复杂订单
public class Order
{
    // 订单基本信息
    public string OrderId { get; set; }
    public DateTime OrderDate { get; set; }
    public string Status { get; set; }
    
    // 客户信息
    public CustomerInfo Customer { get; set; }
    
    // 产品列表
    public List<OrderItem> Items { get; set; } = new List<OrderItem>();
    
    // 地址信息
    public Address BillingAddress { get; set; }
    public Address ShippingAddress { get; set; }
    
    // 支付相关
    public PaymentInfo Payment { get; set; }
    
    // 配送相关
    public ShippingInfo Shipping { get; set; }
    
    // 折扣信息
    public List<Discount> Discounts { get; set; } = new List<Discount>();
    
    // 税费信息
    public TaxInfo Tax { get; set; }
    
    // 计算总价
    public decimal CalculateTotal()
    {
        decimal subtotal = Items.Sum(item => item.Price * item.Quantity);
        decimal discountAmount = Discounts.Sum(d => d.Amount);
        decimal taxAmount = Tax?.Amount ?? 0;
        decimal shippingCost = Shipping?.Cost ?? 0;
        
        return subtotal - discountAmount + taxAmount + shippingCost;
    }
    
    public void Display()
    {
        Console.WriteLine($"订单ID: {OrderId}");
        Console.WriteLine($"订单日期: {OrderDate}");
        Console.WriteLine($"状态: {Status}");
        
        Console.WriteLine("\n客户信息:");
        Customer?.Display();
        
        Console.WriteLine("\n账单地址:");
        BillingAddress?.Display();
        
        Console.WriteLine("\n配送地址:");
        ShippingAddress?.Display();
        
        Console.WriteLine("\n订单项目:");
        foreach (var item in Items)
        {
            item.Display();
        }
        
        Console.WriteLine("\n折扣:");
        foreach (var discount in Discounts)
        {
            discount.Display();
        }
        
        Console.WriteLine("\n支付信息:");
        Payment?.Display();
        
        Console.WriteLine("\n配送信息:");
        Shipping?.Display();
        
        Console.WriteLine("\n税费信息:");
        Tax?.Display();
        
        Console.WriteLine($"\n订单总金额: {CalculateTotal():C}");
    }
}

// 辅助类
public class CustomerInfo
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    
    public void Display()
    {
        Console.WriteLine($"  ID: {Id}");
        Console.WriteLine($"  姓名: {Name}");
        Console.WriteLine($"  邮箱: {Email}");
        Console.WriteLine($"  电话: {Phone}");
    }
}

public class Address
{
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string Country { get; set; }
    
    public void Display()
    {
        Console.WriteLine($"  {Line1}");
        if (!string.IsNullOrEmpty(Line2))
            Console.WriteLine($"  {Line2}");
        Console.WriteLine($"  {City}, {State} {ZipCode}");
        Console.WriteLine($"  {Country}");
    }
}

public class OrderItem
{
    public string ProductId { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public int Quantity { get; set; }
    
    public void Display()
    {
        Console.WriteLine($"  {ProductId} - {Name} x {Quantity} @ {Price:C} = {Price * Quantity:C}");
    }
}

public class PaymentInfo
{
    public string Method { get; set; }
    public string TransactionId { get; set; }
    public DateTime PaymentDate { get; set; }
    public decimal Amount { get; set; }
    public string Status { get; set; }
    
    public void Display()
    {
        Console.WriteLine($"  方式: {Method}");
        Console.WriteLine($"  交易ID: {TransactionId}");
        Console.WriteLine($"  日期: {PaymentDate}");
        Console.WriteLine($"  金额: {Amount:C}");
        Console.WriteLine($"  状态: {Status}");
    }
}

public class ShippingInfo
{
    public string Method { get; set; }
    public string TrackingNumber { get; set; }
    public DateTime EstimatedDelivery { get; set; }
    public decimal Cost { get; set; }
    
    public void Display()
    {
        Console.WriteLine($"  方式: {Method}");
        Console.WriteLine($"  跟踪号: {TrackingNumber}");
        Console.WriteLine($"  预计送达: {EstimatedDelivery}");
        Console.WriteLine($"  费用: {Cost:C}");
    }
}

public class Discount
{
    public string Code { get; set; }
    public string Description { get; set; }
    public decimal Amount { get; set; }
    
    public void Display()
    {
        Console.WriteLine($"  {Description} ({Code}): -{Amount:C}");
    }
}

public class TaxInfo
{
    public string Type { get; set; }
    public decimal Rate { get; set; }
    public decimal Amount { get; set; }
    
    public void Display()
    {
        Console.WriteLine($"  类型: {Type}");
        Console.WriteLine($"  税率: {Rate:P}");
        Console.WriteLine($"  金额: {Amount:C}");
    }
}

// 抽象建造者
public interface IOrderBuilder
{
    IOrderBuilder SetOrderBasicInfo(string orderId, DateTime orderDate, string status);
    IOrderBuilder SetCustomerInfo(string id, string name, string email, string phone);
    IOrderBuilder AddOrderItem(string productId, string name, decimal price, int quantity);
    IOrderBuilder SetBillingAddress(string line1, string line2, string city, string state, string zipCode, string country);
    IOrderBuilder SetShippingAddress(string line1, string line2, string city, string state, string zipCode, string country);
    IOrderBuilder SetPaymentInfo(string method, string transactionId, DateTime paymentDate, decimal amount, string status);
    IOrderBuilder SetShippingInfo(string method, string trackingNumber, DateTime estimatedDelivery, decimal cost);
    IOrderBuilder AddDiscount(string code, string description, decimal amount);
    IOrderBuilder SetTaxInfo(string type, decimal rate, decimal amount);
    Order Build();
}

// 具体建造者
public class OrderBuilder : IOrderBuilder
{
    private Order _order = new Order();
    
    public IOrderBuilder SetOrderBasicInfo(string orderId, DateTime orderDate, string status)
    {
        _order.OrderId = orderId;
        _order.OrderDate = orderDate;
        _order.Status = status;
        return this;
    }
    
    public IOrderBuilder SetCustomerInfo(string id, string name, string email, string phone)
    {
        _order.Customer = new CustomerInfo
        {
            Id = id,
            Name = name,
            Email = email,
            Phone = phone
        };
        return this;
    }
    
    public IOrderBuilder AddOrderItem(string productId, string name, decimal price, int quantity)
    {
        _order.Items.Add(new OrderItem
        {
            ProductId = productId,
            Name = name,
            Price = price,
            Quantity = quantity
        });
        return this;
    }
    
    public IOrderBuilder SetBillingAddress(string line1, string line2, string city, string state, string zipCode, string country)
    {
        _order.BillingAddress = new Address
        {
            Line1 = line1,
            Line2 = line2,
            City = city,
            State = state,
            ZipCode = zipCode,
            Country = country
        };
        return this;
    }
    
    public IOrderBuilder SetShippingAddress(string line1, string line2, string city, string state, string zipCode, string country)
    {
        _order.ShippingAddress = new Address
        {
            Line1 = line1,
            Line2 = line2,
            City = city,
            State = state,
            ZipCode = zipCode,
            Country = country
        };
        return this;
    }
    
    public IOrderBuilder SetPaymentInfo(string method, string transactionId, DateTime paymentDate, decimal amount, string status)
    {
        _order.Payment = new PaymentInfo
        {
            Method = method,
            TransactionId = transactionId,
            PaymentDate = paymentDate,
            Amount = amount,
            Status = status
        };
        return this;
    }
    
    public IOrderBuilder SetShippingInfo(string method, string trackingNumber, DateTime estimatedDelivery, decimal cost)
    {
        _order.Shipping = new ShippingInfo
        {
            Method = method,
            TrackingNumber = trackingNumber,
            EstimatedDelivery = estimatedDelivery,
            Cost = cost
        };
        return this;
    }
    
    public IOrderBuilder AddDiscount(string code, string description, decimal amount)
    {
        _order.Discounts.Add(new Discount
        {
            Code = code,
            Description = description,
            Amount = amount
        });
        return this;
    }
    
    public IOrderBuilder SetTaxInfo(string type, decimal rate, decimal amount)
    {
        _order.Tax = new TaxInfo
        {
            Type = type,
            Rate = rate,
            Amount = amount
        };
        return this;
    }
    
    public Order Build()
    {
        return _order;
    }
}

// 指挥者 - 提供各种创建订单的方法
public class OrderDirector
{
    private readonly IOrderBuilder _builder;
    
    public OrderDirector(IOrderBuilder builder)
    {
        _builder = builder;
    }
    
    public Order CreateSimpleOrder(string customerId, string customerName, string customerEmail)
    {
        return _builder
            .SetOrderBasicInfo($"ORD-{Guid.NewGuid().ToString().Substring(0, 8)}", DateTime.Now, "新订单")
            .SetCustomerInfo(customerId, customerName, customerEmail, null)
            .Build();
    }
    
    public Order CreateStandardOrder(string customerId, string customerName, string customerEmail, string phone,
                                   Address billingAddress, Address shippingAddress,
                                   List<OrderItem> items)
    {
        _builder.SetOrderBasicInfo($"ORD-{Guid.NewGuid().ToString().Substring(0, 8)}", DateTime.Now, "新订单")
                .SetCustomerInfo(customerId, customerName, customerEmail, phone);
                
        // 添加订单项
        foreach (var item in items)
        {
            _builder.AddOrderItem(item.ProductId, item.Name, item.Price, item.Quantity);
        }
        
        // 设置地址
        _builder.SetBillingAddress(
            billingAddress.Line1, billingAddress.Line2, billingAddress.City,
            billingAddress.State, billingAddress.ZipCode, billingAddress.Country);
            
        _builder.SetShippingAddress(
            shippingAddress.Line1, shippingAddress.Line2, shippingAddress.City,
            shippingAddress.State, shippingAddress.ZipCode, shippingAddress.Country);
            
        // 计算税费
        decimal subtotal = items.Sum(item => item.Price * item.Quantity);
        decimal taxRate = 0.07m; // 7% 税率
        decimal taxAmount = subtotal * taxRate;
        
        _builder.SetTaxInfo("销售税", taxRate, taxAmount);
        
        // 设置标准运输
        _builder.SetShippingInfo("标准配送", null, DateTime.Now.AddDays(5), 9.99m);
        
        return _builder.Build();
    }
    
    public Order CreatePremiumOrder(string customerId, string customerName, string customerEmail, string phone,
                                  Address billingAddress, Address shippingAddress,
                                  List<OrderItem> items, string discountCode)
    {
        // 设置基本订单信息
        _builder.SetOrderBasicInfo($"PORD-{Guid.NewGuid().ToString().Substring(0, 8)}", DateTime.Now, "优先订单")
                .SetCustomerInfo(customerId, customerName, customerEmail, phone);
                
        // 添加订单项
        foreach (var item in items)
        {
            _builder.AddOrderItem(item.ProductId, item.Name, item.Price, item.Quantity);
        }
        
        // 设置地址
        _builder.SetBillingAddress(
            billingAddress.Line1, billingAddress.Line2, billingAddress.City,
            billingAddress.State, billingAddress.ZipCode, billingAddress.Country);
            
        _builder.SetShippingAddress(
            shippingAddress.Line1, shippingAddress.Line2, shippingAddress.City,
            shippingAddress.State, shippingAddress.ZipCode, shippingAddress.Country);
            
        // 添加折扣
        if (discountCode == "PREMIUM10")
        {
            decimal subtotal = items.Sum(item => item.Price * item.Quantity);
            decimal discountAmount = subtotal * 0.10m;
            _builder.AddDiscount("PREMIUM10", "高级会员10%折扣", discountAmount);
        }
        
        // 计算税费
        decimal totalAfterDiscount = items.Sum(item => item.Price * item.Quantity);
        if (discountCode == "PREMIUM10")
        {
            totalAfterDiscount *= 0.90m; // 应用10%折扣
        }
        
        decimal taxRate = 0.07m; // 7% 税率
        decimal taxAmount = totalAfterDiscount * taxRate;
        
        _builder.SetTaxInfo("销售税", taxRate, taxAmount);
        
        // 设置快速运输
        _builder.SetShippingInfo("优先配送", null, DateTime.Now.AddDays(2), 19.99m);
        
        return _builder.Build();
    }
}

// 客户端代码
public class Client
{
    public static void Main()
    {
        IOrderBuilder builder = new OrderBuilder();
        OrderDirector director = new OrderDirector(builder);
        
        // 创建简单订单
        Console.WriteLine("=== 简单订单 ===");
        Order simpleOrder = director.CreateSimpleOrder(
            "CUST-001",
            "张三",
            "zhangsan@example.com");
        simpleOrder.Display();
        
        Console.WriteLine("\n=== 标准订单 ===");
        // 准备订单项
        var items = new List<OrderItem>
        {
            new OrderItem { ProductId = "PROD-001", Name = "商品1", Price = 29.99m, Quantity = 2 },
            new OrderItem { ProductId = "PROD-002", Name = "商品2", Price = 49.99m, Quantity = 1 }
        };
        
        // 准备地址
        var address = new Address
        {
            Line1 = "某某路123号",
            Line2 = "某某小区A座",
            City = "北京",
            State = "北京",
            ZipCode = "100000",
            Country = "中国"
        };
        
        Order standardOrder = director.CreateStandardOrder(
            "CUST-002",
            "李四",
            "lisi@example.com",
            "13800138000",
            address,
            address, // 使用相同地址作为配送地址
            items);
        standardOrder.Display();
        
        Console.WriteLine("\n=== 高级订单 ===");
        // 准备高级订单项
        var premiumItems = new List<OrderItem>
        {
            new OrderItem { ProductId = "PROD-003", Name = "高级商品1", Price = 99.99m, Quantity = 1 },
            new OrderItem { ProductId = "PROD-004", Name = "高级商品2", Price = 149.99m, Quantity = 2 }
        };
        
        // 准备地址
        var billingAddress = new Address
        {
            Line1 = "高级路456号",
            Line2 = "豪华小区B座",
            City = "上海",
            State = "上海",
            ZipCode = "200000",
            Country = "中国"
        };
        
        var shippingAddress = new Address
        {
            Line1 = "配送路789号",
            Line2 = "配送小区C座",
            City = "上海",
            State = "上海",
            ZipCode = "200000",
            Country = "中国"
        };
        
        Order premiumOrder = director.CreatePremiumOrder(
            "CUST-003",
            "王五",
            "wangwu@example.com",
            "13900139000",
            billingAddress,
            shippingAddress,
            premiumItems,
            "PREMIUM10");
        premiumOrder.Display();
    }
}
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512

业务场景结合:

// 在真实电商系统中的订单创建流程

// 1. 数据传输对象
public class OrderDTO
{
    public string CustomerId { get; set; }
    public List<CartItem> Items { get; set; }
    public AddressDTO BillingAddress { get; set; }
    public AddressDTO ShippingAddress { get; set; }
    public string PaymentMethod { get; set; }
    public string ShippingMethod { get; set; }
    public List<string> DiscountCodes { get; set; }
}

public class CartItem
{
    public string ProductId { get; set; }
    public int Quantity { get; set; }
}

public class AddressDTO
{
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string Country { get; set; }
}

// 2. 领域模型
public class Order
{
    public string Id { get; set; }
    public Customer Customer { get; set; }
    public List<OrderLineItem> LineItems { get; set; } = new List<OrderLineItem>();
    public Address BillingAddress { get; set; }
    public Address ShippingAddress { get; set; }
    public PaymentDetails Payment { get; set; }
    public ShippingDetails Shipping { get; set; }
    public List<DiscountDetails> Discounts { get; set; } = new List<DiscountDetails>();
    public TaxDetails Tax { get; set; }
    public decimal Subtotal => LineItems.Sum(item => item.Subtotal);
    public decimal DiscountTotal => Discounts.Sum(d => d.Amount);
    public decimal TaxAmount => Tax?.Amount ?? 0;
    public decimal ShippingCost => Shipping?.Cost ?? 0;
    public decimal Total => Subtotal - DiscountTotal + TaxAmount + ShippingCost;
    public string Status { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime UpdatedAt { get; set; }
    
    // 其他业务方法
    public void AddItem(OrderLineItem item)
    {
        LineItems.Add(item);
    }
    
    public void AddDiscount(DiscountDetails discount)
    {
        Discounts.Add(discount);
    }
    
    public bool CanBeFulfilled()
    {
        // 检查库存和其他条件
        return true;
    }
    
    // 其他方法...
}

// 关联模型和值对象
public class Customer
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public CustomerType Type { get; set; }
}

public enum CustomerType
{
    Regular,
    Premium,
    Business
}

public class OrderLineItem
{
    public string ProductId { get; set; }
    public string ProductName { get; set; }
    public string Sku { get; set; }
    public decimal UnitPrice { get; set; }
    public int Quantity { get; set; }
    public decimal Subtotal => UnitPrice * Quantity;
}

public class Address
{
    public string Line1 { get; set; }
    public string Line2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string Country { get; set; }
    
    public string FormattedAddress => 
        $"{Line1}, {(string.IsNullOrEmpty(Line2) ? "" : Line2 + ", ")}{City}, {State} {ZipCode}, {Country}";
}

public class PaymentDetails
{
    public string Method { get; set; }
    public string TransactionId { get; set; }
    public decimal Amount { get; set; }
    public string Status { get; set; }
    public DateTime? ProcessedAt { get; set; }
}

public class ShippingDetails
{
    public string Method { get; set; }
    public string Carrier { get; set; }
    public string TrackingNumber { get; set; }
    public decimal Cost { get; set; }
    public DateTime? EstimatedDelivery { get; set; }
}

public class DiscountDetails
{
    public string Code { get; set; }
    public string Description { get; set; }
    public DiscountType Type { get; set; }
    public decimal Amount { get; set; }
}

public enum DiscountType
{
    Fixed,
    Percentage,
    FreeShipping
}

public class TaxDetails
{
    public string Type { get; set; }
    public decimal Rate { get; set; }
    public decimal Amount { get; set; }
}

// 3. 服务接口
public interface IProductService
{
    Task<ProductDetails> GetProductDetailsAsync(string productId);
}

public interface ICustomerService
{
    Task<Customer> GetCustomerAsync(string customerId);
}

public interface IDiscountService
{
    Task<DiscountDetails> GetDiscountDetailsAsync(string code, decimal orderSubtotal);
}

public interface ITaxService
{
    Task<TaxDetails> CalculateTaxAsync(string state, decimal subtotal);
}

public interface IShippingService
{
    Task<ShippingDetails> GetShippingDetailsAsync(string method, Address address, decimal orderWeight);
}

// 4. 建造者接口
public interface IOrderBuilder
{
    Task<IOrderBuilder> SetCustomerAsync(string customerId);
    Task<IOrderBuilder> AddItemsFromCartAsync(List<CartItem> items);
    IOrderBuilder SetBillingAddress(AddressDTO address);
    IOrderBuilder SetShippingAddress(AddressDTO address);
    Task<IOrderBuilder> ApplyDiscountsAsync(List<string> discountCodes);
    Task<IOrderBuilder> CalculateTaxAsync();
    Task<IOrderBuilder> SetShippingMethodAsync(string method);
    IOrderBuilder SetPaymentMethod(string method);
    Task<Order> BuildAsync();
}

// 5. 具体建造者实现
public class OrderBuilder : IOrderBuilder
{
    private readonly Order _order;
    private readonly IProductService _productService;
    private readonly ICustomerService _customerService;
    private readonly IDiscountService _discountService;
    private readonly ITaxService _taxService;
    private readonly IShippingService _shippingService;
    private readonly ILogger<OrderBuilder> _logger;
    
    public OrderBuilder(
        IProductService productService,
        ICustomerService customerService,
        IDiscountService discountService,
        ITaxService taxService,
        IShippingService shippingService,
        ILogger<OrderBuilder> logger)
    {
        _productService = productService;
        _customerService = customerService;
        _discountService = discountService;
        _taxService = taxService;
        _shippingService = shippingService;
        _logger = logger;
        
        _order = new Order
        {
            Id = $"ORD-{Guid.NewGuid().ToString().Substring(0, 8)}",
            Status = "Draft",
            CreatedAt = DateTime.UtcNow,
            UpdatedAt = DateTime.UtcNow
        };
    }
    
    public async Task<IOrderBuilder> SetCustomerAsync(string customerId)
    {
        try
        {
            _order.Customer = await _customerService.GetCustomerAsync(customerId);
            return this;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"获取客户信息时出错: {ex.Message}");
            throw new OrderBuilderException("无法获取客户信息", ex);
        }
    }
    
    public async Task<IOrderBuilder> AddItemsFromCartAsync(List<CartItem> items)
    {
        foreach (var item in items)
        {
            try
            {
                var productDetails = await _productService.GetProductDetailsAsync(item.ProductId);
                
                _order.AddItem(new OrderLineItem
                {
                    ProductId = item.ProductId,
                    ProductName = productDetails.Name,
                    Sku = productDetails.Sku,
                    UnitPrice = productDetails.Price,
                    Quantity = item.Quantity
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"添加商品 {item.ProductId} 时出错: {ex.Message}");
                throw new OrderBuilderException($"无法添加商品: {item.ProductId}", ex);
            }
        }
        
        return this;
    }
    
    public IOrderBuilder SetBillingAddress(AddressDTO addressDto)
    {
        _order.BillingAddress = new Address
        {
            Line1 = addressDto.Line1,
            Line2 = addressDto.Line2,
            City = addressDto.City,
            State = addressDto.State,
            ZipCode = addressDto.ZipCode,
            Country = addressDto.Country
        };
        
        return this;
    }
    
    public IOrderBuilder SetShippingAddress(AddressDTO addressDto)
    {
        _order.ShippingAddress = new Address
        {
            Line1 = addressDto.Line1,
            Line2 = addressDto.Line2,
            City = addressDto.City,
            State = addressDto.State,
            ZipCode = addressDto.ZipCode,
            Country = addressDto.Country
        };
        
        return this;
    }
    
    public async Task<IOrderBuilder> ApplyDiscountsAsync(List<string> discountCodes)
    {
        if (discountCodes == null || !discountCodes.Any())
            return this;
            
        foreach (var code in discountCodes)
        {
            try
            {
                var discount = await _discountService.GetDiscountDetailsAsync(code, _order.Subtotal);
                if (discount != null)
                {
                    _order.AddDiscount(discount);
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, $"应用折扣码 {code} 时出错: {ex.Message}");
                // 继续处理其他折扣码,不中断流程
            }
        }
        
        return this;
    }
    
    public async Task<IOrderBuilder> CalculateTaxAsync()
    {
        if (_order.BillingAddress == null)
        {
            throw new OrderBuilderException("计算税费前需要设置账单地址");
        }
        
        try
        {
            _order.Tax = await _taxService.CalculateTaxAsync(
                _order.BillingAddress.State, 
                _order.Subtotal - _order.DiscountTotal);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"计算税费时出错: {ex.Message}");
            throw new OrderBuilderException("无法计算税费", ex);
        }
        
        return this;
    }
    
    public async Task<IOrderBuilder> SetShippingMethodAsync(string method)
    {
        if (_order.ShippingAddress == null)
        {
            throw new OrderBuilderException("设置配送方式前需要设置配送地址");
        }
        
        try
        {
            // 计算订单重量 (假设有这个属性)
            decimal orderWeight = _order.LineItems.Sum(item => 0.5m * item.Quantity); // 简化示例
            
            _order.Shipping = await _shippingService.GetShippingDetailsAsync(
                method, 
                _order.ShippingAddress, 
                orderWeight);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"设置配送方式时出错: {ex.Message}");
            throw new OrderBuilderException("无法设置配送方式", ex);
        }
        
        return this;
    }
    
    public IOrderBuilder SetPaymentMethod(string method)
    {
        _order.Payment = new PaymentDetails
        {
            Method = method,
            Status = "Pending",
            Amount = _order.Total // 更新总金额
        };
        
        return this;
    }
    
    public async Task<Order> BuildAsync()
    {
        // 执行最终验证和构建步骤
        if (!_order.CanBeFulfilled())
        {
            throw new OrderBuilderException("订单无法完成,请检查商品库存或其他限制");
        }
        
        // 更新订单状态和时间戳
        _order.Status = "Created";
        _order.UpdatedAt = DateTime.UtcNow;
        
        return _order;
    }
}

// 异常类
public class OrderBuilderException : Exception
{
    public OrderBuilderException(string message) : base(message) { }
    public OrderBuilderException(string message, Exception innerException) : base(message, innerException) { }
}

// 6. 指挥者 - 订单服务
public class OrderService
{
    private readonly IOrderBuilder _orderBuilder;
    
    public OrderService(IOrderBuilder orderBuilder)
    {
        _orderBuilder = orderBuilder;
    }
    
    public async Task<Order> CreateOrderAsync(OrderDTO orderDto)
    {
        return await _orderBuilder
            .SetCustomerAsync(orderDto.CustomerId)
            .Result
            .AddItemsFromCartAsync(orderDto.Items)
            .Result
            .SetBillingAddress(orderDto.BillingAddress)
            .SetShippingAddress(orderDto.ShippingAddress)
            .ApplyDiscountsAsync(orderDto.DiscountCodes)
            .Result
            .CalculateTaxAsync()
            .Result
            .SetShippingMethodAsync(orderDto.ShippingMethod)
            .Result
            .SetPaymentMethod(orderDto.PaymentMethod)
            .BuildAsync();
    }
}

// 7. 使用示例 - ASP.NET Core API控制器
[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
    private readonly OrderService _orderService;
    private readonly ILogger<OrdersController> _logger;
    
    public OrdersController(OrderService orderService, ILogger<OrdersController> logger)
    {
        _orderService = orderService;
        _logger = logger;
    }
    
    [HttpPost]
    public async Task<IActionResult> CreateOrder([FromBody] OrderDTO orderDto)
    {
        try
        {
            var order = await _orderService.CreateOrderAsync(orderDto);
            return CreatedAtAction(nameof(GetOrder), new { id = order.Id }, order);
        }
        catch (OrderBuilderException ex)
        {
            _logger.LogError(ex, $"创建订单时出错: {ex.Message}");
            return BadRequest(new { error = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"创建订单时发生未知错误: {ex.Message}");
            return StatusCode(500, new { error = "创建订单时发生未知错误" });
        }
    }
    
    [HttpGet("{id}")]
    public IActionResult GetOrder(string id)
    {
        // 实现获取订单的逻辑
        return Ok();
    }
}

// 8. 服务注册 - Startup.cs
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // 注册服务
        services.AddScoped<IProductService, ProductService>();
        services.AddScoped<ICustomerService, CustomerService>();
        services.AddScoped<IDiscountService, DiscountService>();
        services.AddScoped<ITaxService, TaxService>();
        services.AddScoped<IShippingService, ShippingService>();
        
        // 注册建造者和服务
        services.AddScoped<IOrderBuilder, OrderBuilder>();
        services.AddScoped<OrderService>();
        
        // 添加其他服务...
    }
}
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496

# 4. 原型模式

原理:
原型模式通过复制(克隆)一个已有对象来创建新对象,而不是通过实例化类。在需要创建大量相似对象的情况下,原型模式可以减少资源消耗,提高性能。

思路:

  1. 创建一个抽象原型接口,定义克隆方法
  2. 实现具体原型类,实现克隆方法
  3. 使用原型管理器维护可用的原型

前辈经验:

  • 当需要创建的对象构造成本高(例如需要数据库操作或复杂计算)时,使用原型模式复制已有实例更高效
  • 在系统中有大量相似对象,只有少量属性不同时,使用原型模式可以减少类的数量
  • 当需要保存对象状态(快照)时,原型模式非常有用
  • 注意深拷贝和浅拷贝的区别,根据需求选择合适的克隆策略

业务场景:
文档编辑系统,需要复制已有文档或模板来创建新文档,避免从头创建的开销。

简单实现:

// 抽象原型接口
public interface ICloneable<T>
{
    T Clone();
}

// 具体原型类
public class Document : ICloneable<Document>
{
    public string Title { get; set; }
    public string Content { get; set; }
    public string Author { get; set; }
    public DateTime CreatedDate { get; set; }
    
    public Document(string title, string content, string author)
    {
        Title = title;
        Content = content;
        Author = author;
        CreatedDate = DateTime.Now;
    }
    
    // 克隆方法
    public Document Clone()
    {
        return new Document(Title, Content, Author)
        {
            CreatedDate = DateTime.Now // 更新创建日期
        };
    }
    
    public void Display()
    {
        Console.WriteLine($"文档: {Title}");
        Console.WriteLine($"作者: {Author}");
        Console.WriteLine($"创建日期: {CreatedDate}");
        Console.WriteLine($"内容: {Content}");
    }
}

// 客户端代码
public class Client
{
    public static void Main()
    {
        // 创建原始文档
        Document original = new Document(
            "原始文档",
            "这是原始文档的内容。",
            "张三");
        
        Console.WriteLine("原始文档:");
        original.Display();
        
        // 克隆文档
        Document clone = original.Clone();
        clone.Title = "克隆文档";
        clone.Content = "这是从原始文档克隆的内容,但已经修改。";
        
        Console.WriteLine("\n克隆文档:");
        clone.Display();
    }
}
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

复杂实现:

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

// 抽象原型接口
public interface IPrototype<T>
{
    T ShallowCopy();
    T DeepCopy();
}

// 文档元素基类
[Serializable]
public abstract class DocumentElement
{
    public string Id { get; set; }
    public abstract DocumentElement Clone();
}

// 文本元素
[Serializable]
public class TextElement : DocumentElement
{
    public string Text { get; set; }
    public string FontName { get; set; }
    public int FontSize { get; set; }
    public bool IsBold { get; set; }
    public bool IsItalic { get; set; }
    
    public TextElement(string text, string fontName = "Arial", int fontSize = 12, bool isBold = false, bool isItalic = false)
    {
        Id = Guid.NewGuid().ToString();
        Text = text;
        FontName = fontName;
        FontSize = fontSize;
        IsBold = isBold;
        IsItalic = isItalic;
    }
    
    public override DocumentElement Clone()
    {
        return new TextElement(Text, FontName, FontSize, IsBold, IsItalic) { Id = this.Id };
    }
    
    public override string ToString()
    {
        return $"文本: \"{Text}\" (字体: {FontName}, 大小: {FontSize}, 粗体: {IsBold}, 斜体: {IsItalic})";
    }
}

// 图片元素
[Serializable]
public class ImageElement : DocumentElement
{
    public string Path { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
    
    public ImageElement(string path, int width = 100, int height = 100)
    {
        Id = Guid.NewGuid().ToString();
        Path = path;
        Width = width;
        Height = height;
    }
    
    public override DocumentElement Clone()
    {
        return new ImageElement(Path, Width, Height) { Id = this.Id };
    }
    
    public override string ToString()
    {
        return $"图片: {Path} (尺寸: {Width}x{Height})";
    }
}

// 表格元素
[Serializable]
public class TableElement : DocumentElement
{
    public int Rows { get; set; }
    public int Columns { get; set; }
    public List<string> Data { get; set; }
    
    public TableElement(int rows, int columns)
    {
        Id = Guid.NewGuid().ToString();
        Rows = rows;
        Columns = columns;
        Data = new List<string>(new string[rows * columns]);
    }
    
    public void SetCell(int row, int column, string value)
    {
        if (row >= 0 && row < Rows && column >= 0 && column < Columns)
        {
            Data[row * Columns + column] = value;
        }
    }
    
    public string GetCell(int row, int column)
    {
        if (row >= 0 && row < Rows && column >= 0 && column < Columns)
        {
            return Data[row * Columns + column];
        }
        return null;
    }
    
    public override DocumentElement Clone()
    {
        TableElement clone = new TableElement(Rows, Columns) { Id = this.Id };
        clone.Data = new List<string>(Data);
        return clone;
    }
    
    public override string ToString()
    {
        return $"表格: {Rows}x{Columns}";
    }
}

// 文档类
[Serializable]
public class Document : IPrototype<Document>
{
    public string Title { get; set; }
    public string Author { get; set; }
    public DateTime CreatedDate { get; set; }
    public List<DocumentElement> Elements { get; set; }
    
    public Document()
    {
        Title = "新文档";
        Author = "未知";
        CreatedDate = DateTime.Now;
        Elements = new List<DocumentElement>();
    }
    
    public Document(string title, string author)
    {
        Title = title;
        Author = author;
        CreatedDate = DateTime.Now;
        Elements = new List<DocumentElement>();
    }
    
    public void AddElement(DocumentElement element)
    {
        Elements.Add(element);
    }
    
    public void RemoveElement(string id)
    {
        Elements.RemoveAll(e => e.Id == id);
    }
    
    // 浅拷贝 - 只复制基本字段,共享引用类型
    public Document ShallowCopy()
    {
        return (Document)this.MemberwiseClone();
    }
    
    // 深拷贝 - 复制所有内容,创建新的引用类型对象
    public Document DeepCopy()
    {
        Document clone = new Document
        {
            Title = this.Title,
            Author = this.Author,
            CreatedDate = DateTime.Now,  // 更新创建日期
            Elements = new List<DocumentElement>()
        };
        
        // 复制所有元素
        foreach (var element in Elements)
        {
            clone.Elements.Add(element.Clone());
        }
        
        return clone;
    }
    
    // 使用序列化进行深拷贝 (通用方法)
    public Document DeepCopyBySerialization()
    {
        if (!this.GetType().IsSerializable)
        {
            throw new InvalidOperationException("类型必须是可序列化的");
        }
        
        using (MemoryStream stream = new MemoryStream())
        {
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, this);
            stream.Position = 0;
            return (Document)formatter.Deserialize(stream);
        }
    }
    
    public void Display()
    {
        Console.WriteLine($"文档标题: {Title}");
        Console.WriteLine($"作者: {Author}");
        Console.WriteLine($"创建日期: {CreatedDate}");
        Console.WriteLine("内容元素:");
        
        foreach (var element in Elements)
        {
            Console.WriteLine($"- {element}");
        }
    }
}

// 文档模板管理器
public class DocumentTemplateManager
{
    private Dictionary<string, Document> _templates = new Dictionary<string, Document>();
    
    public void AddTemplate(string templateName, Document document)
    {
        _templates[templateName] = document;
    }
    
    public Document GetTemplate(string templateName)
    {
        if (_templates.ContainsKey(templateName))
        {
            return _templates[templateName];
        }
        return null;
    }
    
    public Document CreateDocumentFromTemplate(string templateName)
    {
        Document template = GetTemplate(templateName);
        if (template != null)
        {
            return template.DeepCopy();
        }
        return null;
    }
    
    public List<string> GetAvailableTemplates()
    {
        return new List<string>(_templates.Keys);
    }
}

// 客户端代码
public class Client
{
    public static void Main()
    {
        // 创建文档模板管理器
        DocumentTemplateManager templateManager = new DocumentTemplateManager();
        
        // 创建简单报告模板
        Document reportTemplate = new Document("报告模板", "系统");
        reportTemplate.AddElement(new TextElement("报告标题", "Arial", 24, true, false));
        reportTemplate.AddElement(new TextElement("这是报告的简介部分...", "Times New Roman", 12));
        
        TableElement dataTable = new TableElement(3, 2);
        dataTable.SetCell(0, 0, "项目");
        dataTable.SetCell(0, 1, "值");
        dataTable.SetCell(1, 0, "项目1");
        dataTable.SetCell(1, 1, "值1");
        dataTable.SetCell(2, 0, "项目2");
        dataTable.SetCell(2, 1, "值2");
        reportTemplate.AddElement(dataTable);
        
        reportTemplate.AddElement(new TextElement("这是报告的结论部分...", "Times New Roman", 12));
        
        // 创建演示文稿模板
        Document presentationTemplate = new Document("演示文稿模板", "系统");
        presentationTemplate.AddElement(new TextElement("演示标题", "Calibri", 32, true, false));
        presentationTemplate.AddElement(new ImageElement("logo.png", 200, 100));
        presentationTemplate.AddElement(new TextElement("• 要点1\n• 要点2\n• 要点3", "Calibri", 18));
        
        // 注册模板
        templateManager.AddTemplate("报告", reportTemplate);
        templateManager.AddTemplate("演示文稿", presentationTemplate);
        
        // 显示可用模板
        Console.WriteLine("可用的文档模板:");
        foreach (var template in templateManager.GetAvailableTemplates())
        {
            Console.WriteLine($"- {template}");
        }
        
        Console.WriteLine("\n创建新报告:");
        // 从模板创建新文档
        Document newReport = templateManager.CreateDocumentFromTemplate("报告");
        if (newReport != null)
        {
            newReport.Title = "2023年第一季度销售报告";
            newReport.Author = "张三";
            
            // 修改表格数据
            foreach (var element in newReport.Elements)
            {
                if (element is TableElement table)
                {
                    table.SetCell(1, 1, "¥1,234,567");
                    table.SetCell(2, 1, "¥2,345,678");
                    break;
                }
            }
            
            newReport.Display();
        }
        
        Console.WriteLine("\n创建新演示文稿:");
        // 从模板创建新演示文稿
        Document newPresentation = templateManager.CreateDocumentFromTemplate("演示文稿");
        if (newPresentation != null)
        {
            newPresentation.Title = "产品发布会";
            newPresentation.Author = "李四";
            
            // 修改要点
            foreach (var element in newPresentation.Elements)
            {
                if (element is TextElement text && text.Text.StartsWith("•"))
                {
                    text.Text = "• 新产品介绍\n• 市场分析\n• 销售预测\n• Q&A";
                    break;
                }
            }
            
            newPresentation.Display();
        }
        
        // 演示浅拷贝和深拷贝的区别
        Console.WriteLine("\n演示浅拷贝和深拷贝的区别:");
        Document original = new Document("原始文档", "王五");
        original.AddElement(new TextElement("这是原始内容"));
        
        // 浅拷贝
        Document shallowCopy = original.ShallowCopy();
        shallowCopy.Title = "浅拷贝文档";
        
        // 深拷贝
        Document deepCopy = original.DeepCopy();
        deepCopy.Title = "深拷贝文档";
        
        // 修改原始文档中的元素
        if (original.Elements[0] is TextElement textElement)
        {
            textElement.Text = "这是修改后的内容";
        }
        
        Console.WriteLine("原始文档:");
        original.Display();
        
        Console.WriteLine("\n浅拷贝文档 (元素被共享):");
        shallowCopy.Display();
        
        Console.WriteLine("\n深拷贝文档 (元素是独立的):");
        deepCopy.Display();
    }
}
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

业务场景结合:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

// 1. 领域模型
namespace DocumentManagementSystem.Models
{
    // 原型接口
    public interface IPrototype<T>
    {
        T Clone(bool deep = true);
    }
    
    // 文档类
    public class Document : IPrototype<Document>
    {
        public Guid Id { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public DocumentType Type { get; set; }
        public string Author { get; set; }
        public string Department { get; set; }
        public DateTime CreatedAt { get; set; }
        public DateTime ModifiedAt { get; set; }
        public List<Section> Sections { get; set; } = new List<Section>();
        public List<string> Tags { get; set; } = new List<string>();
        public DocumentStatus Status { get; set; }
        public Dictionary<string, string> Metadata { get; set; } = new Dictionary<string, string>();
        public List<VersionInfo> VersionHistory { get; set; } = new List<VersionInfo>();
        
        // 克隆方法
        public Document Clone(bool deep = true)
        {
            var clone = new Document
            {
                // 新ID以区分克隆
                Id = Guid.NewGuid(),
                Title = $"Copy of {Title}",
                Description = Description,
                Type = Type,
                Author = Author,
                Department = Department,
                CreatedAt = DateTime.UtcNow,
                ModifiedAt = DateTime.UtcNow,
                Status = DocumentStatus.Draft,
                // 复制元数据
                Metadata = new Dictionary<string, string>(Metadata)
            };
            
            // 复制标签
            clone.Tags = new List<string>(Tags);
            
            // 添加版本信息
            clone.VersionHistory.Add(new VersionInfo
            {
                Version = "1.0",
                ModifiedAt = DateTime.UtcNow,
                ModifiedBy = Author,
                Comments = $"Cloned from document {Id}"
            });
            
            // 深度克隆
            if (deep)
            {
                // 克隆节
                foreach (var section in Sections)
                {
                    clone.Sections.Add(section.Clone());
                }
            }
            
            return clone;
        }
    }
    
    // 文档部分
    public class Section : IPrototype<Section>
    {
        public Guid Id { get; set; }
        public string Title { get; set; }
        public int Order { get; set; }
        public List<ContentBlock> Content { get; set; } = new List<ContentBlock>();
        
        public Section Clone()
        {
            var clone = new Section
            {
                Id = Guid.NewGuid(),
                Title = Title,
                Order = Order,
                Content = new List<ContentBlock>()
            };
            
            // 克隆内容块
            foreach (var block in Content)
            {
                clone.Content.Add(block.Clone());
            }
            
            return clone;
        }
    }
    
    // 内容块基类
    public abstract class ContentBlock : IPrototype<ContentBlock>
    {
        public Guid Id { get; set; }
        public ContentType Type { get; set; }
        public int Order { get; set; }
        
        public abstract ContentBlock Clone();
    }
    
    // 文本块
    public class TextBlock : ContentBlock
    {
        public string Text { get; set; }
        public TextFormat Format { get; set; }
        
        public TextBlock()
        {
            Type = ContentType.Text;
        }
        
        public override ContentBlock Clone()
        {
            return new TextBlock
            {
                Id = Guid.NewGuid(),
                Order = Order,
                Text = Text,
                Format = Format,
                Type = ContentType.Text
            };
        }
    }
    
    // 图片块
    public class ImageBlock : ContentBlock
    {
        public string Url { get; set; }
        public string Caption { get; set; }
        public int Width { get; set; }
        public int Height { get; set; }
        
        public ImageBlock()
        {
            Type = ContentType.Image;
        }
        
        public override ContentBlock Clone()
        {
            return new ImageBlock
            {
                Id = Guid.NewGuid(),
                Order = Order,
                Url = Url,
                Caption = Caption,
                Width = Width,
                Height = Height,
                Type = ContentType.Image
            };
        }
    }
    
    // 表格块
    public class TableBlock : ContentBlock
    {
        public List<List<string>> Data { get; set; } = new List<List<string>>();
        public bool HasHeader { get;set;}
        public TableBlock()
        {
            Type = ContentType.Table;
        }
    }

    public override ContentBlock Clone()
    {
        var clone = new TableBlock
        {
            Id = Guid.NewGuid(),
            Order = Order,
            HasHeader = HasHeader,
            Type = ContentType.Table,
            Data = new List<List<string>>()
        };

        // 深拷贝表格数据
        foreach (var row in Data)
        {
            clone.Data.Add(new List<string>(row));
        }

        return clone;
    }
}
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200

​

// 表格块(续)
public class TableBlock : ContentBlock
{
    public List<List<string>> Data { get; set; } = new List<List<string>>();
    public bool HasHeader { get; set; }
    public int Rows => Data.Count;
    public int Columns => Data.Count > 0 ? Data[0].Count : 0;

    public TableBlock()
    {
        Type = ContentType.Table;
    }

    public override ContentBlock Clone()
    {
        var clone = new TableBlock
        {
            Id = Guid.NewGuid(),
            Order = Order,
            HasHeader = HasHeader,
            Type = ContentType.Table,
            Data = new List<List<string>>()
        };

        // 深拷贝表格数据
        foreach (var row in Data)
        {
            clone.Data.Add(new List<string>(row));
        }

        return clone;
    }
}
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
// 列表块
public class ListBlock : ContentBlock
{
    public List<string> Items { get; set; } = new List<string>();
    public ListStyle Style { get; set; }

    public ListBlock()
    {
        Type = ContentType.List;
    }

    public override ContentBlock Clone()
    {
        return new ListBlock
        {
            Id = Guid.NewGuid(),
            Order = Order,
            Items = new List<string>(Items),
            Style = Style,
            Type = ContentType.List
        };
    }
}

// 文档版本信息
public class VersionInfo
{
    public string Version { get; set; }
    public DateTime ModifiedAt { get; set; }
    public string ModifiedBy { get; set; }
    public string Comments { get; set; }
}

// 枚举类型
public enum DocumentType
{
    Report,
    Presentation,
    Contract,
    Form,
    Letter,
    Manual,
    Other
}

public enum DocumentStatus
{
    Draft,
    UnderReview,
    Approved,
    Published,
    Archived,
    Deprecated
}

public enum ContentType
{
    Text,
    Image,
    Table,
    List,
    Chart,
    File
}

public enum TextFormat
{
    Plain,
    Heading1,
    Heading2,
    Heading3,
    Quote,
    Code,
    Paragraph
}

public enum ListStyle
{
    Bullet,
    Numbered,
    Checkbox
}


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
83
84
// 2. 文档模板管理服务
namespace DocumentManagementSystem.Services
{
    public interface ITemplateService
    {
        Task<List<DocumentTemplate>> GetTemplatesAsync();
        Task<DocumentTemplate> GetTemplateByIdAsync(Guid id);
        Task<Document> CreateDocumentFromTemplateAsync(Guid templateId, string title, string author);
        Task<Document> SaveTemplateAsync(Document document, string templateName, string category);
    }
}

public class DocumentTemplate
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string Category { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime ModifiedAt { get; set; }
    public Document Document { get; set; }
}

public class TemplateService : ITemplateService
{
    private readonly IDocumentRepository _documentRepository;
    private readonly ITemplateRepository _templateRepository;
    private readonly ILogger<TemplateService> _logger;

    public TemplateService(
        IDocumentRepository documentRepository,
        ITemplateRepository templateRepository,
        ILogger<TemplateService> logger)
    {
        _documentRepository = documentRepository;
        _templateRepository = templateRepository;
        _logger = logger;
    }

    public async Task<List<DocumentTemplate>> GetTemplatesAsync()
    {
        try
        {
            return await _templateRepository.GetAllTemplatesAsync();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取文档模板时出错");
            throw;
        }
    }

    public async Task<DocumentTemplate> GetTemplateByIdAsync(Guid id)
    {
        try
        {
            return await _templateRepository.GetTemplateByIdAsync(id);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"获取ID为{id}的模板时出错");
            throw;
        }
    }

    public async Task<Document> CreateDocumentFromTemplateAsync(Guid templateId, string title, string author)
    {
        try
        {
            var template = await _templateRepository.GetTemplateByIdAsync(templateId);
            if (template == null)
            {
                throw new KeyNotFoundException($"ID为{templateId}的模板不存在");
            }

            // 克隆模板文档
            var newDocument = template.Document.Clone(true);

            // 更新文档属性
            newDocument.Title = title;
            newDocument.Author = author;
            newDocument.CreatedAt = DateTime.UtcNow;
            newDocument.ModifiedAt = DateTime.UtcNow;

            // 保存新文档
            await _documentRepository.SaveDocumentAsync(newDocument);

            return newDocument;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"从模板{templateId}创建文档时出错");
            throw;
        }
    }

    public async Task<Document> SaveTemplateAsync(Document document, string templateName, string category)
    {
        try
        {
            // 创建模板文档的克隆
            var templateDoc = document.Clone(true);

            // 创建新模板
            var template = new DocumentTemplate
            {
                Id = Guid.NewGuid(),
                Name = templateName,
                Description = document.Description,
                Category = category,
                CreatedAt = DateTime.UtcNow,
                ModifiedAt = DateTime.UtcNow,
                Document = templateDoc
            };

            // 保存模板
            await _templateRepository.SaveTemplateAsync(template);

            return templateDoc;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "保存文档模板时出错");
            throw;
        }
    }
}

// 数据访问接口
public interface IDocumentRepository
{
    Task<Document> GetDocumentByIdAsync(Guid id);
    Task<Guid> SaveDocumentAsync(Document document);
    Task<bool> DeleteDocumentAsync(Guid id);
}

public interface ITemplateRepository
{
    Task<List<DocumentTemplate>> GetAllTemplatesAsync();
    Task<List<DocumentTemplate>> GetTemplatesByCategoryAsync(string category);
    Task<DocumentTemplate> GetTemplateByIdAsync(Guid id);
    Task<Guid> SaveTemplateAsync(DocumentTemplate template);
    Task<bool> DeleteTemplateAsync(Guid id);
}
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// 3. 创建默认模板的服务
namespace DocumentManagementSystem.Services
{
    public class DefaultTemplateInitializer
    {
        private readonly ITemplateRepository _templateRepository;
        private readonly ILogger<DefaultTemplateInitializer> _logger;

        public DefaultTemplateInitializer(
            ITemplateRepository templateRepository,
            ILogger<DefaultTemplateInitializer> logger)
        {
            _templateRepository = templateRepository;
            _logger = logger;
        }

        public async Task InitializeDefaultTemplatesAsync()
        {
            try
            {
                // 检查是否已存在模板
                var existingTemplates = await _templateRepository.GetAllTemplatesAsync();
                if (existingTemplates.Any())
                {
                    return;
                }

                // 创建默认模板
                await CreateReportTemplateAsync();
                await CreateContractTemplateAsync();
                await CreatePresentationTemplateAsync();

                _logger.LogInformation("默认文档模板已初始化");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "初始化默认模板时出错");
            }
        }

        private async Task CreateReportTemplateAsync()
        {
            var reportDoc = new Document
            {
                Id = Guid.NewGuid(),
                Title = "标准报告",
                Description = "适用于一般业务报告的标准模板",
                Type = DocumentType.Report,
                Author = "系统管理员",
                CreatedAt = DateTime.UtcNow,
                ModifiedAt = DateTime.UtcNow,
                Status = DocumentStatus.Published,
                Tags = new List<string> { "报告", "标准" }
            };

            // 添加报告节
            var titleSection = new Section
            {
                Id = Guid.NewGuid(),
                Title = "标题页",
                Order = 1,
                Content = new List<ContentBlock>
                {
                    new TextBlock
                    {
                        Id = Guid.NewGuid(),
                        Order = 1,
                        Text = "[报告标题]",
                        Format = TextFormat.Heading1
                    },
                    new TextBlock
                    {
                        Id = Guid.NewGuid(),
                        Order = 2,
                        Text = "准备人: [姓名]\n部门: [部门]\n日期: [日期]",
                        Format = TextFormat.Plain
                    }
                }
            };

            var summarySection = new Section
            {
                Id = Guid.NewGuid(),
                Title = "摘要",
                Order = 2,
                Content = new List<ContentBlock>
                {
                    new TextBlock
                    {
                        Id = Guid.NewGuid(),
                        Order = 1,
                        Text = "本报告的主要内容和结论概述...",
                        Format = TextFormat.Paragraph
                    }
                }
            };

            var introductionSection = new Section
            {
                Id = Guid.NewGuid(),
                Title = "介绍",
                Order = 3,
                Content = new List<ContentBlock>
                {
                    new TextBlock
                    {
                        Id = Guid.NewGuid(),
                        Order = 1,
                        Text = "报告的背景和目的...",
                        Format = TextFormat.Paragraph
                    }
                }
            };

            var dataSection = new Section
            {
                Id = Guid.NewGuid(),
                Title = "数据分析",
                Order = 4,
                Content = new List<ContentBlock>
                {
                    new TextBlock
                    {
                        Id = Guid.NewGuid(),
                        Order = 1,
                        Text = "数据分析的主要发现...",
                        Format = TextFormat.Paragraph
                    },
                    new TableBlock
                    {
                        Id = Guid.NewGuid(),
                        Order = 2,
                        HasHeader = true,
                        Data = new List<List<string>>
                        {
                            new List<string> { "类别", "数值", "百分比" },
                            new List<string> { "类别1", "100", "50%" },
                            new List<string> { "类别2", "80", "40%" },
                            new List<string> { "类别3", "20", "10%" }
                        }
                    }
                }
            };

            var conclusionSection = new Section
            {
                Id = Guid.NewGuid(),
                Title = "结论",
                Order = 5,
                Content = new List<ContentBlock>
                {
                    new TextBlock
                    {
                        Id = Guid.NewGuid(),
                        Order = 1,
                        Text = "基于分析得出的结论...",
                        Format = TextFormat.Paragraph
                    }
                }
            };

            reportDoc.Sections.Add(titleSection);
            reportDoc.Sections.Add(summarySection);
            reportDoc.Sections.Add(introductionSection);
            reportDoc.Sections.Add(dataSection);
            reportDoc.Sections.Add(conclusionSection);

            // 保存为模板
            var template = new DocumentTemplate
            {
                Id = Guid.NewGuid(),
                Name = "标准业务报告",
                Description = "适用于一般业务报告的标准模板",
                Category = "报告",
                CreatedAt = DateTime.UtcNow,
                ModifiedAt = DateTime.UtcNow,
                Document = reportDoc
            };

            await _templateRepository.SaveTemplateAsync(template);
        }

        private async Task CreateContractTemplateAsync()
        {
            // 创建合同模板
            var contractDoc = new Document
            {
                Id = Guid.NewGuid(),
                Title = "标准合同",
                Description = "适用于一般业务合作的标准合同模板",
                Type = DocumentType.Contract,
                Author = "系统管理员",
                CreatedAt = DateTime.UtcNow,
                ModifiedAt = DateTime.UtcNow,
                Status = DocumentStatus.Published,
                Tags = new List<string> { "合同", "法律" }
            };

            // 添加合同节
            // ... (省略合同模板的详细内容,类似于报告模板)

            // 保存为模板
            var template = new DocumentTemplate
            {
                Id = Guid.NewGuid(),
                Name = "标准业务合同",
                Description = "适用于一般业务合作的标准合同模板",
                Category = "合同",
                CreatedAt = DateTime.UtcNow,
                ModifiedAt = DateTime.UtcNow,
                Document = contractDoc
            };

            await _templateRepository.SaveTemplateAsync(template);
        }

        private async Task CreatePresentationTemplateAsync()
        {
            // 创建演示文稿模板
            // ... (省略演示文稿模板的详细内容)

            // 保存为模板
            var template = new DocumentTemplate
            {
                Id = Guid.NewGuid(),
                Name = "标准演示文稿",
                Description = "适用于一般业务演示的标准模板",
                Category = "演示文稿",
                CreatedAt = DateTime.UtcNow,
                ModifiedAt = DateTime.UtcNow,
                Document = new Document() // 简化示例
            };

            await _templateRepository.SaveTemplateAsync(template);
        } 


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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
// 4. API控制器
namespace DocumentManagementSystem.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class TemplatesController : ControllerBase
    {
        private readonly ITemplateService _templateService;
        private readonly ILogger<TemplatesController> _logger;
        public TemplatesController(
            ITemplateService templateService,
            ILogger<TemplatesController> logger)
        {
            _templateService = templateService;
            _logger = logger;
        }

        [HttpGet]
        public async Task<ActionResult<IEnumerable<DocumentTemplateDto>>> GetTemplates()
        {
            try
            {
                var templates = await _templateService.GetTemplatesAsync();
                var templateDtos = templates.Select(t => new DocumentTemplateDto
                                                    {
                                                        Id = t.Id,
                                                        Name = t.Name,
                                                        Description = t.Description,
                                                        Category = t.Category,
                                                        CreatedAt = t.CreatedAt,
                                                        ModifiedAt = t.ModifiedAt
                                                    });

                return Ok(templateDtos);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取模板列表时出错");
                return StatusCode(500, "获取模板列表时发生错误");
            }
        }

        [HttpGet("{id}")]
        public async Task<ActionResult<DocumentTemplateDto>> GetTemplate(Guid id)
        {
            try
            {
                var template = await _templateService.GetTemplateByIdAsync(id);
                if (template == null)
                {
                    return NotFound();
                }

                var templateDto = new DocumentTemplateDto
                {
                    Id = template.Id,
                    Name = template.Name,
                    Description = template.Description,
                    Category = template.Category,
                    CreatedAt = template.CreatedAt,
                    ModifiedAt = template.ModifiedAt
                };

                return Ok(templateDto);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取ID为{id}的模板时出错");
                return StatusCode(500, "获取模板详情时发生错误");
            }
        }

        [HttpPost("create-document")]
        public async Task<ActionResult<DocumentDto>> CreateDocumentFromTemplate([FromBody] CreateDocumentRequest request)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }

                var document = await _templateService.CreateDocumentFromTemplateAsync(
                    request.TemplateId,
                    request.Title,
                    request.Author);

                var documentDto = new DocumentDto
                {
                    Id = document.Id,
                    Title = document.Title,
                    Description = document.Description,
                    Author = document.Author,
                    CreatedAt = document.CreatedAt,
                    ModifiedAt = document.ModifiedAt,
                    Status = document.Status.ToString()
                };

                return CreatedAtAction("GetDocument", "Documents", new { id = document.Id }, documentDto);
            }
            catch (KeyNotFoundException ex)
            {
                return NotFound(ex.Message);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "从模板创建文档时出错");
                return StatusCode(500, "创建文档时发生错误");
            }
        }

        [HttpPost("save-template")]
        public async Task<ActionResult<DocumentTemplateDto>> SaveTemplate([FromBody] SaveTemplateRequest request)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }

                // 这里需要先获取文档
                // 简化示例,实际中应该从数据库获取
                var document = new Document
                {
                    Id = request.DocumentId,
                    Title = "示例文档",
                    Description = request.Description,
                    Author = "当前用户"
                };

                var templateDoc = await _templateService.SaveTemplateAsync(
                    document,
                    request.Name,
                    request.Category);

                var templateDto = new DocumentTemplateDto
                {
                    Id = Guid.NewGuid(), // 实际应该返回真实ID
                    Name = request.Name,
                    Description = request.Description,
                    Category = request.Category,
                    CreatedAt = DateTime.UtcNow,
                    ModifiedAt = DateTime.UtcNow
                };

                return CreatedAtAction(nameof(GetTemplate), new { id = templateDto.Id }, templateDto);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "保存文档模板时出错");
                return StatusCode(500, "保存模板时发生错误");
            }
        }
    }

    // DTO类
    public class DocumentTemplateDto
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string Category { get; set; }
        public DateTime CreatedAt { get; set; }
        public DateTime ModifiedAt { get; set; }
    }

    public class DocumentDto
    {
        public Guid Id { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public string Author { get; set; }
        public DateTime CreatedAt { get; set; }
        public DateTime ModifiedAt { get; set; }
        public string Status { get; set; }
    }

    public class CreateDocumentRequest
    {
        public Guid TemplateId { get; set; }
        public string Title { get; set; }
        public string Author { get; set; }
    }

    public class SaveTemplateRequest
    {
        public Guid DocumentId { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string Category { get; set; }
    }
}
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// 5. 使用案例 - 文档客户端应用
namespace DocumentManagementSystem.Client
{
    public class DocumentClient
    {
        private readonly HttpClient _httpClient;
            
public DocumentClient(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }
    
    public async Task DemoAsync()
    {
        // 1. 获取可用模板
        Console.WriteLine("获取可用文档模板...");
        var templates = await GetTemplatesAsync();
        DisplayTemplates(templates);
        
        // 2. 选择一个模板
        Console.WriteLine("\n请选择一个模板 (输入编号):");
        int selectedIndex = int.Parse(Console.ReadLine() ?? "0");
        var selectedTemplate = templates[selectedIndex];
        
        // 3. 基于模板创建新文档
        Console.WriteLine($"\n正在基于模板 '{selectedTemplate.Name}' 创建新文档...");
        Console.WriteLine("请输入文档标题:");
        string title = Console.ReadLine() ?? "未命名文档";
        
        Console.WriteLine("请输入作者姓名:");
        string author = Console.ReadLine() ?? "未知作者";
        
        var newDocument = await CreateDocumentFromTemplateAsync(
            selectedTemplate.Id,
            title,
            author);
            
        Console.WriteLine($"\n文档创建成功! ID: {newDocument.Id}");
        DisplayDocument(newDocument);
        
        // 4. 编辑文档... (这里省略实际编辑逻辑)
        
        // 5. 保存为新模板
        Console.WriteLine("\n是否将当前文档保存为新模板? (y/n)");
        string response = Console.ReadLine() ?? "n";
        
        if (response.ToLower() == "y")
        {
            Console.WriteLine("请输入模板名称:");
            string templateName = Console.ReadLine() ?? "我的模板";
            
            Console.WriteLine("请输入模板描述:");
            string description = Console.ReadLine() ?? "自定义模板";
            
            Console.WriteLine("请输入模板分类:");
            string category = Console.ReadLine() ?? "自定义";
            
            var newTemplate = await SaveTemplateAsync(
                newDocument.Id,
                templateName,
                description,
                category);
                
            Console.WriteLine($"\n模板保存成功! ID: {newTemplate.Id}");
            Console.WriteLine($"名称: {newTemplate.Name}");
            Console.WriteLine($"描述: {newTemplate.Description}");
        }
    }
    
    private async Task<List<DocumentTemplateDto>> GetTemplatesAsync()
    {
        var response = await _httpClient.GetAsync("api/templates");
        response.EnsureSuccessStatusCode();
        
        var content = await response.Content.ReadAsStringAsync();
        return JsonSerializer.Deserialize<List<DocumentTemplateDto>>(content, 
            new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
    }
    
    private async Task<DocumentDto> CreateDocumentFromTemplateAsync(Guid templateId, string title, string author)
    {
        var request = new CreateDocumentRequest
        {
            TemplateId = templateId,
            Title = title,
            Author = author
        };
        
        var response = await _httpClient.PostAsJsonAsync("api/templates/create-document", request);
        response.EnsureSuccessStatusCode();
        
        var content = await response.Content.ReadAsStringAsync();
        return JsonSerializer.Deserialize<DocumentDto>(content, 
            new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
    }
    
    private async Task<DocumentTemplateDto> SaveTemplateAsync(Guid documentId, string name, string description, string category)
    {
        var request = new SaveTemplateRequest
        {
            DocumentId = documentId,
            Name = name,
            Description = description,
            Category = category
        };
        
        var response = await _httpClient.PostAsJsonAsync("api/templates/save-template", request);
        response.EnsureSuccessStatusCode();
        
        var content = await response.Content.ReadAsStringAsync();
        return JsonSerializer.Deserialize<DocumentTemplateDto>(content, 
            new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
    }
    
    private void DisplayTemplates(List<DocumentTemplateDto> templates)
    {
        Console.WriteLine("可用模板:");
        for (int i = 0; i < templates.Count; i++)
        {
            var template = templates[i];
            Console.WriteLine($"{i}. {template.Name} - {template.Description} [分类: {template.Category}]");
        }
    }
    
    private void DisplayDocument(DocumentDto document)
    {
        Console.WriteLine($"标题: {document.Title}");
        Console.WriteLine($"描述: {document.Description}");
        Console.WriteLine($"作者: {document.Author}");
        Console.WriteLine($"创建时间: {document.CreatedAt}");
        Console.WriteLine($"状态: {document.Status}");
    }
}
}
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// 6. 服务注册和依赖注入配置
namespace DocumentManagementSystem
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
           
    public IConfiguration Configuration { get; }
    
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        
        // 注册仓储服务
        services.AddScoped<IDocumentRepository, DocumentRepository>();
        services.AddScoped<ITemplateRepository, TemplateRepository>();
        
        // 注册业务服务
        services.AddScoped<ITemplateService, TemplateService>();
        
        // 注册初始化服务
        services.AddTransient<DefaultTemplateInitializer>();
        
        // 注册HTTP客户端
        services.AddHttpClient<DocumentClient>(client =>
        {
            client.BaseAddress = new Uri(Configuration["ApiBaseUrl"]);
        });
    }
    
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider)
    {
        // 基本配置...
        
        // 应用启动时初始化默认模板
        var initializer = serviceProvider.GetRequiredService<DefaultTemplateInitializer>();
        initializer.InitializeDefaultTemplatesAsync().GetAwaiter().GetResult();
    }
}
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

# 5. 单例模式

原理:
单例模式确保一个类只有一个实例,并提供一个全局访问点。单例模式一般用于系统中只需要一个实例来协调操作的情况。

思路:

  1. 将类的构造函数私有化,防止外部直接创建实例
  2. 在类内部创建一个私有静态实例
  3. 提供一个公共静态方法获取该实例

前辈经验:

  • 单例模式在需要严格控制资源访问的情况下非常有用
  • 在多线程环境下,需要特别注意线程安全问题
  • .NET中可以使用Lazy<T>实现线程安全的单例
  • 虽然单例模式使用广泛,但也容易被滥用,不要将其作为全局状态的替代品
  • 单例对测试不友好,考虑依赖注入而非硬编码的单例

业务场景:
配置管理器,负责加载和管理应用程序的配置信息,需要确保全局只有一个实例以避免重复加载和不一致。

简单实现:

// 简单的单例模式 - 饿汉式(不支持延迟加载)
public class ConfigurationManager
{
    // 私有静态实例,在类加载时创建
    private static readonly ConfigurationManager _instance = new ConfigurationManager();
    
    // 私有构造函数,防止外部实例化
    private ConfigurationManager()
    {
        Console.WriteLine("初始化配置管理器...");
        LoadConfiguration();
    }
    
    // 公共静态方法,提供全局访问点
    public static ConfigurationManager Instance => _instance;
    
    // 配置数据
    private Dictionary<string, string> _configuration = new Dictionary<string, string>();
    
    // 加载配置
    private void LoadConfiguration()
    {
        // 模拟从文件加载配置
        _configuration["DatabaseConnection"] = "Server=localhost;Database=MyDB;User Id=admin;Password=admin123;";
        _configuration["ApiEndpoint"] = "https://api.example.com/v1/";
        _configuration["MaxRetryCount"] = "3";
    }
    
    // 获取配置
    public string GetValue(string key)
    {
        if (_configuration.ContainsKey(key))
        {
            return _configuration[key];
        }
        return null;
    }
    
    // 设置配置
    public void SetValue(string key, string value)
    {
        _configuration[key] = value;
    }
}

// 客户端代码
public class Client
{
    public static void Main()
    {
        // 获取配置管理器实例
        ConfigurationManager configManager = ConfigurationManager.Instance;
        
        // 获取配置值
        string dbConnection = configManager.GetValue("DatabaseConnection");
        string apiEndpoint = configManager.GetValue("ApiEndpoint");
        
        Console.WriteLine($"数据库连接: {dbConnection}");
        Console.WriteLine($"API端点: {apiEndpoint}");
        
        // 更新配置
        configManager.SetValue("MaxRetryCount", "5");
        Console.WriteLine($"更新后的重试次数: {configManager.GetValue("MaxRetryCount")}");
        
        // 再次获取实例,验证是否是同一个实例
        ConfigurationManager anotherManager = ConfigurationManager.Instance;
        Console.WriteLine($"是否是同一个实例: {object.ReferenceEquals(configManager, anotherManager)}");
    }
}
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

复杂实现:

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Xml.Linq;
using Microsoft.Extensions.Configuration;

// 线程安全的单例模式 - 使用Lazy<T>
public sealed class ConfigurationManager
{
    // 使用Lazy<T>实现线程安全的延迟初始化
    private static readonly Lazy<ConfigurationManager> _instance = 
        new Lazy<ConfigurationManager>(() => new ConfigurationManager(), LazyThreadSafetyMode.ExecutionAndPublication);
    
    // 配置数据
    private IConfiguration _configuration;
    private Dictionary<string, object> _cache = new Dictionary<string, object>();
    private ReaderWriterLockSlim _cacheLock = new ReaderWriterLockSlim();
    private Timer _refreshTimer;
    private readonly TimeSpan _refreshInterval = TimeSpan.FromMinutes(10);
    
    // 事件
    public event EventHandler<ConfigurationChangedEventArgs> ConfigurationChanged;
    
    // 私有构造函数
    private ConfigurationManager()
    {
        LoadConfiguration();
        
        // 设置定时刷新
        _refreshTimer = new Timer(RefreshConfiguration, null, _refreshInterval, _refreshInterval);
    }
    
    // 公共静态属性,提供全局访问点
    public static ConfigurationManager Instance => _instance.Value;
    
    // 加载配置
    private void LoadConfiguration()
    {
        try
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
                .AddEnvironmentVariables();
                
            _configuration = builder.Build();
            
            Console.WriteLine("配置已加载");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"加载配置时出错: {ex.Message}");
            // 加载默认配置或重新抛出异常
            throw;
        }
    }
    
    // 定时刷新配置
    private void RefreshConfiguration(object state)
    {
        try
        {
            var oldConfig = _configuration;
            LoadConfiguration();
            
            // 通知配置变更
            OnConfigurationChanged(new ConfigurationChangedEventArgs
            {
                ChangedAt = DateTime.Now
            });
            
            // 清除缓存
            _cacheLock.EnterWriteLock();
            try
            {
                _cache.Clear();
            }
            finally
            {
                _cacheLock.ExitWriteLock();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"刷新配置时出错: {ex.Message}");
        }
    }
    
    // 配置变更事件
    protected virtual void OnConfigurationChanged(ConfigurationChangedEventArgs e)
    {
        ConfigurationChanged?.Invoke(this, e);
    }
    
    // 获取字符串配置
    public string GetValue(string key, string defaultValue = null)
    {
        return _configuration[key] ?? defaultValue;
    }
    
    // 获取强类型配置
    public T GetValue<T>(string key, T defaultValue = default)
    {
        _cacheLock.EnterUpgradeableReadLock();
        try
        {
            string cacheKey = $"{typeof(T).Name}_{key}";
            
            if (_cache.ContainsKey(cacheKey))
            {
                return (T)_cache[cacheKey];
            }
            
            T value = _configuration.GetValue<T>(key);
            if (EqualityComparer<T>.Default.Equals(value, default))
            {
                value = defaultValue;
            }
            
            _cacheLock.EnterWriteLock();
            try
            {
                _cache[cacheKey] = value;
            }
            finally
            {
                _cacheLock.ExitWriteLock();
            }
            
            return value;
        }
        finally
        {
            _cacheLock.ExitUpgradeableReadLock();
        }
    }
    
    // 获取配置节
    public IConfigurationSection GetSection(string key)
    {
        return _configuration.GetSection(key);
    }
    
    // 获取子节点配置对象
    public T GetOptions<T>(string sectionName) where T : class, new()
    {
        _cacheLock.EnterUpgradeableReadLock();
        try
        {
            string cacheKey = $"Options_{typeof(T).Name}_{sectionName}";
            
            if (_cache.ContainsKey(cacheKey))
            {
                return (T)_cache[cacheKey];
            }
            
            var options = new T();
            _configuration.GetSection(sectionName).Bind(options);
            
            _cacheLock.EnterWriteLock();
            try
            {
                _cache[cacheKey] = options;
            }
            finally
            {
                _cacheLock.ExitWriteLock();
            }
            
            return options;
        }
        finally
        {
            _cacheLock.ExitUpgradeableReadLock();
        }
    }
    
    // 手动刷新配置
    public void Refresh()
    {
        RefreshConfiguration(null);
    }
    
    // 设置配置(仅用于内存中,不持久化)
    public void SetValue(string key, string value)
    {
        _cacheLock.EnterWriteLock();
        try
        {
            // 这里只是修改内存中的值,实际应用中可能需要持久化到配置文件
            // 这需要额外的实现
            _configuration[key] = value;
            
            // 清除相关缓存
            var keysToRemove = new List<string>();
            foreach (var cacheKey in _cache.Keys)
            {
                if (cacheKey.EndsWith($"_{key}"))
                {
                    keysToRemove.Add(cacheKey);
                }
            }
            
            foreach (var cacheKey in keysToRemove)
            {
                _cache.Remove(cacheKey);
            }
        }
        finally
        {
            _cacheLock.ExitWriteLock();
        }
    }
    
    // 释放资源
    public void Dispose()
    {
        _refreshTimer?.Dispose();
        _cacheLock?.Dispose();
    }
}

// 配置变更事件参数
public class ConfigurationChangedEventArgs : EventArgs
{
    public DateTime ChangedAt { get; set; }
}

// 配置类示例
public class DatabaseOptions
{
    public string ConnectionString { get; set; }
    public int CommandTimeout { get; set; }
    public bool UsePooling { get; set; }
    public int MaxPoolSize { get; set; }
}

public class ApiOptions
{
    public string BaseUrl { get; set; }
    public string ApiKey { get; set; }
    public int Timeout { get; set; }
    public RetryPolicy RetryPolicy { get; set; }
}

public class RetryPolicy
{
    public int MaxRetries { get; set; }
    public int RetryInterval { get; set; }
}

// 客户端代码
public class Client
{
    public static void Main()
    {
        // 获取配置管理器实例
        ConfigurationManager configManager = ConfigurationManager.Instance;
        
        // 添加配置变更事件处理
        configManager.ConfigurationChanged += (sender, e) =>
        {
            Console.WriteLine($"配置已于 {e.ChangedAt} 更新");
        };
        
        // 获取简单配置值
        string appName = configManager.GetValue("AppName", "默认应用");
        int maxConnections = configManager.GetValue<int>("MaxConnections", 100);
        bool enableLogging = configManager.GetValue<bool>("EnableLogging", true);
        
        Console.WriteLine($"应用名称: {appName}");
        Console.WriteLine($"最大连接数: {maxConnections}");
        Console.WriteLine($"启用日志: {enableLogging}");
        
        // 获取复杂配置对象
        var dbOptions = configManager.GetOptions<DatabaseOptions>("Database");
        Console.WriteLine($"数据库连接: {dbOptions.ConnectionString}");
        Console.WriteLine($"命令超时: {dbOptions.CommandTimeout}秒");
        Console.WriteLine($"最大连接池: {dbOptions.MaxPoolSize}");
        
        var apiOptions = configManager.GetOptions<ApiOptions>("Api");
        Console.WriteLine($"API基地址: {apiOptions.BaseUrl}");
        Console.WriteLine($"最大重试次数: {apiOptions.RetryPolicy.MaxRetries}");
        
        // 模拟更新配置
        Console.WriteLine("\n更新配置值...");
        configManager.SetValue("AppName", "更新后的应用名称");
        
        // 获取更新后的值
        appName = configManager.GetValue("AppName");
        Console.WriteLine($"更新后的应用名称: {appName}");
        
        // 强制刷新配置
        Console.WriteLine("\n手动刷新配置...");
        configManager.Refresh();
        
        Console.WriteLine("\n按任意键退出");
        Console.ReadKey();
    }
}
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302

业务场景结合:

using System;
using System.Collections.Concurrent;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

// 1. 应用设置类
namespace MyApplication.Configuration
{
    // 数据库配置
    public class DatabaseSettings
    {
        public string ConnectionString { get; set; }
        public int CommandTimeout { get; set; } = 30;
        public bool EnableRetry { get; set; } = true;
        public int MaxRetryCount { get; set; } = 3;
        public int RetryDelay { get; set; } = 1000; // 毫秒
    }
    
    // 缓存配置
    public class CacheSettings
    {
        public bool Enabled { get; set; } = true;
        public string Provider { get; set; } = "Memory";
        public int ExpirationMinutes { get; set; } = 60;
        public string RedisConnection { get; set; }
    }
    
    // API配置
    public class ApiSettings
    {
        public string BaseUrl { get; set; }
        public string ApiKey { get; set; }
        public int TimeoutSeconds { get; set; } = 30;
        public bool UseCompression { get; set; } = true;
    }
    
    // 日志配置
    public class LogSettings
    {
        public string Level { get; set; } = "Information";
        public bool EnableConsole { get; set; } = true;
        public bool EnableFile { get; set; } = true;
        public string FilePath { get; set; } = "logs/app.log";
        public int RetentionDays { get; set; } = 7;
    }
    
    // 功能开关配置
    public class FeatureFlags
    {
        public bool EnableNewUserInterface { get; set; } = false;
        public bool EnableBetaFeatures { get; set; } = false;
        public bool EnablePerformanceMetrics { get; set; } = true;
    }
    
    // 安全配置
    public class SecuritySettings
    {
        public int PasswordExpirationDays { get; set; } = 90;
        public bool RequireTwoFactorAuth { get; set; } = false;
        public string JwtSecret { get; set; }
        public int JwtExpirationMinutes { get; set; } = 60;
    }
    
    // 应用整体配置
    public class AppSettings
    {
        public string ApplicationName { get; set; }
        public string Environment { get; set; }
        public string Version { get; set; }
        public DatabaseSettings Database { get; set; } = new DatabaseSettings();
        public CacheSettings Cache { get; set; } = new CacheSettings();
        public ApiSettings Api { get; set; } = new ApiSettings();
        public LogSettings Logging { get; set; } = new LogSettings();
        public FeatureFlags Features { get; set; } = new FeatureFlags();
        public SecuritySettings Security { get; set; } = new SecuritySettings();
    }
}

// 2. 配置管理器单例
namespace MyApplication.Configuration
{
    public sealed class AppConfigurationManager : IDisposable
    {
        // 单例实例
        private static readonly Lazy<AppConfigurationManager> _instance = 
            new Lazy<AppConfigurationManager>(() => new AppConfigurationManager(), LazyThreadSafetyMode.ExecutionAndPublication);
        
        // 公共访问点
        public static AppConfigurationManager Instance => _instance.Value;
        
        // 应用配置
        private AppSettings _appSettings;
        
        // 底层配置源
        private IConfiguration _configuration;
        
        // 缓存
        private readonly ConcurrentDictionary<string, object> _configCache = new ConcurrentDictionary<string, object>();
        
        // 配置变更监听
        private CancellationTokenSource _watcherCts;
        private Task _watcherTask;
        
        // 日志
        private ILogger<AppConfigurationManager> _logger;
        
        // 事件
        public event EventHandler<ConfigChangedEventArgs> ConfigurationChanged;
        
        // 私有构造函数
        private AppConfigurationManager()
        {
            Initialize();
        }
        
        // 初始化配置
        private void Initialize()
        {
            try
            {
                var loggerFactory = LoggerFactory.Create(builder =>
                {
                    builder.AddConsole();
                });
                _logger = loggerFactory.CreateLogger<AppConfigurationManager>();
                
                _logger.LogInformation("初始化应用配置管理器");
                
                LoadConfiguration();
                StartConfigurationWatcher();
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "初始化配置管理器时出错");
                throw;
            }
        }
        
        // 加载配置
        private void LoadConfiguration()
        {
            try
            {
                string environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production";
                
                var builder = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                    .AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true)
                    .AddEnvironmentVariables();
                
                // 添加用户机密(仅开发环境)
                if (environment == "Development")
                {
                    builder.AddUserSecrets<AppConfigurationManager>();
                }
                
                _configuration = builder.Build();
                
                // 绑定到AppSettings对象
                _appSettings = new AppSettings();
                _configuration.Bind(_appSettings);
                
                _logger?.LogInformation("配置已加载: {Environment}", environment);
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "加载配置时出错");
                // 使用默认配置
                _appSettings = new AppSettings
                {
                    ApplicationName = "应用程序(默认配置)",
                    Environment = "Unknown"
                };
            }
        }
        
        // 监视配置变更
        private void StartConfigurationWatcher()
        {
            _watcherCts = new CancellationTokenSource();
            _watcherTask = Task.Run(async () =>
            {
                while (!_watcherCts.Token.IsCancellationRequested)
                {
                    try
                    {
                        // 等待一小段时间
                        await Task.Delay(5000, _watcherCts.Token);
                        
                        // 重新加载配置并检查变更
                        var newSettings = new AppSettings();
                        _configuration.Bind(newSettings);
                        
                        // 对比新旧配置,检测变更
                        bool hasChanges = false;
                        
                        // 简化示例,实际应该进行深度比较
                        if (_appSettings.Database.ConnectionString != newSettings.Database.ConnectionString ||
                            _appSettings.Features.EnableNewUserInterface != newSettings.Features.EnableNewUserInterface)
                        {
                            hasChanges = true;
                        }
                        
                        if (hasChanges)
                        {
                            _logger?.LogInformation("检测到配置变更");
                            
                            // 更新配置
                            _appSettings = newSettings;
                            _configCache.Clear();
                            
                            // 触发事件
                            OnConfigurationChanged(new ConfigChangedEventArgs
                            {
                                ChangedAt = DateTime.UtcNow
                            });
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        // 正常取消
                        break;
                    }
                    catch (Exception ex)
                    {
                        _logger?.LogError(ex, "监视配置变更时出错");
                    }
                }
            }, _watcherCts.Token);
        }
        
        // 触发配置变更事件
        private void OnConfigurationChanged(ConfigChangedEventArgs e)
        {
            ConfigurationChanged?.Invoke(this, e);
        }
        
        // 获取应用设置
        public AppSettings GetAppSettings()
        {
            return _appSettings;
        }
        
        // 获取数据库设置
        public DatabaseSettings GetDatabaseSettings()
        {
            return _appSettings.Database;
        }
        
        // 获取缓存设置
        public CacheSettings GetCacheSettings()
        {
            return _appSettings.Cache;
        }
        
        // 获取API设置
        public ApiSettings GetApiSettings()
        {
            return _appSettings.Api;
        }
        
        // 获取日志设置
        public LogSettings GetLogSettings()
        {
            return _appSettings.Logging;
        }
        
        // 获取功能开关
        public FeatureFlags GetFeatureFlags()
        {
            return _appSettings.Features;
        }
        
        // 获取安全设置
        public SecuritySettings GetSecuritySettings()
        {
            return _appSettings.Security;
        }
        
        // 检查功能是否启用
        public bool IsFeatureEnabled(string featureName)
        {
            // 基于反射获取功能开关值
            var featureProperty = typeof(FeatureFlags).GetProperty(featureName);
            if (featureProperty != null && featureProperty.PropertyType == typeof(bool))
            {
                return (bool)featureProperty.GetValue(_appSettings.Features);
            }
            
            return false;
        }
        
        // 重新加载配置
        public void Reload()
        {
            _logger?.LogInformation("手动重新加载配置");
            LoadConfiguration();
            _configCache.Clear();
            
            OnConfigurationChanged(new ConfigChangedEventArgs
            {
                ChangedAt = DateTime.UtcNow,
                IsManualReload = true
            });
        }
        
        // 获取原始配置值
        public T GetValue<T>(string key, T defaultValue = default)
        {
            string cacheKey = $"{typeof(T).Name}_{key}";
            
            return (T)_configCache.GetOrAdd(cacheKey, _ =>
            {
                T value = _configuration.GetValue<T>(key);
                if (EqualityComparer<T>.Default.Equals(value, default))
                {
                    return defaultValue;
                }
                return value;
            });
        }
        
        // 获取配置节
        public IConfigurationSection GetSection(string key)
        {
            return _configuration.GetSection(key);
        }
        
        // 释放资源
        public void Dispose()
        {
            _watcherCts?.Cancel();
            try
            {
                _watcherTask?.Wait(1000);
            }
            catch (Exception ex)
            {
                _logger?.LogWarning(ex, "等待配置监视任务结束时出错");
            }
            
            _watcherCts?.Dispose();
            _watcherCts = null;
            _watcherTask = null;
        }
    }
    
    // 配置变更事件参数
    public class ConfigChangedEventArgs : EventArgs
    {
        public DateTime ChangedAt { get; set; }
        public bool IsManualReload { get; set; }
    }
}

// 3. 配置提供者(用于依赖注入)
namespace MyApplication.Configuration
{
    public interface IAppConfigurationProvider
    {
        AppSettings GetAppSettings();
        DatabaseSettings GetDatabaseSettings();
        CacheSettings GetCacheSettings();
        ApiSettings GetApiSettings();
        LogSettings GetLogSettings();
        FeatureFlags GetFeatureFlags();
        SecuritySettings GetSecuritySettings();
        bool IsFeatureEnabled(string featureName);
        void Reload();
    }
    
    public class AppConfigurationProvider : IAppConfigurationProvider
    {
        public AppSettings GetAppSettings() => AppConfigurationManager.Instance.GetAppSettings();
        public DatabaseSettings GetDatabaseSettings() => AppConfigurationManager.Instance.GetDatabaseSettings();
        public CacheSettings GetCacheSettings() => AppConfigurationManager.Instance.GetCacheSettings();
        public ApiSettings GetApiSettings() => AppConfigurationManager.Instance.GetApiSettings();
        public LogSettings GetLogSettings() => AppConfigurationManager.Instance.GetLogSettings();
        public FeatureFlags GetFeatureFlags() => AppConfigurationManager.Instance.GetFeatureFlags();
        public SecuritySettings GetSecuritySettings() => AppConfigurationManager.Instance.GetSecuritySettings();
        public bool IsFeatureEnabled(string featureName) => AppConfigurationManager.Instance.IsFeatureEnabled(featureName);
        public void Reload() => AppConfigurationManager.Instance.Reload();
    }
}

// 4. 服务扩展 - 注册配置服务
namespace MyApplication.Configuration
{
    public static class ServiceCollectionExtensions
    {
        public static IServiceCollection AddAppConfiguration(this IServiceCollection services)
        {
            // 添加单例配置提供者
            services.AddSingleton<IAppConfigurationProvider, AppConfigurationProvider>();
            
            // 从单例获取配置并注册为服务
            var appSettings = AppConfigurationManager.Instance.GetAppSettings();
            
            services.AddSingleton(appSettings);
            services.AddSingleton(appSettings.Database);
            services.AddSingleton(appSettings.Cache);
            services.AddSingleton(appSettings.Api);
            services.AddSingleton(appSettings.Logging);
            services.AddSingleton(appSettings.Features);
            services.AddSingleton(appSettings.Security);
            
            return services;
        }
    }
}

// 5. 使用配置管理器的数据库服务示例
namespace MyApplication.Services
{
    public interface IDatabaseService
    {
        Task<bool> ConnectAsync();
        Task<int> ExecuteQueryAsync(string sql, object parameters = null);
    }
    
    public class DatabaseService : IDatabaseService
    {
        private readonly ILogger<DatabaseService> _logger;
        private readonly DatabaseSettings _settings;
        private readonly IAppConfigurationProvider _configProvider;
        
        // 构造函数注入配置
        public DatabaseService(
            ILogger<DatabaseService> logger,
            DatabaseSettings settings,
            IAppConfigurationProvider configProvider)
        {
            _logger = logger;
            _settings = settings;
            _configProvider = configProvider;
            
            // 注册配置变更事件
            AppConfigurationManager.Instance.ConfigurationChanged += OnConfigurationChanged;
        }
        
        private void OnConfigurationChanged(object sender, ConfigChangedEventArgs e)
        {
            // 获取最新配置
            var newSettings = _configProvider.GetDatabaseSettings();
            
            // 检查关键配置是否变化
            if (_settings.ConnectionString != newSettings.ConnectionString)
            {
                _logger.LogInformation("数据库连接配置已更改,重新初始化连接...");
                // 执行重新连接逻辑...
            }
        }
        
        public async Task<bool> ConnectAsync()
        {
            try
            {
                _logger.LogInformation("连接到数据库: {ConnectionString}", 
                    MaskConnectionString(_settings.ConnectionString));
                
                // 模拟连接
                await Task.Delay(100);
                
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "连接数据库时出错");
                return false;
            }
        }
        
        public async Task<int> ExecuteQueryAsync(string sql, object parameters = null)
        {
            try
            {
                _logger.LogDebug("执行SQL: {Sql}", sql);
                
                // 检查是否启用重试
                int maxRetries = _settings.EnableRetry ? _settings.MaxRetryCount : 0;
                
                // 实现重试逻辑
                for (int attempt = 0; attempt <= maxRetries; attempt++)
                {
                    try
                    {
                        // 模拟查询执行
                        await Task.Delay(50);
                        return 1; // 假设影响了1行
                    }
                    catch (Exception ex)
                    {
                        if (attempt == maxRetries)
                        {
                            throw;
                        }
                        
                        _logger.LogWarning(ex, "执行查询失败,尝试重试 {Attempt}/{MaxRetries}", 
                            attempt + 1, maxRetries);
                        
                        // 等待重试
                        await Task.Delay(_settings.RetryDelay);
                    }
                }
                
                return 0;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "执行查询时出错");
                throw;
            }
        }
        
        // 掩盖连接字符串中的敏感信息
        private string MaskConnectionString(string connectionString)
        {
            if (string.IsNullOrEmpty(connectionString))
                return connectionString;
                
            // 简单地替换密码
            return System.Text.RegularExpressions.Regex.Replace(
                connectionString,
                "Password=([^;]*)",
                "Password=****");
        }
    }
}

// 6. API控制器示例
namespace MyApplication.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ConfigurationController : ControllerBase
    {
        private readonly IAppConfigurationProvider _configProvider;
        private readonly ILogger<ConfigurationController> _logger;
        
        public ConfigurationController(
            IAppConfigurationProvider configProvider,
            ILogger<ConfigurationController> logger)
        {
            _configProvider = configProvider;
            _logger = logger;
        }
        
        [HttpGet]
        public ActionResult<ConfigurationViewModel> GetConfiguration()
        {
            // 获取非敏感配置
            var appSettings = _configProvider.GetAppSettings();
            var featureFlags = _configProvider.GetFeatureFlags();
            
            return new ConfigurationViewModel
            {
                ApplicationName = appSettings.ApplicationName,
                Environment = appSettings.Environment,
                Version = appSettings.Version,
                FeatureFlags = new FeatureFlagsViewModel
                {
                    EnableNewUserInterface = featureFlags.EnableNewUserInterface,
                    EnableBetaFeatures = featureFlags.EnableBetaFeatures,
                    EnablePerformanceMetrics = featureFlags.EnablePerformanceMetrics
                }
            };
        }
        
        [HttpPost("reload")]
        [Authorize(Roles = "Administrator")]
        public IActionResult ReloadConfiguration()
        {
            try
            {
                _logger.LogInformation("手动重新加载配置");
                _configProvider.Reload();
                return Ok(new { message = "配置已重新加载" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "重新加载配置时出错");
                return StatusCode(500, new { error = "重新加载配置时出错" });
            }
        }
    }
    
    public class ConfigurationViewModel
    {
        public string ApplicationName { get; set; }
        public string Environment { get; set; }
        public string Version { get; set; }
        public FeatureFlagsViewModel FeatureFlags { get; set; }
    }
    
    public class FeatureFlagsViewModel
    {
        public bool EnableNewUserInterface { get; set; }
        public bool EnableBetaFeatures { get; set; }
        public bool EnablePerformanceMetrics { get; set; }
    }
}

// 7. 应用程序启动配置
namespace MyApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            // 确保配置管理器已初始化
            var configManager = AppConfigurationManager.Instance;
            
            CreateHostBuilder(args).Build().Run();
        }
        
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                })
                .ConfigureLogging((hostContext, logging) =>
                {
                    // 从配置管理器获取日志设置
                    var logSettings = AppConfigurationManager.Instance.GetLogSettings();
                    
                    // 配置日志级别
                    var logLevel = Enum.Parse<LogLevel>(logSettings.Level, true);
                    logging.SetMinimumLevel(logLevel);
                    
                    // 添加控制台日志
                    if (logSettings.EnableConsole)
                    {
                        logging.AddConsole();
                    }
                    
                    // 添加文件日志
                    if (logSettings.EnableFile)
                    {
                        logging.AddFile(logSettings.FilePath, options =>
                        {
                            options.RetainedFileCountLimit = logSettings.RetentionDays;
                        });
                    }
                });
    }
    
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            // 添加配置服务
            services.AddAppConfiguration();
            
            // 添加其他服务
            services.AddScoped<IDatabaseService, DatabaseService>();
            
            services.AddControllers();
        }
        
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            // 获取环境信息
            var appSettings = AppConfigurationManager.Instance.GetAppSettings();
            
            if (env.IsDevelopment() || appSettings.Environment.ToLower() == "development")
            {
                app.UseDeveloperExceptionPage();
            }
            
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthorization();
            
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
            
            // 输出应用启动信息
            var logger = app.ApplicationServices.GetRequiredService<ILogger<Startup>>();
            logger.LogInformation("应用 {AppName} v{Version} 已启动,环境: {Environment}",
                appSettings.ApplicationName,
                appSettings.Version,
                appSettings.Environment);
        }
    }
}
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
编辑 (opens new window)
#pattern
上次更新: 2026/03/11, 07:20:31
SOLID原则
结构型

← SOLID原则 结构型→

最近更新
01
鉴权服务中心
03-11
02
聚合根
03-11
03
补充
02-06
更多文章>
Theme by Vdoing | Copyright © 2019-2026 moklgy's blog
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式