其他模式与组合使用
# C#设计模式全面指南
# 状态模式 (State Pattern)
# 原理思路
状态模式允许对象在内部状态改变时改变其行为,对象看起来好像修改了它的类。
# 前辈经验 - 业务场景
- 订单状态管理(待支付→已支付→已发货→已完成)
- 游戏角色状态(正常→中毒→眩晕→死亡)
- 工作流引擎状态转换
- TCP连接状态管理
# 简单实现
// 状态接口
public interface IOrderState
{
void Handle(OrderContext context);
string GetStateName();
}
// 具体状态:待支付
public class PendingPaymentState : IOrderState
{
public void Handle(OrderContext context)
{
Console.WriteLine("处理支付...");
context.SetState(new PaidState());
}
public string GetStateName() => "待支付";
}
// 具体状态:已支付
public class PaidState : IOrderState
{
public void Handle(OrderContext context)
{
Console.WriteLine("安排发货...");
context.SetState(new ShippedState());
}
public string GetStateName() => "已支付";
}
// 具体状态:已发货
public class ShippedState : IOrderState
{
public void Handle(OrderContext context)
{
Console.WriteLine("确认收货...");
context.SetState(new DeliveredState());
}
public string GetStateName() => "已发货";
}
// 具体状态:已完成
public class DeliveredState : IOrderState
{
public void Handle(OrderContext context)
{
Console.WriteLine("订单已完成,无法继续操作");
}
public string GetStateName() => "已完成";
}
// 上下文
public class OrderContext
{
private IOrderState _state;
public OrderContext()
{
_state = new PendingPaymentState();
}
public void SetState(IOrderState state)
{
_state = state;
Console.WriteLine($"订单状态变更为: {_state.GetStateName()}");
}
public void ProcessNext()
{
_state.Handle(this);
}
public string GetCurrentState()
{
return _state.GetStateName();
}
}
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
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
# 复杂实现
using System;
using System.Collections.Generic;
// 抽象状态类
public abstract class GameCharacterState
{
protected GameCharacter character;
public GameCharacterState(GameCharacter character)
{
this.character = character;
}
public abstract void Attack();
public abstract void TakeDamage(int damage);
public abstract void UseSkill();
public abstract void Update();
public abstract string GetStateName();
}
// 正常状态
public class NormalState : GameCharacterState
{
public NormalState(GameCharacter character) : base(character) { }
public override void Attack()
{
Console.WriteLine($"{character.Name} 发动普通攻击,造成 {character.Attack} 点伤害");
}
public override void TakeDamage(int damage)
{
character.Health -= damage;
Console.WriteLine($"{character.Name} 受到 {damage} 点伤害,剩余血量: {character.Health}");
if (character.Health <= 0)
{
character.ChangeState(new DeadState(character));
}
else if (damage > 50)
{
character.ChangeState(new StunnedState(character, 2));
}
}
public override void UseSkill()
{
if (character.Mana >= 30)
{
character.Mana -= 30;
Console.WriteLine($"{character.Name} 使用技能!造成 {character.Attack * 2} 点伤害");
}
else
{
Console.WriteLine($"{character.Name} 魔法值不足,无法使用技能");
}
}
public override void Update()
{
// 正常状态下恢复魔法值
if (character.Mana < character.MaxMana)
{
character.Mana = Math.Min(character.MaxMana, character.Mana + 5);
}
}
public override string GetStateName() => "正常";
}
// 眩晕状态
public class StunnedState : GameCharacterState
{
private int stunDuration;
public StunnedState(GameCharacter character, int duration) : base(character)
{
stunDuration = duration;
Console.WriteLine($"{character.Name} 被眩晕了!持续 {duration} 回合");
}
public override void Attack()
{
Console.WriteLine($"{character.Name} 处于眩晕状态,无法攻击");
}
public override void TakeDamage(int damage)
{
// 眩晕状态下受到额外伤害
int actualDamage = (int)(damage * 1.5f);
character.Health -= actualDamage;
Console.WriteLine($"{character.Name} 眩晕中受到 {actualDamage} 点伤害(+50%),剩余血量: {character.Health}");
if (character.Health <= 0)
{
character.ChangeState(new DeadState(character));
}
}
public override void UseSkill()
{
Console.WriteLine($"{character.Name} 处于眩晕状态,无法使用技能");
}
public override void Update()
{
stunDuration--;
if (stunDuration <= 0)
{
Console.WriteLine($"{character.Name} 从眩晕中恢复");
character.ChangeState(new NormalState(character));
}
else
{
Console.WriteLine($"{character.Name} 还剩 {stunDuration} 回合眩晕");
}
}
public override string GetStateName() => $"眩晕({stunDuration})";
}
// 中毒状态
public class PoisonedState : GameCharacterState
{
private int poisonDuration;
private int poisonDamage;
public PoisonedState(GameCharacter character, int duration, int damage) : base(character)
{
poisonDuration = duration;
poisonDamage = damage;
Console.WriteLine($"{character.Name} 中毒了!每回合受到 {damage} 点伤害,持续 {duration} 回合");
}
public override void Attack()
{
// 中毒状态下攻击力减半
Console.WriteLine($"{character.Name} 中毒状态下发动攻击,造成 {character.Attack / 2} 点伤害");
}
public override void TakeDamage(int damage)
{
character.Health -= damage;
Console.WriteLine($"{character.Name} 受到 {damage} 点伤害,剩余血量: {character.Health}");
if (character.Health <= 0)
{
character.ChangeState(new DeadState(character));
}
}
public override void UseSkill()
{
Console.WriteLine($"{character.Name} 中毒状态下无法集中精神使用技能");
}
public override void Update()
{
// 中毒伤害
character.Health -= poisonDamage;
Console.WriteLine($"{character.Name} 受到毒素伤害 {poisonDamage} 点,剩余血量: {character.Health}");
if (character.Health <= 0)
{
character.ChangeState(new DeadState(character));
return;
}
poisonDuration--;
if (poisonDuration <= 0)
{
Console.WriteLine($"{character.Name} 毒素消散,恢复正常");
character.ChangeState(new NormalState(character));
}
else
{
Console.WriteLine($"{character.Name} 还剩 {poisonDuration} 回合中毒");
}
}
public override string GetStateName() => $"中毒({poisonDuration})";
}
// 死亡状态
public class DeadState : GameCharacterState
{
public DeadState(GameCharacter character) : base(character)
{
Console.WriteLine($"{character.Name} 死亡了!");
}
public override void Attack()
{
Console.WriteLine($"{character.Name} 已死亡,无法攻击");
}
public override void TakeDamage(int damage)
{
Console.WriteLine($"{character.Name} 已死亡,无法受到伤害");
}
public override void UseSkill()
{
Console.WriteLine($"{character.Name} 已死亡,无法使用技能");
}
public override void Update()
{
Console.WriteLine($"{character.Name} 躺在地上一动不动...");
}
public override string GetStateName() => "死亡";
}
// 角色类
public class GameCharacter
{
public string Name { get; set; }
public int Health { get; set; }
public int MaxHealth { get; set; }
public int Mana { get; set; }
public int MaxMana { get; set; }
public int Attack { get; set; }
private GameCharacterState state;
public GameCharacter(string name, int health, int mana, int attack)
{
Name = name;
Health = MaxHealth = health;
Mana = MaxMana = mana;
Attack = attack;
state = new NormalState(this);
}
public void ChangeState(GameCharacterState newState)
{
state = newState;
}
public void PerformAttack() => state.Attack();
public void TakeDamage(int damage) => state.TakeDamage(damage);
public void UseSkill() => state.UseSkill();
public void Update() => state.Update();
public string GetStatus() => $"{Name} - 血量: {Health}/{MaxHealth}, 魔法: {Mana}/{MaxMana}, 状态: {state.GetStateName()}";
// 特殊方法:施加中毒
public void ApplyPoison(int duration, int damage)
{
if (!(state is DeadState))
{
ChangeState(new PoisonedState(this, duration, damage));
}
}
}
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
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
# 策略模式 (Strategy Pattern)
# 原理思路
策略模式定义一系列算法,把它们一个个封装起来,并且使它们可相互替换。
# 前辈经验 - 业务场景
- 支付系统(支付宝、微信、银行卡)
- 排序算法选择
- 游戏AI行为策略
- 促销折扣计算
# 简单实现
// 策略接口
public interface IPaymentStrategy
{
void Pay(decimal amount);
}
// 具体策略:支付宝支付
public class AlipayStrategy : IPaymentStrategy
{
private string account;
public AlipayStrategy(string account)
{
this.account = account;
}
public void Pay(decimal amount)
{
Console.WriteLine($"使用支付宝账户 {account} 支付 {amount:C}");
}
}
// 具体策略:微信支付
public class WeChatPayStrategy : IPaymentStrategy
{
private string phoneNumber;
public WeChatPayStrategy(string phoneNumber)
{
this.phoneNumber = phoneNumber;
}
public void Pay(decimal amount)
{
Console.WriteLine($"使用微信账户 {phoneNumber} 支付 {amount:C}");
}
}
// 具体策略:银行卡支付
public class CreditCardStrategy : IPaymentStrategy
{
private string cardNumber;
public CreditCardStrategy(string cardNumber)
{
this.cardNumber = cardNumber;
}
public void Pay(decimal amount)
{
Console.WriteLine($"使用信用卡 ****{cardNumber.Substring(cardNumber.Length - 4)} 支付 {amount:C}");
}
}
// 上下文
public class PaymentContext
{
private IPaymentStrategy strategy;
public void SetStrategy(IPaymentStrategy strategy)
{
this.strategy = strategy;
}
public void ProcessPayment(decimal amount)
{
if (strategy == null)
{
Console.WriteLine("请选择支付方式");
return;
}
strategy.Pay(amount);
}
}
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
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
# 复杂实现
using System;
using System.Collections.Generic;
using System.Linq;
// 抽象策略:排序策略
public abstract class SortStrategy<T> where T : IComparable<T>
{
public abstract void Sort(List<T> data);
public abstract string GetName();
public abstract string GetTimeComplexity();
public abstract string GetSpaceComplexity();
}
// 具体策略:冒泡排序
public class BubbleSortStrategy<T> : SortStrategy<T> where T : IComparable<T>
{
public override void Sort(List<T> data)
{
int n = data.Count;
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - i - 1; j++)
{
if (data[j].CompareTo(data[j + 1]) > 0)
{
T temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
}
}
public override string GetName() => "冒泡排序";
public override string GetTimeComplexity() => "O(n²)";
public override string GetSpaceComplexity() => "O(1)";
}
// 具体策略:快速排序
public class QuickSortStrategy<T> : SortStrategy<T> where T : IComparable<T>
{
public override void Sort(List<T> data)
{
QuickSort(data, 0, data.Count - 1);
}
private void QuickSort(List<T> data, int low, int high)
{
if (low < high)
{
int pi = Partition(data, low, high);
QuickSort(data, low, pi - 1);
QuickSort(data, pi + 1, high);
}
}
private int Partition(List<T> data, int low, int high)
{
T pivot = data[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++)
{
if (data[j].CompareTo(pivot) < 0)
{
i++;
T temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
T temp2 = data[i + 1];
data[i + 1] = data[high];
data[high] = temp2;
return (i + 1);
}
public override string GetName() => "快速排序";
public override string GetTimeComplexity() => "O(n log n)";
public override string GetSpaceComplexity() => "O(log n)";
}
// 具体策略:归并排序
public class MergeSortStrategy<T> : SortStrategy<T> where T : IComparable<T>
{
public override void Sort(List<T> data)
{
MergeSort(data, 0, data.Count - 1);
}
private void MergeSort(List<T> data, int left, int right)
{
if (left < right)
{
int mid = left + (right - left) / 2;
MergeSort(data, left, mid);
MergeSort(data, mid + 1, right);
Merge(data, left, mid, right);
}
}
private void Merge(List<T> data, int left, int mid, int right)
{
int n1 = mid - left + 1;
int n2 = right - mid;
T[] leftArray = new T[n1];
T[] rightArray = new T[n2];
Array.Copy(data.ToArray(), left, leftArray, 0, n1);
Array.Copy(data.ToArray(), mid + 1, rightArray, 0, n2);
int i = 0, j = 0, k = left;
while (i < n1 && j < n2)
{
if (leftArray[i].CompareTo(rightArray[j]) <= 0)
{
data[k] = leftArray[i];
i++;
}
else
{
data[k] = rightArray[j];
j++;
}
k++;
}
while (i < n1)
{
data[k] = leftArray[i];
i++;
k++;
}
while (j < n2)
{
data[k] = rightArray[j];
j++;
k++;
}
}
public override string GetName() => "归并排序";
public override string GetTimeComplexity() => "O(n log n)";
public override string GetSpaceComplexity() => "O(n)";
}
// 排序上下文
public class SortContext<T> where T : IComparable<T>
{
private SortStrategy<T> strategy;
public void SetStrategy(SortStrategy<T> strategy)
{
this.strategy = strategy;
}
public void Sort(List<T> data)
{
if (strategy == null)
{
Console.WriteLine("请设置排序策略");
return;
}
Console.WriteLine($"使用 {strategy.GetName()} 进行排序");
Console.WriteLine($"时间复杂度: {strategy.GetTimeComplexity()}, 空间复杂度: {strategy.GetSpaceComplexity()}");
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
strategy.Sort(data);
stopwatch.Stop();
Console.WriteLine($"排序完成,耗时: {stopwatch.ElapsedMilliseconds} ms");
}
public SortStrategy<T> GetCurrentStrategy() => strategy;
}
// 策略选择器
public class SortStrategySelector<T> where T : IComparable<T>
{
public static SortStrategy<T> SelectBestStrategy(int dataSize)
{
if (dataSize < 10)
{
return new BubbleSortStrategy<T>(); // 小数据量用冒泡排序
}
else if (dataSize < 1000)
{
return new QuickSortStrategy<T>(); // 中等数据量用快速排序
}
else
{
return new MergeSortStrategy<T>(); // 大数据量用归并排序
}
}
}
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
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
# 模板方法模式 (Template Method Pattern)
# 原理思路
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。
# 前辈经验 - 业务场景
- 数据处理流程(ETL:提取→转换→加载)
- 游戏关卡流程(开始→游戏逻辑→结束)
- 订单处理流程
- 测试框架(setUp→test→tearDown)
# 简单实现
// 抽象模板类
public abstract class DataProcessor
{
// 模板方法
public void ProcessData()
{
LoadData();
ValidateData();
TransformData();
SaveData();
CleanUp();
}
protected abstract void LoadData();
protected abstract void TransformData();
protected abstract void SaveData();
protected virtual void ValidateData()
{
Console.WriteLine("执行基本数据验证");
}
protected virtual void CleanUp()
{
Console.WriteLine("清理临时资源");
}
}
// 具体实现:CSV数据处理
public class CsvDataProcessor : DataProcessor
{
protected override void LoadData()
{
Console.WriteLine("从CSV文件加载数据");
}
protected override void TransformData()
{
Console.WriteLine("转换CSV数据格式");
}
protected override void SaveData()
{
Console.WriteLine("保存数据到数据库");
}
}
// 具体实现:JSON数据处理
public class JsonDataProcessor : DataProcessor
{
protected override void LoadData()
{
Console.WriteLine("从JSON文件加载数据");
}
protected override void TransformData()
{
Console.WriteLine("解析并转换JSON数据");
}
protected override void SaveData()
{
Console.WriteLine("保存数据到缓存");
}
protected override void ValidateData()
{
base.ValidateData();
Console.WriteLine("执行JSON schema验证");
}
}
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
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
# 复杂实现
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
// 抽象游戏关卡模板
public abstract class GameLevel
{
protected string levelName;
protected int difficulty;
protected TimeSpan timeLimit;
protected int score;
protected List<string> events;
public GameLevel(string name, int difficulty, TimeSpan timeLimit)
{
levelName = name;
this.difficulty = difficulty;
this.timeLimit = timeLimit;
score = 0;
events = new List<string>();
}
// 模板方法:定义关卡流程
public async Task<GameResult> PlayLevel()
{
var startTime = DateTime.Now;
try
{
// 1. 关卡初始化
InitializeLevel();
// 2. 显示开场动画
await ShowIntroduction();
// 3. 玩家准备
if (!await PlayerReady())
{
return new GameResult { Success = false, Reason = "玩家取消游戏" };
}
// 4. 主要游戏循环
var gameResult = await ExecuteGameLogic();
// 5. 计算分数
CalculateFinalScore(DateTime.Now - startTime);
// 6. 显示结束画面
await ShowConclusion(gameResult);
// 7. 清理资源
CleanupLevel();
return gameResult;
}
catch (Exception ex)
{
LogEvent($"关卡异常: {ex.Message}");
EmergencyCleanup();
return new GameResult { Success = false, Reason = ex.Message };
}
}
// 抽象方法:子类必须实现
protected abstract void InitializeLevel();
protected abstract Task<GameResult> ExecuteGameLogic();
protected abstract void SetupEnemies();
protected abstract void ConfigurePowerUps();
// 钩子方法:子类可以选择重写
protected virtual async Task ShowIntroduction()
{
LogEvent($"欢迎来到 {levelName}!");
LogEvent($"难度等级: {difficulty}");
LogEvent($"时间限制: {timeLimit.TotalMinutes} 分钟");
await Task.Delay(2000); // 模拟动画时间
}
protected virtual async Task<bool> PlayerReady()
{
LogEvent("按任意键开始游戏...");
await Task.Delay(1000); // 模拟等待玩家输入
return true; // 简化实现,总是返回true
}
protected virtual void CalculateFinalScore(TimeSpan elapsed)
{
int timeBonus = Math.Max(0, (int)(timeLimit.TotalSeconds - elapsed.TotalSeconds) * 10);
int difficultyBonus = difficulty * 100;
score += timeBonus + difficultyBonus;
LogEvent($"最终得分: {score} (时间奖励: {timeBonus}, 难度奖励: {difficultyBonus})");
}
protected virtual async Task ShowConclusion(GameResult result)
{
LogEvent($"关卡结束!");
LogEvent($"结果: {(result.Success ? "成功" : "失败")}");
if (!result.Success && !string.IsNullOrEmpty(result.Reason))
{
LogEvent($"失败原因: {result.Reason}");
}
LogEvent($"本关得分: {score}");
await Task.Delay(3000); // 模拟结束动画
}
protected virtual void CleanupLevel()
{
LogEvent("清理关卡资源");
}
protected virtual void EmergencyCleanup()
{
LogEvent("紧急清理资源");
}
protected void LogEvent(string message)
{
var timestamp = DateTime.Now.ToString("HH:mm:ss");
var logMessage = $"[{timestamp}] {levelName}: {message}";
events.Add(logMessage);
Console.WriteLine(logMessage);
}
public List<string> GetEventLog() => new List<string>(events);
public int GetScore() => score;
}
// 具体关卡:射击关卡
public class ShootingLevel : GameLevel
{
private int enemyCount;
private int enemiesKilled;
private List<string> enemies;
public ShootingLevel(string name, int difficulty, TimeSpan timeLimit)
: base(name, difficulty, timeLimit)
{
enemies = new List<string>();
}
protected override void InitializeLevel()
{
LogEvent("初始化射击关卡");
SetupEnemies();
ConfigurePowerUps();
LogEvent($"生成了 {enemyCount} 个敌人");
}
protected override void SetupEnemies()
{
enemyCount = difficulty * 5; // 根据难度生成敌人
enemiesKilled = 0;
for (int i = 0; i < enemyCount; i++)
{
enemies.Add($"敌人{i + 1}");
}
}
protected override void ConfigurePowerUps()
{
LogEvent("配置武器升级道具");
// 根据难度配置不同的道具
}
protected override async Task<GameResult> ExecuteGameLogic()
{
LogEvent("开始射击战斗!");
var startTime = DateTime.Now;
while (enemiesKilled < enemyCount &&
DateTime.Now - startTime < timeLimit)
{
// 模拟射击
await SimulateShootingRound();
if (enemiesKilled >= enemyCount)
{
LogEvent("所有敌人被消灭!");
score += 1000;
return new GameResult { Success = true };
}
}
if (DateTime.Now - startTime >= timeLimit)
{
LogEvent("时间用完了!");
return new GameResult { Success = false, Reason = "超时" };
}
return new GameResult { Success = false, Reason = "未知错误" };
}
private async Task SimulateShootingRound()
{
await Task.Delay(500); // 模拟射击间隔
if (enemiesKilled < enemyCount)
{
enemiesKilled++;
score += 100;
LogEvent($"击败了 {enemies[enemiesKilled - 1]}!当前得分: {score}");
}
}
protected override async Task ShowIntroduction()
{
await base.ShowIntroduction();
LogEvent("目标:消灭所有敌人!");
LogEvent("使用鼠标瞄准,点击射击");
}
}
// 具体关卡:解谜关卡
public class PuzzleLevel : GameLevel
{
private int puzzleCount;
private int puzzlesSolved;
private List<string> puzzles;
public PuzzleLevel(string name, int difficulty, TimeSpan timeLimit)
: base(name, difficulty, timeLimit)
{
puzzles = new List<string>();
}
protected override void InitializeLevel()
{
LogEvent("初始化解谜关卡");
SetupEnemies(); // 在解谜关卡中,"敌人"是难题
ConfigurePowerUps(); // 提示道具
LogEvent($"准备了 {puzzleCount} 个谜题");
}
protected override void SetupEnemies()
{
puzzleCount = difficulty + 2; // 根据难度生成谜题数量
puzzlesSolved = 0;
for (int i = 0; i < puzzleCount; i++)
{
puzzles.Add($"谜题{i + 1}");
}
}
protected override void ConfigurePowerUps()
{
LogEvent("配置提示道具");
}
protected override async Task<GameResult> ExecuteGameLogic()
{
LogEvent("开始解谜!");
var startTime = DateTime.Now;
while (puzzlesSolved < puzzleCount &&
DateTime.Now - startTime < timeLimit)
{
await SolvePuzzle();
if (puzzlesSolved >= puzzleCount)
{
LogEvent("所有谜题都解开了!");
score += 2000;
return new GameResult { Success = true };
}
}
if (DateTime.Now - startTime >= timeLimit)
{
LogEvent("时间用完了!");
return new GameResult { Success = false, Reason = "超时" };
}
return new GameResult { Success = false, Reason = "未知错误" };
}
private async Task SolvePuzzle()
{
await Task.Delay(2000); // 模拟解谜时间
if (puzzlesSolved < puzzleCount)
{
puzzlesSolved++;
int puzzleScore = difficulty * 200;
score += puzzleScore;
LogEvent($"解开了 {puzzles[puzzlesSolved - 1]}!获得 {puzzleScore} 分");
}
}
protected override async Task ShowIntroduction()
{
await base.ShowIntroduction();
LogEvent("目标:解开所有谜题!");
LogEvent("仔细观察,运用逻辑思维");
}
protected override void CalculateFinalScore(TimeSpan elapsed)
{
base.CalculateFinalScore(elapsed);
// 解谜关卡额外的智力奖励
int intelligenceBonus = puzzlesSolved * 50;
score += intelligenceBonus;
LogEvent($"智力奖励: {intelligenceBonus} 分");
}
}
// 游戏结果类
public class GameResult
{
public bool Success { get; set; }
public string Reason { get; set; }
}
// 关卡管理器
public class LevelManager
{
private List<GameLevel> levels;
private int currentLevelIndex;
private int totalScore;
public LevelManager()
{
levels = new List<GameLevel>();
currentLevelIndex = 0;
totalScore = 0;
}
public void AddLevel(GameLevel level)
{
levels.Add(level);
}
public async Task<bool> PlayAllLevels()
{
Console.WriteLine("开始游戏!");
for (currentLevelIndex = 0; currentLevelIndex < levels.Count; currentLevelIndex++)
{
var level = levels[currentLevelIndex];
Console.WriteLine($"\n=== 第 {currentLevelIndex + 1} 关 ===");
var result = await level.PlayLevel();
totalScore += level.GetScore();
if (!result.Success)
{
Console.WriteLine($"游戏结束!总分: {totalScore}");
return false;
}
Console.WriteLine($"关卡完成!当前总分: {totalScore}");
}
Console.WriteLine($"恭喜通关!最终得分: {totalScore}");
return true;
}
}
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
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
# 5个多种设计模式结合的实际案例
# 案例1:电商订单处理系统
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
// 组合多种模式:单例 + 工厂 + 观察者 + 状态 + 策略
// 1. 订单状态(状态模式)
public interface IOrderState
{
Task ProcessAsync(Order order);
string GetStateName();
bool CanTransitionTo(Type stateType);
}
public class PendingState : IOrderState
{
public async Task ProcessAsync(Order order)
{
Console.WriteLine($"订单 {order.Id} 等待支付...");
await Task.Delay(1000);
// 检查支付
var paymentService = PaymentServiceFactory.Instance.CreatePaymentService(order.PaymentMethod);
var paymentResult = await paymentService.ProcessPaymentAsync(order.TotalAmount);
if (paymentResult.Success)
{
order.ChangeState(new PaidState());
}
else
{
order.ChangeState(new CancelledState());
}
}
public string GetStateName() => "待支付";
public bool CanTransitionTo(Type stateType) =>
stateType == typeof(PaidState) || stateType == typeof(CancelledState);
}
public class PaidState : IOrderState
{
public async Task ProcessAsync(Order order)
{
Console.WriteLine($"订单 {order.Id} 已支付,准备发货...");
await Task.Delay(2000);
// 检查库存
var inventoryService = InventoryService.Instance;
if (await inventoryService.CheckStockAsync(order.Items))
{
await inventoryService.ReserveStockAsync(order.Items);
order.ChangeState(new ShippedState());
}
else
{
order.ChangeState(new OutOfStockState());
}
}
public string GetStateName() => "已支付";
public bool CanTransitionTo(Type stateType) =>
stateType == typeof(ShippedState) || stateType == typeof(OutOfStockState);
}
public class ShippedState : IOrderState
{
public async Task ProcessAsync(Order order)
{
Console.WriteLine($"订单 {order.Id} 已发货,等待确认收货...");
await Task.Delay(3000);
order.ChangeState(new DeliveredState());
}
public string GetStateName() => "已发货";
public bool CanTransitionTo(Type stateType) => stateType == typeof(DeliveredState);
}
public class DeliveredState : IOrderState
{
public async Task ProcessAsync(Order order)
{
Console.WriteLine($"订单 {order.Id} 已完成");
await Task.CompletedTask;
}
public string GetStateName() => "已完成";
public bool CanTransitionTo(Type stateType) => false;
}
public class CancelledState : IOrderState
{
public async Task ProcessAsync(Order order)
{
Console.WriteLine($"订单 {order.Id} 已取消");
await Task.CompletedTask;
}
public string GetStateName() => "已取消";
public bool CanTransitionTo(Type stateType) => false;
}
public class OutOfStockState : IOrderState
{
public async Task ProcessAsync(Order order)
{
Console.WriteLine($"订单 {order.Id} 库存不足,等待补货...");
// 可以转换回已支付状态等待补货
await Task.CompletedTask;
}
public string GetStateName() => "库存不足";
public bool CanTransitionTo(Type stateType) => stateType == typeof(PaidState);
}
// 2. 支付策略(策略模式)
public interface IPaymentStrategy
{
Task<PaymentResult> ProcessPaymentAsync(decimal amount);
string GetPaymentMethodName();
}
public class AlipayStrategy : IPaymentStrategy
{
public async Task<PaymentResult> ProcessPaymentAsync(decimal amount)
{
Console.WriteLine($"使用支付宝支付 {amount:C}");
await Task.Delay(1500);
return new PaymentResult { Success = true, TransactionId = Guid.NewGuid().ToString() };
}
public string GetPaymentMethodName() => "支付宝";
}
public class WeChatPayStrategy : IPaymentStrategy
{
public async Task<PaymentResult> ProcessPaymentAsync(decimal amount)
{
Console.WriteLine($"使用微信支付 {amount:C}");
await Task.Delay(1200);
return new PaymentResult { Success = true, TransactionId = Guid.NewGuid().ToString() };
}
public string GetPaymentMethodName() => "微信支付";
}
public class CreditCardStrategy : IPaymentStrategy
{
public async Task<PaymentResult> ProcessPaymentAsync(decimal amount)
{
Console.WriteLine($"使用信用卡支付 {amount:C}");
await Task.Delay(2000);
// 模拟10%的失败率
return new PaymentResult
{
Success = new Random().Next(1, 11) <= 9,
TransactionId = Guid.NewGuid().ToString()
};
}
public string GetPaymentMethodName() => "信用卡";
}
// 3. 支付服务工厂(工厂模式)
public class PaymentServiceFactory
{
private static PaymentServiceFactory _instance;
private static readonly object _lock = new object();
private PaymentServiceFactory() { }
public static PaymentServiceFactory Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
_instance = new PaymentServiceFactory();
}
}
return _instance;
}
}
public IPaymentStrategy CreatePaymentService(PaymentMethod method)
{
return method switch
{
PaymentMethod.Alipay => new AlipayStrategy(),
PaymentMethod.WeChat => new WeChatPayStrategy(),
PaymentMethod.CreditCard => new CreditCardStrategy(),
_ => throw new ArgumentException("不支持的支付方式")
};
}
}
// 4. 观察者模式:订单事件通知
public interface IOrderObserver
{
Task OnOrderStateChangedAsync(Order order, string fromState, string toState);
}
public class EmailNotificationObserver : IOrderObserver
{
public async Task OnOrderStateChangedAsync(Order order, string fromState, string toState)
{
Console.WriteLine($"发送邮件通知:订单 {order.Id} 状态从 '{fromState}' 变更为 '{toState}'");
await Task.Delay(500); // 模拟发送邮件
}
}
public class SMSNotificationObserver : IOrderObserver
{
public async Task OnOrderStateChangedAsync(Order order, string fromState, string toState)
{
if (toState == "已发货" || toState == "已完成")
{
Console.WriteLine($"发送短信通知:订单 {order.Id} {toState}");
await Task.Delay(300); // 模拟发送短信
}
}
}
public class InventoryObserver : IOrderObserver
{
public async Task OnOrderStateChangedAsync(Order order, string fromState, string toState)
{
if (toState == "已取消" && fromState == "已支付")
{
Console.WriteLine($"释放订单 {order.Id} 的库存");
var inventoryService = InventoryService.Instance;
await inventoryService.ReleaseStockAsync(order.Items);
}
}
}
// 5. 库存服务(单例模式)
public class InventoryService
{
private static InventoryService _instance;
private static readonly object _lock = new object();
private Dictionary<string, int> _stock;
private InventoryService()
{
_stock = new Dictionary<string, int>
{
{ "商品A", 100 },
{ "商品B", 50 },
{ "商品C", 200 }
};
}
public static InventoryService Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
_instance = new InventoryService();
}
}
return _instance;
}
}
public async Task<bool> CheckStockAsync(List<OrderItem> items)
{
await Task.Delay(500); // 模拟数据库查询
foreach (var item in items)
{
if (!_stock.ContainsKey(item.ProductName) || _stock[item.ProductName] < item.Quantity)
{
return false;
}
}
return true;
}
public async Task ReserveStockAsync(List<OrderItem> items)
{
await Task.Delay(300);
foreach (var item in items)
{
if (_stock.ContainsKey(item.ProductName))
{
_stock[item.ProductName] -= item.Quantity;
Console.WriteLine($"预留库存:{item.ProductName} -{item.Quantity},剩余:{_stock[item.ProductName]}");
}
}
}
public async Task ReleaseStockAsync(List<OrderItem> items)
{
await Task.Delay(300);
foreach (var item in items)
{
if (_stock.ContainsKey(item.ProductName))
{
_stock[item.ProductName] += item.Quantity;
Console.WriteLine($"释放库存:{item.ProductName} +{item.Quantity},剩余:{_stock[item.ProductName]}");
}
}
}
}
// 核心订单类
public class Order
{
private IOrderState _state;
private List<IOrderObserver> _observers;
public string Id { get; set; }
public List<OrderItem> Items { get; set; }
public decimal TotalAmount { get; set; }
public PaymentMethod PaymentMethod { get; set; }
public DateTime CreateTime { get; set; }
public Order(string id, PaymentMethod paymentMethod)
{
Id = id;
PaymentMethod = paymentMethod;
Items = new List<OrderItem>();
_observers = new List<IOrderObserver>();
_state = new PendingState();
CreateTime = DateTime.Now;
}
public void AddObserver(IOrderObserver observer)
{
_observers.Add(observer);
}
public void RemoveObserver(IOrderObserver observer)
{
_observers.Remove(observer);
}
public async Task ChangeState(IOrderState newState)
{
var oldStateName = _state.GetStateName();
var newStateName = newState.GetStateName();
if (!_state.CanTransitionTo(newState.GetType()))
{
Console.WriteLine($"不能从 '{oldStateName}' 转换到 '{newStateName}'");
return;
}
_state = newState;
Console.WriteLine($"订单 {Id} 状态变更:{oldStateName} -> {newStateName}");
// 通知所有观察者
var notificationTasks = _observers.Select(observer =>
observer.OnOrderStateChangedAsync(this, oldStateName, newStateName));
await Task.WhenAll(notificationTasks);
}
public async Task ProcessAsync()
{
await _state.ProcessAsync(this);
}
public string GetCurrentState() => _state.GetStateName();
public void AddItem(string productName, int quantity, decimal price)
{
Items.Add(new OrderItem { ProductName = productName, Quantity = quantity, Price = price });
TotalAmount += quantity * price;
}
}
// 辅助类
public class OrderItem
{
public string ProductName { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
}
public class PaymentResult
{
public bool Success { get; set; }
public string TransactionId { get; set; }
public string ErrorMessage { get; set; }
}
public enum PaymentMethod
{
Alipay,
WeChat,
CreditCard
}
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
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
# 案例2:游戏角色系统
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
// 组合:建造者 + 装饰器 + 命令 + 观察者 + 工厂
// 1. 角色建造者模式
public class Character
{
public string Name { get; set; }
public int Health { get; set; }
public int MaxHealth { get; set; }
public int Attack { get; set; }
public int Defense { get; set; }
public int Speed { get; set; }
public CharacterClass Class { get; set; }
public List<ISkill> Skills { get; set; }
public List<IEquipment> Equipment { get; set; }
public List<ICharacterObserver> Observers { get; set; }
public Character()
{
Skills = new List<ISkill>();
Equipment = new List<IEquipment>();
Observers = new List<ICharacterObserver>();
}
public void AddObserver(ICharacterObserver observer)
{
Observers.Add(observer);
}
public async Task TakeDamage(int damage)
{
int actualDamage = Math.Max(1, damage - Defense);
Health = Math.Max(0, Health - actualDamage);
Console.WriteLine($"{Name} 受到 {actualDamage} 点伤害,剩余血量: {Health}/{MaxHealth}");
// 通知观察者
var tasks = Observers.Select(o => o.OnHealthChangedAsync(this, actualDamage));
await Task.WhenAll(tasks);
if (Health <= 0)
{
var deathTasks = Observers.Select(o => o.OnCharacterDeathAsync(this));
await Task.WhenAll(deathTasks);
}
}
public void Heal(int amount)
{
int oldHealth = Health;
Health = Math.Min(MaxHealth, Health + amount);
Console.WriteLine($"{Name} 恢复 {Health - oldHealth} 点血量,当前血量: {Health}/{MaxHealth}");
}
public int GetTotalAttack()
{
int totalAttack = Attack;
foreach (var equipment in Equipment)
{
totalAttack += equipment.GetAttackBonus();
}
return totalAttack;
}
public int GetTotalDefense()
{
int totalDefense = Defense;
foreach (var equipment in Equipment)
{
totalDefense += equipment.GetDefenseBonus();
}
return totalDefense;
}
}
public abstract class CharacterBuilder
{
protected Character character;
public CharacterBuilder()
{
character = new Character();
}
public abstract CharacterBuilder SetName(string name);
public abstract CharacterBuilder SetClass(CharacterClass characterClass);
public abstract CharacterBuilder SetBaseStats();
public abstract CharacterBuilder AddDefaultSkills();
public abstract CharacterBuilder AddDefaultEquipment();
public virtual CharacterBuilder AddSkill(ISkill skill)
{
character.Skills.Add(skill);
return this;
}
public virtual CharacterBuilder AddEquipment(IEquipment equipment)
{
character.Equipment.Add(equipment);
return this;
}
public Character Build()
{
character.Health = character.MaxHealth;
return character;
}
}
public class WarriorBuilder : CharacterBuilder
{
public override CharacterBuilder SetName(string name)
{
character.Name = name;
return this;
}
public override CharacterBuilder SetClass(CharacterClass characterClass)
{
character.Class = CharacterClass.Warrior;
return this;
}
public override CharacterBuilder SetBaseStats()
{
character.MaxHealth = 120;
character.Attack = 25;
character.Defense = 15;
character.Speed = 8;
return this;
}
public override CharacterBuilder AddDefaultSkills()
{
character.Skills.Add(new PowerStrike());
character.Skills.Add(new DefensiveStance());
return this;
}
public override CharacterBuilder AddDefaultEquipment()
{
character.Equipment.Add(new IronSword());
character.Equipment.Add(new LeatherArmor());
return this;
}
}
public class MageBuilder : CharacterBuilder
{
public override CharacterBuilder SetName(string name)
{
character.Name = name;
return this;
}
public override CharacterBuilder SetClass(CharacterClass characterClass)
{
character.Class = CharacterClass.Mage;
return this;
}
public override CharacterBuilder SetBaseStats()
{
character.MaxHealth = 80;
character.Attack = 35;
character.Defense = 5;
character.Speed = 12;
return this;
}
public override CharacterBuilder AddDefaultSkills()
{
character.Skills.Add(new Fireball());
character.Skills.Add(new MagicShield());
return this;
}
public override CharacterBuilder AddDefaultEquipment()
{
character.Equipment.Add(new MagicStaff());
character.Equipment.Add(new MageRobe());
return this;
}
}
// 2. 装饰器模式:装备系统
public interface IEquipment
{
string GetName();
int GetAttackBonus();
int GetDefenseBonus();
int GetSpeedBonus();
string GetDescription();
}
public abstract class BaseEquipment : IEquipment
{
protected string name;
protected int attackBonus;
protected int defenseBonus;
protected int speedBonus;
public virtual string GetName() => name;
public virtual int GetAttackBonus() => attackBonus;
public virtual int GetDefenseBonus() => defenseBonus;
public virtual int GetSpeedBonus() => speedBonus;
public abstract string GetDescription();
}
public class IronSword : BaseEquipment
{
public IronSword()
{
name = "铁剑";
attackBonus = 10;
defenseBonus = 0;
speedBonus = 0;
}
public override string GetDescription() => $"{name}: +{attackBonus} 攻击力";
}
public class MagicStaff : BaseEquipment
{
public MagicStaff()
{
name = "魔法杖";
attackBonus = 15;
defenseBonus = 0;
speedBonus = 2;
}
public override string GetDescription() => $"{name}: +{attackBonus} 攻击力, +{speedBonus} 速度";
}
public class LeatherArmor : BaseEquipment
{
public LeatherArmor()
{
name = "皮甲";
attackBonus = 0;
defenseBonus = 8;
speedBonus = -1;
}
public override string GetDescription() => $"{name}: +{defenseBonus} 防御力, {speedBonus} 速度";
}
public class MageRobe : BaseEquipment
{
public MageRobe()
{
name = "法师长袍";
attackBonus = 2;
defenseBonus = 3;
speedBonus = 1;
}
public override string GetDescription() => $"{name}: +{attackBonus} 攻击力, +{defenseBonus} 防御力, +{speedBonus} 速度";
}
// 装备强化装饰器
public abstract class EquipmentDecorator : IEquipment
{
protected IEquipment equipment;
public EquipmentDecorator(IEquipment equipment)
{
this.equipment = equipment;
}
public virtual string GetName() => equipment.GetName();
public virtual int GetAttackBonus() => equipment.GetAttackBonus();
public virtual int GetDefenseBonus() => equipment.GetDefenseBonus();
public virtual int GetSpeedBonus() => equipment.GetSpeedBonus();
public virtual string GetDescription() => equipment.GetDescription();
}
public class EnchantedDecorator : EquipmentDecorator
{
public EnchantedDecorator(IEquipment equipment) : base(equipment) { }
public override string GetName() => $"附魔的{equipment.GetName()}";
public override int GetAttackBonus() => equipment.GetAttackBonus() + 5;
public override int GetDefenseBonus() => equipment.GetDefenseBonus() + 3;
public override string GetDescription() =>
$"{GetName()}: +{GetAttackBonus()} 攻击力, +{GetDefenseBonus()} 防御力, +{GetSpeedBonus()} 速度 [附魔]";
}
public class MasterworkDecorator : EquipmentDecorator
{
public MasterworkDecorator(IEquipment equipment) : base(equipment) { }
public override string GetName() => $"精工{equipment.GetName()}";
public override int GetAttackBonus() => (int)(equipment.GetAttackBonus() * 1.5f);
public override int GetDefenseBonus() => (int)(equipment.GetDefenseBonus() * 1.5f);
public override int GetSpeedBonus() => equipment.GetSpeedBonus() + 1;
public override string GetDescription() =>
$"{GetName()}: +{GetAttackBonus()} 攻击力, +{GetDefenseBonus()} 防御力, +{GetSpeedBonus()} 速度 [精工]";
}
// 3. 命令模式:技能系统
public interface ICommand
{
Task ExecuteAsync(Character caster, Character target = null);
bool CanExecute(Character caster);
string GetName();
string GetDescription();
}
public interface ISkill : ICommand
{
int ManaCost { get; }
int Cooldown { get; }
int CurrentCooldown { get; set; }
}
public abstract class BaseSkill : ISkill
{
public string Name { get; protected set; }
public string Description { get; protected set; }
public int ManaCost { get; protected set; }
public int Cooldown { get; protected set; }
public int CurrentCooldown { get; set; }
public abstract Task ExecuteAsync(Character caster, Character target = null);
public virtual bool CanExecute(Character caster)
{
return CurrentCooldown <= 0; // 简化实现,不检查法力值
}
public string GetName() => Name;
public string GetDescription() => Description;
}
public class PowerStrike : BaseSkill
{
public PowerStrike()
{
Name = "强力攻击";
Description = "造成150%攻击力的伤害";
ManaCost = 15;
Cooldown = 3;
}
public override async Task ExecuteAsync(Character caster, Character target = null)
{
if (target == null) return;
int damage = (int)(caster.GetTotalAttack() * 1.5f);
Console.WriteLine($"{caster.Name} 对 {target.Name} 使用了 {Name}!");
await target.TakeDamage(damage);
CurrentCooldown = Cooldown;
}
}
public class Fireball : BaseSkill
{
public Fireball()
{
Name = "火球术";
Description = "造成200%攻击力的魔法伤害";
ManaCost = 25;
Cooldown = 2;
}
public override async Task ExecuteAsync(Character caster, Character target = null)
{
if (target == null) return;
int damage = caster.GetTotalAttack() * 2;
Console.WriteLine($"{caster.Name} 向 {target.Name} 发射了 {Name}!");
await target.TakeDamage(damage);
CurrentCooldown = Cooldown;
}
}
public class DefensiveStance : BaseSkill
{
public DefensiveStance()
{
Name = "防御姿态";
Description = "提高防御力并恢复少量血量";
ManaCost = 10;
Cooldown = 4;
}
public override async Task ExecuteAsync(Character caster, Character target = null)
{
Console.WriteLine($"{caster.Name} 进入了 {Name}!");
caster.Defense += 5; // 临时提升防御
caster.Heal(15);
CurrentCooldown = Cooldown;
await Task.CompletedTask;
}
}
public class MagicShield : BaseSkill
{
public MagicShield()
{
Name = "魔法护盾";
Description = "大幅提升防御力";
ManaCost = 20;
Cooldown = 5;
}
public override async Task ExecuteAsync(Character caster, Character target = null)
{
Console.WriteLine($"{caster.Name} 施展了 {Name}!");
caster.Defense += 10; // 临时大幅提升防御
CurrentCooldown = Cooldown;
await Task.CompletedTask;
}
}
// 4. 观察者模式:事件系统
public interface ICharacterObserver
{
Task OnHealthChangedAsync(Character character, int damage);
Task OnCharacterDeathAsync(Character character);
}
public class CombatLogger : ICharacterObserver
{
public async Task OnHealthChangedAsync(Character character, int damage)
{
Console.WriteLine($"[战斗日志] {character.Name} 受到 {damage} 点伤害");
await Task.CompletedTask;
} public async Task OnCharacterDeathAsync(Character character)
{
Console.WriteLine($"[战斗日志] {character.Name} 阵亡了!");
await Task.CompletedTask;
}
}
public class ExperienceManager : ICharacterObserver
{
public async Task OnHealthChangedAsync(Character character, int damage)
{
// 受到伤害时不获得经验
await Task.CompletedTask;
}
public async Task OnCharacterDeathAsync(Character character)
{
Console.WriteLine($"[经验系统] {character.Name} 死亡,其他角色获得经验值");
await Task.CompletedTask;
}
}
public class AchievementSystem : ICharacterObserver
{
private Dictionary<string, int> playerStats = new Dictionary<string, int>();
public async Task OnHealthChangedAsync(Character character, int damage)
{
if (!playerStats.ContainsKey(character.Name))
playerStats[character.Name] = 0;
playerStats[character.Name] += damage;
if (playerStats[character.Name] >= 100)
{
Console.WriteLine($"[成就系统] {character.Name} 解锁成就:承受伤害达人");
}
await Task.CompletedTask;
}
public async Task OnCharacterDeathAsync(Character character)
{
Console.WriteLine($"[成就系统] {character.Name} 解锁成就:英勇牺牲");
await Task.CompletedTask;
}
}
// 5. 工厂模式:角色创建
public enum CharacterClass
{
Warrior,
Mage,
Archer,
Assassin
}
public class CharacterFactory
{
public static CharacterBuilder GetBuilder(CharacterClass characterClass)
{
return characterClass switch
{
CharacterClass.Warrior => new WarriorBuilder(),
CharacterClass.Mage => new MageBuilder(),
_ => throw new ArgumentException("不支持的角色类型")
};
}
public static Character CreateCharacter(CharacterClass characterClass, string name)
{
var builder = GetBuilder(characterClass);
return builder
.SetName(name)
.SetClass(characterClass)
.SetBaseStats()
.AddDefaultSkills()
.AddDefaultEquipment()
.Build();
}
public static Character CreateAdvancedCharacter(CharacterClass characterClass, string name, List<ISkill> customSkills = null)
{
var builder = GetBuilder(characterClass);
var character = builder
.SetName(name)
.SetClass(characterClass)
.SetBaseStats()
.AddDefaultSkills()
.AddDefaultEquipment()
.Build();
// 强化装备
for (int i = 0; i < character.Equipment.Count; i++)
{
character.Equipment[i] = new EnchantedDecorator(
new MasterworkDecorator(character.Equipment[i])
);
}
// 添加自定义技能
if (customSkills != null)
{
character.Skills.AddRange(customSkills);
}
return character;
}
}
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
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
# 案例3:文档处理系统
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
// 组合:适配器 + 桥接 + 责任链 + 访问者 + 原型
// 1. 桥接模式:文档格式与处理器分离
public interface IDocumentProcessor
{
Task<string> ProcessAsync(string content);
string GetProcessorName();
}
public class PlainTextProcessor : IDocumentProcessor
{
public async Task<string> ProcessAsync(string content)
{
await Task.Delay(100);
return content; // 纯文本不需要处理
}
public string GetProcessorName() => "纯文本处理器";
}
public class MarkdownProcessor : IDocumentProcessor
{
public async Task<string> ProcessAsync(string content)
{
await Task.Delay(300);
// 简化的Markdown处理
string processed = content
.Replace("**", "<strong>").Replace("**", "</strong>")
.Replace("*", "<em>").Replace("*", "</em>")
.Replace("\n", "<br>");
return $"<html><body>{processed}</body></html>";
}
public string GetProcessorName() => "Markdown处理器";
}
public class HTMLProcessor : IDocumentProcessor
{
public async Task<string> ProcessAsync(string content)
{
await Task.Delay(200);
// 简化的HTML验证和格式化
return content.Contains("<html>") ? content : $"<html><body>{content}</body></html>";
}
public string GetProcessorName() => "HTML处理器";
}
// 抽象文档类
public abstract class Document
{
protected IDocumentProcessor processor;
public string Title { get; set; }
public string Content { get; set; }
public DateTime CreatedDate { get; set; }
public string Author { get; set; }
public DocumentMetadata Metadata { get; set; }
public Document(IDocumentProcessor processor)
{
this.processor = processor;
CreatedDate = DateTime.Now;
Metadata = new DocumentMetadata();
}
public abstract Task<string> RenderAsync();
public abstract Document Clone();
public abstract void Accept(IDocumentVisitor visitor);
}
public class TextDocument : Document
{
public TextDocument(IDocumentProcessor processor) : base(processor) { }
public override async Task<string> RenderAsync()
{
Console.WriteLine($"使用 {processor.GetProcessorName()} 渲染文本文档");
return await processor.ProcessAsync(Content);
}
public override Document Clone()
{
var cloned = new TextDocument(processor)
{
Title = this.Title,
Content = this.Content,
Author = this.Author,
CreatedDate = this.CreatedDate,
Metadata = this.Metadata.Clone()
};
return cloned;
}
public override void Accept(IDocumentVisitor visitor)
{
visitor.VisitTextDocument(this);
}
}
public class RichDocument : Document
{
public List<string> Images { get; set; }
public List<string> Links { get; set; }
public RichDocument(IDocumentProcessor processor) : base(processor)
{
Images = new List<string>();
Links = new List<string>();
}
public override async Task<string> RenderAsync()
{
Console.WriteLine($"使用 {processor.GetProcessorName()} 渲染富文档");
var baseContent = await processor.ProcessAsync(Content);
// 添加图片和链接
foreach (var image in Images)
{
baseContent += $"<img src='{image}' />";
}
foreach (var link in Links)
{
baseContent += $"<a href='{link}'>{link}</a>";
}
return baseContent;
}
public override Document Clone()
{
var cloned = new RichDocument(processor)
{
Title = this.Title,
Content = this.Content,
Author = this.Author,
CreatedDate = this.CreatedDate,
Metadata = this.Metadata.Clone(),
Images = new List<string>(this.Images),
Links = new List<string>(this.Links)
};
return cloned;
}
public override void Accept(IDocumentVisitor visitor)
{
visitor.VisitRichDocument(this);
}
}
// 2. 原型模式:文档元数据
public class DocumentMetadata
{
public Dictionary<string, string> Properties { get; set; }
public List<string> Tags { get; set; }
public int Version { get; set; }
public DocumentMetadata()
{
Properties = new Dictionary<string, string>();
Tags = new List<string>();
Version = 1;
}
public DocumentMetadata Clone()
{
return new DocumentMetadata
{
Properties = new Dictionary<string, string>(this.Properties),
Tags = new List<string>(this.Tags),
Version = this.Version
};
}
}
// 3. 适配器模式:旧系统集成
public interface ILegacyDocumentSystem
{
string GetDocumentContent(int documentId);
void SaveDocument(int documentId, string content);
}
public class LegacyDocumentSystem : ILegacyDocumentSystem
{
private Dictionary<int, string> documents = new Dictionary<int, string>();
public string GetDocumentContent(int documentId)
{
return documents.ContainsKey(documentId) ? documents[documentId] : null;
}
public void SaveDocument(int documentId, string content)
{
documents[documentId] = content;
Console.WriteLine($"保存到旧系统,文档ID: {documentId}");
}
}
public class DocumentSystemAdapter
{
private readonly ILegacyDocumentSystem legacySystem;
public DocumentSystemAdapter(ILegacyDocumentSystem legacySystem)
{
this.legacySystem = legacySystem;
}
public async Task<Document> LoadDocumentAsync(int documentId)
{
await Task.Delay(500); // 模拟网络延迟
string content = legacySystem.GetDocumentContent(documentId);
if (content == null) return null;
var document = new TextDocument(new PlainTextProcessor())
{
Title = $"旧文档 {documentId}",
Content = content,
Author = "旧系统"
};
return document;
}
public async Task SaveDocumentAsync(Document document, int documentId)
{
await Task.Delay(300);
string renderedContent = await document.RenderAsync();
legacySystem.SaveDocument(documentId, renderedContent);
}
}
// 4. 责任链模式:文档验证
public abstract class DocumentValidator
{
protected DocumentValidator nextValidator;
public void SetNext(DocumentValidator next)
{
nextValidator = next;
}
public async Task<ValidationResult> ValidateAsync(Document document)
{
var result = await DoValidateAsync(document);
if (result.IsValid && nextValidator != null)
{
var nextResult = await nextValidator.ValidateAsync(document);
if (!nextResult.IsValid)
return nextResult;
}
return result;
}
protected abstract Task<ValidationResult> DoValidateAsync(Document document);
}
public class ContentValidator : DocumentValidator
{
protected override async Task<ValidationResult> DoValidateAsync(Document document)
{
await Task.Delay(100);
if (string.IsNullOrWhiteSpace(document.Content))
{
return new ValidationResult { IsValid = false, ErrorMessage = "文档内容不能为空" };
}
if (document.Content.Length > 10000)
{
return new ValidationResult { IsValid = false, ErrorMessage = "文档内容过长" };
}
Console.WriteLine("内容验证通过");
return new ValidationResult { IsValid = true };
}
}
public class TitleValidator : DocumentValidator
{
protected override async Task<ValidationResult> DoValidateAsync(Document document)
{
await Task.Delay(50);
if (string.IsNullOrWhiteSpace(document.Title))
{
return new ValidationResult { IsValid = false, ErrorMessage = "文档标题不能为空" };
}
if (document.Title.Length > 100)
{
return new ValidationResult { IsValid = false, ErrorMessage = "文档标题过长" };
}
Console.WriteLine("标题验证通过");
return new ValidationResult { IsValid = true };
}
}
public class SecurityValidator : DocumentValidator
{
private readonly List<string> bannedWords = new List<string> { "恶意", "病毒", "危险" };
protected override async Task<ValidationResult> DoValidateAsync(Document document)
{
await Task.Delay(200);
foreach (var word in bannedWords)
{
if (document.Content.Contains(word) || document.Title.Contains(word))
{
return new ValidationResult
{
IsValid = false,
ErrorMessage = $"文档包含禁用词汇: {word}"
};
}
}
Console.WriteLine("安全验证通过");
return new ValidationResult { IsValid = true };
}
}
public class ValidationResult
{
public bool IsValid { get; set; }
public string ErrorMessage { get; set; }
}
// 5. 访问者模式:文档分析
public interface IDocumentVisitor
{
void VisitTextDocument(TextDocument document);
void VisitRichDocument(RichDocument document);
DocumentAnalysisResult GetResult();
}
public class WordCountVisitor : IDocumentVisitor
{
private int totalWords;
private int documentCount;
public void VisitTextDocument(TextDocument document)
{
totalWords += CountWords(document.Content);
documentCount++;
Console.WriteLine($"文本文档 '{document.Title}' 字数: {CountWords(document.Content)}");
}
public void VisitRichDocument(RichDocument document)
{
totalWords += CountWords(document.Content);
documentCount++;
Console.WriteLine($"富文档 '{document.Title}' 字数: {CountWords(document.Content)}, 图片: {document.Images.Count}, 链接: {document.Links.Count}");
}
private int CountWords(string content)
{
if (string.IsNullOrWhiteSpace(content)) return 0;
return content.Split(new char[] { ' ', '\t', '\n', '\r' },
StringSplitOptions.RemoveEmptyEntries).Length;
}
public DocumentAnalysisResult GetResult()
{
return new DocumentAnalysisResult
{
TotalWords = totalWords,
DocumentCount = documentCount,
AverageWordsPerDocument = documentCount > 0 ? (double)totalWords / documentCount : 0
};
}
}
public class SecurityAnalysisVisitor : IDocumentVisitor
{
private List<string> securityIssues;
private readonly List<string> suspiciousPatterns = new List<string>
{
"javascript:", "onclick", "onerror", "<script"
};
public SecurityAnalysisVisitor()
{
securityIssues = new List<string>();
}
public void VisitTextDocument(TextDocument document)
{
AnalyzeContent(document.Title, document.Content);
}
public void VisitRichDocument(RichDocument document)
{
AnalyzeContent(document.Title, document.Content);
// 检查链接安全性
foreach (var link in document.Links)
{
if (link.StartsWith("javascript:") || link.Contains("malware"))
{
securityIssues.Add($"可疑链接: {link}");
}
}
}
private void AnalyzeContent(string title, string content)
{
foreach (var pattern in suspiciousPatterns)
{
if (content.Contains(pattern) || title.Contains(pattern))
{
securityIssues.Add($"发现可疑模式: {pattern}");
}
}
}
public DocumentAnalysisResult GetResult()
{
return new DocumentAnalysisResult
{
SecurityIssues = new List<string>(securityIssues),
IsSecure = securityIssues.Count == 0
};
}
}
public class DocumentAnalysisResult
{
public int TotalWords { get; set; }
public int DocumentCount { get; set; }
public double AverageWordsPerDocument { get; set; }
public List<string> SecurityIssues { get; set; }
public bool IsSecure { get; set; }
public DocumentAnalysisResult()
{
SecurityIssues = new List<string>();
}
}
// 文档管理系统
public class DocumentManager
{
private List<Document> documents;
private DocumentValidator validatorChain;
private DocumentSystemAdapter legacyAdapter;
public DocumentManager(ILegacyDocumentSystem legacySystem)
{
documents = new List<Document>();
legacyAdapter = new DocumentSystemAdapter(legacySystem);
SetupValidationChain();
}
private void SetupValidationChain()
{
var titleValidator = new TitleValidator();
var contentValidator = new ContentValidator();
var securityValidator = new SecurityValidator();
titleValidator.SetNext(contentValidator);
contentValidator.SetNext(securityValidator);
validatorChain = titleValidator;
}
public async Task<bool> AddDocumentAsync(Document document)
{
var validationResult = await validatorChain.ValidateAsync(document);
if (!validationResult.IsValid)
{
Console.WriteLine($"文档验证失败: {validationResult.ErrorMessage}");
return false;
}
documents.Add(document);
Console.WriteLine($"文档 '{document.Title}' 添加成功");
return true;
}
public async Task<DocumentAnalysisResult> AnalyzeDocumentsAsync(IDocumentVisitor visitor)
{
foreach (var document in documents)
{
document.Accept(visitor);
}
await Task.CompletedTask;
return visitor.GetResult();
}
public Document CreateDocumentTemplate(Document prototype)
{
var template = prototype.Clone();
template.Title = "新文档模板";
template.Content = "请输入内容...";
template.CreatedDate = DateTime.Now;
return 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
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
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
# 案例4:智能家居控制系统
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
// 组合:外观 + 代理 + 中介者 + 备忘录 + 组合
// 1. 组合模式:设备层次结构
public abstract class SmartDevice
{
public string Id { get; set; }
public string Name { get; set; }
public bool IsOnline { get; set; }
protected List<SmartDevice> children;
public SmartDevice(string id, string name)
{
Id = id;
Name = name;
IsOnline = true;
children = new List<SmartDevice>();
}
public virtual void AddDevice(SmartDevice device)
{
children.Add(device);
}
public virtual void RemoveDevice(SmartDevice device)
{
children.Remove(device);
}
public virtual async Task<bool> TurnOnAsync()
{
var tasks = new List<Task<bool>>();
foreach (var child in children)
{
tasks.Add(child.TurnOnAsync());
}
var results = await Task.WhenAll(tasks);
return Array.TrueForAll(results, r => r);
}
public virtual async Task<bool> TurnOffAsync()
{
var tasks = new List<Task<bool>>();
foreach (var child in children)
{
tasks.Add(child.TurnOffAsync());
}
var results = await Task.WhenAll(tasks);
return Array.TrueForAll(results, r => r);
}
public abstract Task<DeviceStatus> GetStatusAsync();
public abstract Task<bool> ExecuteCommandAsync(string command, object parameter = null);
}
public class Room : SmartDevice
{
public Room(string id, string name) : base(id, name) { }
public override async Task<DeviceStatus> GetStatusAsync()
{
var status = new DeviceStatus { DeviceId = Id, DeviceName = Name };
foreach (var device in children)
{
var childStatus = await device.GetStatusAsync();
status.ChildStatuses.Add(childStatus);
}
return status;
}
public override async Task<bool> ExecuteCommandAsync(string command, object parameter = null)
{
Console.WriteLine($"在房间 {Name} 执行命令: {command}");
var tasks = new List<Task<bool>>();
foreach (var device in children)
{
tasks.Add(device.ExecuteCommandAsync(command, parameter));
}
var results = await Task.WhenAll(tasks);
return Array.TrueForAll(results, r => r);
}
}
public class Light : SmartDevice
{
public int Brightness { get; set; }
public string Color { get; set; }
public bool IsOn { get; set; }
public Light(string id, string name) : base(id, name)
{
Brightness = 100;
Color = "白色";
IsOn = false;
}
public override async Task<bool> TurnOnAsync()
{
await Task.Delay(100);
IsOn = true;
Console.WriteLine($"灯光 {Name} 已开启");
return true;
}
public override async Task<bool> TurnOffAsync()
{
await Task.Delay(100);
IsOn = false;
Console.WriteLine($"灯光 {Name} 已关闭");
return true;
}
public override async Task<DeviceStatus> GetStatusAsync()
{
await Task.Delay(50);
return new DeviceStatus
{
DeviceId = Id,
DeviceName = Name,
IsOnline = IsOnline,
Properties = new Dictionary<string, object>
{
{"IsOn", IsOn},
{"Brightness", Brightness},
{"Color", Color}
}
};
}
public override async Task<bool> ExecuteCommandAsync(string command, object parameter = null)
{
await Task.Delay(100);
switch (command.ToLower())
{
case "turnon":
return await TurnOnAsync();
case "turnoff":
return await TurnOffAsync();
case "setbrightness":
if (parameter is int brightness)
{
Brightness = Math.Max(0, Math.Min(100, brightness));
Console.WriteLine($"灯光 {Name} 亮度设置为 {Brightness}%");
return true;
}
break;
case "setcolor":
if (parameter is string color)
{
Color = color;
Console.WriteLine($"灯光 {Name} 颜色设置为 {Color}");
return true;
}
break;
}
return false;
}
}
public class AirConditioner : SmartDevice
{
public bool IsOn { get; set; }
public int Temperature { get; set; }
public string Mode { get; set; }
public AirConditioner(string id, string name) : base(id, name)
{
IsOn = false;
Temperature = 24;
Mode = "制冷";
}
public override async Task<bool> TurnOnAsync()
{
await Task.Delay(2000); // 空调启动需要更长时间
IsOn = true;
Console.WriteLine($"空调 {Name} 已开启,模式: {Mode},温度: {Temperature}°C");
return true;
}
public override async Task<bool> TurnOffAsync()
{
await Task.Delay(1000);
IsOn = false;
Console.WriteLine($"空调 {Name} 已关闭");
return true;
}
public override async Task<DeviceStatus> GetStatusAsync()
{
await Task.Delay(100);
return new DeviceStatus
{
DeviceId = Id,
DeviceName = Name,
IsOnline = IsOnline,
Properties = new Dictionary<string, object>
{
{"IsOn", IsOn},
{"Temperature", Temperature},
{"Mode", Mode}
}
};
}
public override async Task<bool> ExecuteCommandAsync(string command, object parameter = null)
{
await Task.Delay(500);
switch (command.ToLower())
{
case "turnon":
return await TurnOnAsync();
case "turnoff":
return await TurnOffAsync();
case "settemperature":
if (parameter is int temp)
{
Temperature = Math.Max(16, Math.Min(30, temp));
Console.WriteLine($"空调 {Name} 温度设置为 {Temperature}°C");
return true;
}
break;
case "setmode":
if (parameter is string mode)
{
Mode = mode;
Console.WriteLine($"空调 {Name} 模式设置为 {Mode}");
return true;
}
break;
}
return false;
}
}
// 2. 代理模式:设备访问控制
public interface IDeviceProxy
{
Task<bool> ExecuteCommandAsync(string deviceId, string command, object parameter = null);
Task<DeviceStatus> GetDeviceStatusAsync(string deviceId);
}
public class SecureDeviceProxy : IDeviceProxy
{
private readonly Dictionary<string, SmartDevice> devices;
private readonly IAuthenticationService authService;
private readonly List<string> accessLog;
public SecureDeviceProxy(IAuthenticationService authService)
{
this.authService = authService;
devices = new Dictionary<string, SmartDevice>();
accessLog = new List<string>();
}
public void RegisterDevice(SmartDevice device)
{
devices[device.Id] = device;
}
public async Task<bool> ExecuteCommandAsync(string deviceId, string command, object parameter = null)
{
// 权限检查
if (!await authService.IsAuthorizedAsync(command))
{
LogAccess($"未授权访问设备 {deviceId},命令: {command}");
return false;
}
// 设备存在性检查
if (!devices.ContainsKey(deviceId))
{
LogAccess($"设备 {deviceId} 不存在");
return false;
}
// 设备在线检查
var device = devices[deviceId];
if (!device.IsOnline)
{
LogAccess($"设备 {deviceId} 离线");
return false;
}
LogAccess($"执行命令 {command} 在设备 {deviceId}");
return await device.ExecuteCommandAsync(command, parameter);
}
public async Task<DeviceStatus> GetDeviceStatusAsync(string deviceId)
{
if (!devices.ContainsKey(deviceId))
{
return null;
}
LogAccess($"查询设备 {deviceId} 状态");
return await devices[deviceId].GetStatusAsync();
}
private void LogAccess(string message)
{
var logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {message}";
accessLog.Add(logEntry);
Console.WriteLine($"[访问日志] {message}");
}
public List<string> GetAccessLog() => new List<string>(accessLog);
}
// 3. 中介者模式:设备协调
public interface IHomeAutomationMediator
{
Task RegisterDeviceAsync(SmartDevice device);
Task ExecuteSceneAsync(string sceneName);
Task NotifyDeviceStateChangeAsync(string deviceId, string state);
}
public class HomeAutomationMediator : IHomeAutomationMediator
{
private readonly Dictionary<string, SmartDevice> devices;
private readonly Dictionary<string, Scene> scenes;
private readonly IDeviceProxy deviceProxy;
public HomeAutomationMediator(IDeviceProxy deviceProxy)
{
this.deviceProxy = deviceProxy;
devices = new Dictionary<string, SmartDevice>();
scenes = new Dictionary<string, Scene>();
InitializeScenes();
}
private void InitializeScenes()
{
// 回家场景
scenes["回家"] = new Scene
{
Name = "回家",
Actions = new List<SceneAction>
{
new SceneAction { DeviceId = "living_room_light", Command = "turnon" },
new SceneAction { DeviceId = "living_room_light", Command = "setbrightness", Parameter = 80 },
new SceneAction { DeviceId = "living_room_ac", Command = "turnon" },
new SceneAction { DeviceId = "living_room_ac", Command = "settemperature", Parameter = 24 }
}
};
// 睡眠场景
scenes["睡眠"] = new Scene
{
Name = "睡眠",
Actions = new List<SceneAction>
{
new SceneAction { DeviceId = "living_room_light", Command = "turnoff" },
new SceneAction { DeviceId = "bedroom_light", Command = "turnon" },
new SceneAction { DeviceId = "bedroom_light", Command = "setbrightness", Parameter = 20 },
new SceneAction { DeviceId = "living_room_ac", Command = "settemperature", Parameter = 26 }
}
};
// 外出场景
scenes["外出"] = new Scene
{
Name = "外出",
Actions = new List<SceneAction>
{
new SceneAction { DeviceId = "living_room_light", Command = "turnoff" },
new SceneAction { DeviceId = "bedroom_light", Command = "turnoff" },
new SceneAction { DeviceId = "living_room_ac", Command = "turnoff" }
}
};
}
public async Task RegisterDeviceAsync(SmartDevice device)
{
devices[device.Id] = device;
Console.WriteLine($"设备 {device.Name} 已注册到中介者");
await Task.CompletedTask;
}
public async Task ExecuteSceneAsync(string sceneName)
{
if (!scenes.ContainsKey(sceneName))
{
Console.WriteLine($"场景 '{sceneName}' 不存在");
return;
}
var scene = scenes[sceneName];
Console.WriteLine($"执行场景: {sceneName}");
foreach (var action in scene.Actions)
{
await deviceProxy.ExecuteCommandAsync(action.DeviceId, action.Command, action.Parameter);
await Task.Delay(200); // 设备之间的执行间隔
}
Console.WriteLine($"场景 '{sceneName}' 执行完成");
}
public async Task NotifyDeviceStateChangeAsync(string deviceId, string state)
{
Console.WriteLine($"设备 {deviceId} 状态变更: {state}");
// 根据设备状态变化触发自动化逻辑
if (deviceId == "door_sensor" && state == "opened")
{
await ExecuteSceneAsync("回家");
}
else if (deviceId == "motion_sensor" && state == "no_motion_5min")
{
await ExecuteSceneAsync("睡眠");
}
}
}
// 4. 备忘录模式:设备状态保存与恢复
public class DeviceMemento
{
public string DeviceId { get; set; }
public Dictionary<string, object> State { get; set; }
public DateTime SaveTime { get; set; }
public DeviceMemento(string deviceId, Dictionary<string, object> state)
{
DeviceId = deviceId;
State = new Dictionary<string, object>(state);
SaveTime = DateTime.Now;
}
}
public class HomeStateCaretaker
{
private readonly Stack<List<DeviceMemento>> stateHistory;
private readonly IDeviceProxy deviceProxy;
public HomeStateCaretaker(IDeviceProxy deviceProxy)
{
this.deviceProxy = deviceProxy;
stateHistory = new Stack<List<DeviceMemento>>();
}
public async Task SaveCurrentStateAsync(List<string> deviceIds, string description = "")
{
var mementos = new List<DeviceMemento>();
foreach (var deviceId in deviceIds)
{
var status = await deviceProxy.GetDeviceStatusAsync(deviceId);
if (status != null)
{
mementos.Add(new DeviceMemento(deviceId, status.Properties));
}
}
stateHistory.Push(mementos);
Console.WriteLine($"保存家居状态: {description} (设备数: {mementos.Count})");
}
public async Task<bool> RestoreLastStateAsync()
{
if (stateHistory.Count == 0)
{
Console.WriteLine("没有可恢复的状态");
return false;
}
var mementos = stateHistory.Pop();
Console.WriteLine($"开始恢复状态 (设备数: {mementos.Count})");
foreach (var memento in mementos)
{
await RestoreDeviceState(memento);
}
Console.WriteLine("状态恢复完成");
return true;
}
private async Task RestoreDeviceState(DeviceMemento memento)
{
foreach (var property in memento.State)
{
switch (property.Key.ToLower())
{
case "ison":
if ((bool)property.Value)
await deviceProxy.ExecuteCommandAsync(memento.DeviceId, "turnon");
else
await deviceProxy.ExecuteCommandAsync(memento.DeviceId, "turnoff");
break;
case "brightness":
await deviceProxy.ExecuteCommandAsync(memento.DeviceId, "setbrightness", property.Value);
break;
case "temperature":
await deviceProxy.ExecuteCommandAsync(memento.DeviceId, "settemperature", property.Value);
break;
case "color":
await deviceProxy.ExecuteCommandAsync(memento.DeviceId, "setcolor", property.Value);
break;
case "mode":
await deviceProxy.ExecuteCommandAsync(memento.DeviceId, "setmode", property.Value);
break;
}
}
}
public int GetStateHistoryCount() => stateHistory.Count;
}
// 5. 外观模式:简化接口
public class SmartHomeFacade
{
private readonly IHomeAutomationMediator mediator;
private readonly IDeviceProxy deviceProxy;
private readonly HomeStateCaretaker stateCaretaker;
private readonly Dictionary<string, SmartDevice> devices;
public SmartHomeFacade()
{
var authService = new SimpleAuthenticationService();
deviceProxy = new SecureDeviceProxy(authService);
mediator = new HomeAutomationMediator(deviceProxy);
stateCaretaker = new HomeStateCaretaker(deviceProxy);
devices = new Dictionary<string, SmartDevice>();
InitializeDevices();
}
private void InitializeDevices()
{
// 创建客厅
var livingRoom = new Room("living_room", "客厅");
var livingRoomLight = new Light("living_room_light", "客厅灯");
var livingRoomAC = new AirConditioner("living_room_ac", "客厅空调");
livingRoom.AddDevice(livingRoomLight);
livingRoom.AddDevice(livingRoomAC);
// 创建卧室
var bedroom = new Room("bedroom", "卧室");
var bedroomLight = new Light("bedroom_light", "卧室灯");
bedroom.AddDevice(bedroomLight);
// 注册设备
var allDevices = new List<SmartDevice>
{
livingRoom, livingRoomLight, livingRoomAC,
bedroom, bedroomLight
};
foreach (var device in allDevices)
{
devices[device.Id] = device;
((SecureDeviceProxy)deviceProxy).RegisterDevice(device);
mediator.RegisterDeviceAsync(device);
}
}
// 简化的用户接口
public async Task<string> WelcomeHomeAsync()
{
await stateCaretaker.SaveCurrentStateAsync(
devices.Keys.ToList(),
"外出前状态"
);
await mediator.ExecuteSceneAsync("回家");
return "欢迎回家!灯光和空调已为您准备就绪。";
}
public async Task<string> GoToBedAsync()
{
await mediator.ExecuteSceneAsync("睡眠");
return "晚安!已为您调整为睡眠模式。";
}
public async Task<string> LeaveHomeAsync()
{
await mediator.ExecuteSceneAsync("外出");
return "再见!所有设备已关闭,为您节能。";
}
public async Task<string> SetRoomTemperatureAsync(string roomName, int temperature)
{
string deviceId = roomName.ToLower() switch
{
"客厅" => "living_room_ac",
"卧室" => "bedroom_ac",
_ => null
};
if (deviceId == null)
{
return "未找到指定房间的空调";
}
var success = await deviceProxy.ExecuteCommandAsync(deviceId, "settemperature", temperature);
return success ? $"{roomName}温度已设置为{temperature}°C" : "设置失败";
}
public async Task<string> ControlLightAsync(string roomName, bool turnOn, int? brightness = null)
{
string deviceId = roomName.ToLower() switch
{
"客厅" => "living_room_light",
"卧室" => "bedroom_light",
_ => null
};
if (deviceId == null)
{
return "未找到指定房间的灯光";
}
string command = turnOn ? "turnon" : "turnoff";
var success = await deviceProxy.ExecuteCommandAsync(deviceId, command);
if (success && turnOn && brightness.HasValue)
{
await deviceProxy.ExecuteCommandAsync(deviceId, "setbrightness", brightness.Value);
return $"{roomName}灯光已开启,亮度设置为{brightness}%";
}
return success ? $"{roomName}灯光已{(turnOn ? "开启" : "关闭")}" : "操作失败";
}
public async Task<string> RestoreLastStateAsync()
{
var success = await stateCaretaker.RestoreLastStateAsync();
return success ? "已恢复到上次保存的状态" : "没有可恢复的状态";
}
public async Task<string> GetHomeStatusAsync()
{
var status = new List<string>();
foreach (var device in devices.Values)
{
var deviceStatus = await device.GetStatusAsync();
status.Add($"{deviceStatus.DeviceName}: {(deviceStatus.IsOnline ? "在线" : "离线")}");
}
return $"智能家居状态:\n{string.Join("\n", status)}";
}
}
// 辅助类
public class DeviceStatus
{
public string DeviceId { get; set; }
public string DeviceName { get; set; }
public bool IsOnline { get; set; }
public Dictionary<string, object> Properties { get; set; }
public List<DeviceStatus> ChildStatuses { get; set; }
public DeviceStatus()
{
Properties = new Dictionary<string, object>();
ChildStatuses = new List<DeviceStatus>();
}
}
public class Scene
{
public string Name { get; set; }
public List<SceneAction> Actions { get; set; }
public Scene()
{
Actions = new List<SceneAction>();
}
}
public class SceneAction
{
public string DeviceId { get; set; }
public string Command { get; set; }
public object Parameter { get; set; }
}
public interface IAuthenticationService
{
Task<bool> IsAuthorizedAsync(string command);
}
public class SimpleAuthenticationService : IAuthenticationService
{
public async Task<bool> IsAuthorizedAsync(string command)
{
await Task.Delay(50); // 模拟权限检查
return true; // 简化实现,总是返回授权
}
}
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
694
695
696
697
698
699
700
701
702
703
704
705
706
707
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
694
695
696
697
698
699
700
701
702
703
704
705
706
707
# 案例5:在线学习平台
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
// 组合:迭代器 + 解释器 + 享元 + 单例 + 抽象工厂
// 1. 享元模式:课程内容共享
public interface IContentFlyweight
{
Task<string> RenderAsync(ContentContext context);
string GetContentType();
}
public class VideoContentFlyweight : IContentFlyweight
{
private readonly string videoTemplate;
public VideoContentFlyweight()
{
videoTemplate = "<video controls><source src='{0}' type='video/mp4'>您的浏览器不支持视频播放。</video>";
}
public async Task<string> RenderAsync(ContentContext context)
{
await Task.Delay(100); // 模拟渲染时间
return string.Format(videoTemplate, context.Url) +
$"<p>时长: {context.Duration}分钟</p>" +
$"<p>质量: {context.Quality}</p>";
}
public string GetContentType() => "视频";
}
public class TextContentFlyweight : IContentFlyweight
{
private readonly string textTemplate;
public TextContentFlyweight()
{
textTemplate = "<div class='text-content'><h3>{0}</h3><p>{1}</p></div>";
}
public async Task<string> RenderAsync(ContentContext context)
{
await Task.Delay(50);
return string.Format(textTemplate, context.Title, context.Content);
}
public string GetContentType() => "文本";
}
public class AudioContentFlyweight : IContentFlyweight
{
private readonly string audioTemplate;
public AudioContentFlyweight()
{
audioTemplate = "<audio controls><source src='{0}' type='audio/mpeg'>您的浏览器不支持音频播放。</audio>";
}
public async Task<string> RenderAsync(ContentContext context)
{
await Task.Delay(80);
return string.Format(audioTemplate, context.Url) +
$"<p>时长: {context.Duration}分钟</p>";
}
public string GetContentType() => "音频";
}
// 享元工厂
public class ContentFlyweightFactory
{
private static readonly Dictionary<string, IContentFlyweight> flyweights =
new Dictionary<string, IContentFlyweight>();
public static IContentFlyweight GetFlyweight(string contentType)
{
if (!flyweights.ContainsKey(contentType))
{
flyweights[contentType] = contentType.ToLower() switch
{
"video" => new VideoContentFlyweight(),
"text" => new TextContentFlyweight(),
"audio" => new AudioContentFlyweight(),
_ => throw new ArgumentException("不支持的内容类型")
};
}
return flyweights[contentType];
}
public static int GetFlyweightCount() => flyweights.Count;
}
// 内容上下文(外部状态)
public class ContentContext
{
public string Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public string Url { get; set; }
public int Duration { get; set; }
public string Quality { get; set; }
public string Author { get; set; }
public DateTime CreateTime { get; set; }
}
// 2. 迭代器模式:课程内容遍历
public interface IIterator<T>
{
bool HasNext();
T Next();
void Reset();
}
public interface IAggregate<T>
{
IIterator<T> CreateIterator();
int Count { get; }
}
public class Course : IAggregate<CourseContent>
{
private List<CourseContent> contents;
public string Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Instructor { get; set; }
public CourseDifficulty Difficulty { get; set; }
public int Count => contents.Count;
public Course(string id, string title, string instructor, CourseDifficulty difficulty)
{
Id = id;
Title = title;
Instructor = instructor;
Difficulty = difficulty;
contents = new List<CourseContent>();
}
public void AddContent(CourseContent content)
{
contents.Add(content);
}
public IIterator<CourseContent> CreateIterator()
{
return new CourseIterator(contents);
}
public IIterator<CourseContent> CreateFilteredIterator(ContentType contentType)
{
return new FilteredCourseIterator(contents, contentType);
}
public IIterator<CourseContent> CreateSequentialIterator()
{
return new SequentialCourseIterator(contents);
}
}
public class CourseIterator : IIterator<CourseContent>
{
private readonly List<CourseContent> contents;
private int currentIndex;
public CourseIterator(List<CourseContent> contents)
{
this.contents = contents;
currentIndex = 0;
}
public bool HasNext()
{
return currentIndex < contents.Count;
}
public CourseContent Next()
{
if (!HasNext())
throw new InvalidOperationException("没有更多元素");
return contents[currentIndex++];
}
public void Reset()
{
currentIndex = 0;
}
}
public class FilteredCourseIterator : IIterator<CourseContent>
{
private readonly List<CourseContent> filteredContents;
private int currentIndex;
public FilteredCourseIterator(List<CourseContent> contents, ContentType filterType)
{
filteredContents = contents.Where(c => c.Type == filterType).ToList();
currentIndex = 0;
}
public bool HasNext()
{
return currentIndex < filteredContents.Count;
}
public CourseContent Next()
{
if (!HasNext())
throw new InvalidOperationException("没有更多元素");
return filteredContents[currentIndex++];
}
public void Reset()
{
currentIndex = 0;
}
}
public class SequentialCourseIterator : IIterator<CourseContent>
{
private readonly List<CourseContent> contents;
private int currentIndex;
private bool isCompleted;
public SequentialCourseIterator(List<CourseContent> contents)
{
this.contents = contents.OrderBy(c => c.Order).ToList();
currentIndex = 0;
isCompleted = false;
}
public bool HasNext()
{
return currentIndex < contents.Count && !isCompleted;
}
public CourseContent Next()
{
if (!HasNext())
throw new InvalidOperationException("课程已完成或没有更多内容");
var content = contents[currentIndex++];
if (currentIndex >= contents.Count)
{
isCompleted = true;
}
return content;
}
public void Reset()
{
currentIndex = 0;
isCompleted = false;
}
}
// 3. 解释器模式:学习进度查询语言
public interface IExpression
{
bool Interpret(StudentProgress context);
}
public class StudentProgress
{
public string StudentId { get; set; }
public Dictionary<string, int> CourseProgress { get; set; } // courseId -> progress%
public Dictionary<string, int> CourseScores { get; set; } // courseId -> score
public HashSet<string> CompletedCourses { get; set; }
public DateTime LastAccessTime { get; set; }
public int TotalStudyHours { get; set; }
public StudentProgress(string studentId)
{
StudentId = studentId;
CourseProgress = new Dictionary<string, int>();
CourseScores = new Dictionary<string, int>();
CompletedCourses = new HashSet<string>();
LastAccessTime = DateTime.Now;
TotalStudyHours = 0;
}
}
// 终结符表达式
public class ProgressExpression : IExpression
{
private readonly string courseId;
private readonly string operator_;
private readonly int value;
public ProgressExpression(string courseId, string operator_, int value)
{
this.courseId = courseId;
this.operator_ = operator_;
this.value = value;
}
public bool Interpret(StudentProgress context)
{
if (!context.CourseProgress.ContainsKey(courseId))
return false;
int progress = context.CourseProgress[courseId];
return operator_ switch
{
">" => progress > value,
"<" => progress < value,
"=" => progress == value,
">=" => progress >= value,
"<=" => progress <= value,
_ => false
};
}
}
public class ScoreExpression : IExpression
{
private readonly string courseId;
private readonly string operator_;
private readonly int value;
public ScoreExpression(string courseId, string operator_, int value)
{
this.courseId = courseId;
this.operator_ = operator_;
this.value = value;
}
public bool Interpret(StudentProgress context)
{
if (!context.CourseScores.ContainsKey(courseId))
return false;
int score = context.CourseScores[courseId];
return operator_ switch
{
">" => score > value,
"<" => score < value,
"=" => score == value,
">=" => score >= value,
"<=" => score <= value,
_ => false
};
}
}
public class CompletedExpression : IExpression
{
private readonly string courseId;
public CompletedExpression(string courseId)
{
this.courseId = courseId;
}
public bool Interpret(StudentProgress context)
{
return context.CompletedCourses.Contains(courseId);
}
}
// 非终结符表达式
public class AndExpression : IExpression
{
private readonly IExpression left;
private readonly IExpression right;
public AndExpression(IExpression left, IExpression right)
{
this.left = left;
this.right = right;
}
public bool Interpret(StudentProgress context)
{
return left.Interpret(context) && right.Interpret(context);
}
}
public class OrExpression : IExpression
{
private readonly IExpression left;
private readonly IExpression right;
public OrExpression(IExpression left, IExpression right)
{
this.left = left;
this.right = right;
}
public bool Interpret(StudentProgress context)
{
return left.Interpret(context) || right.Interpret(context);
}
}
// 查询语言解析器
public class ProgressQueryParser
{
public static IExpression Parse(string query)
{
// 简化的解析实现,实际应该用更复杂的解析器
// 支持的查询格式:
// "progress(course1) >= 80"
// "score(course1) > 60 AND completed(course2)"
// "progress(course1) >= 50 OR score(course2) >= 70"
query = query.Trim();
if (query.Contains(" AND "))
{
var parts = query.Split(" AND ");
var left = Parse(parts[0].Trim());
var right = Parse(parts[1].Trim());
return new AndExpression(left, right);
}
if (query.Contains(" OR "))
{
var parts = query.Split(" OR ");
var left = Parse(parts[0].Trim());
var right = Parse(parts[1].Trim());
return new OrExpression(left, right);
}
// 解析单个表达式
if (query.StartsWith("progress("))
{
return ParseProgressExpression(query);
}
else if (query.StartsWith("score("))
{
return ParseScoreExpression(query);
}
else if (query.StartsWith("completed("))
{
return ParseCompletedExpression(query);
}
throw new ArgumentException($"无法解析查询: {query}");
}
private static IExpression ParseProgressExpression(string expr)
{
// progress(courseId) operator value
var match = System.Text.RegularExpressions.Regex.Match(
expr, @"progress\(([^)]+)\)\s*([><=]+)\s*(\d+)");
if (match.Success)
{
string courseId = match.Groups[1].Value;
string operator_ = match.Groups[2].Value;
int value = int.Parse(match.Groups[3].Value);
return new ProgressExpression(courseId, operator_, value);
}
throw new ArgumentException($"无法解析进度表达式: {expr}");
}
private static IExpression ParseScoreExpression(string expr)
{
var match = System.Text.RegularExpressions.Regex.Match(
expr, @"score\(([^)]+)\)\s*([><=]+)\s*(\d+)");
if (match.Success)
{
string courseId = match.Groups[1].Value;
string operator_ = match.Groups[2].Value;
int value = int.Parse(match.Groups[3].Value);
return new ScoreExpression(courseId, operator_, value);
}
throw new ArgumentException($"无法解析分数表达式: {expr}");
}
private static IExpression ParseCompletedExpression(string expr)
{
var match = System.Text.RegularExpressions.Regex.Match(
expr, @"completed\(([^)]+)\)");
if (match.Success)
{
string courseId = match.Groups[1].Value;
return new CompletedExpression(courseId);
}
throw new ArgumentException($"无法解析完成表达式: {expr}");
}
}
// 4. 单例模式:学习分析服务
public class LearningAnalyticsService
{
private static LearningAnalyticsService _instance;
private static readonly object _lock = new object();
private readonly Dictionary<string, StudentProgress> studentProgresses;
private readonly List<LearningEvent> events;
private LearningAnalyticsService()
{
studentProgresses = new Dictionary<string, StudentProgress>();
events = new List<LearningEvent>();
}
public static LearningAnalyticsService Instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null)
_instance = new LearningAnalyticsService();
}
}
return _instance;
}
}
public void TrackEvent(LearningEvent learningEvent)
{
events.Add(learningEvent);
UpdateStudentProgress(learningEvent);
}
private void UpdateStudentProgress(LearningEvent learningEvent)
{
if (!studentProgresses.ContainsKey(learningEvent.StudentId))
{
studentProgresses[learningEvent.StudentId] = new StudentProgress(learningEvent.StudentId);
}
var progress = studentProgresses[learningEvent.StudentId];
switch (learningEvent.EventType)
{
case LearningEventType.ContentCompleted:
if (!progress.CourseProgress.ContainsKey(learningEvent.CourseId))
progress.CourseProgress[learningEvent.CourseId] = 0;
progress.CourseProgress[learningEvent.CourseId] += 10; // 每完成内容增加10%
break;
case LearningEventType.CourseCompleted:
progress.CompletedCourses.Add(learningEvent.CourseId);
progress.CourseProgress[learningEvent.CourseId] = 100;
break;
case LearningEventType.TestCompleted:
progress.CourseScores[learningEvent.CourseId] = learningEvent.Score;
break;
}
progress.LastAccessTime = learningEvent.Timestamp;
progress.TotalStudyHours += learningEvent.StudyMinutes / 60;
}
public StudentProgress GetStudentProgress(string studentId)
{
return studentProgresses.GetValueOrDefault(studentId);
}
public async Task<List<string>> QueryStudentsAsync(string query)
{
await Task.Delay(100); // 模拟数据库查询
var expression = ProgressQueryParser.Parse(query);
var matchingStudents = new List<string>();
foreach (var progress in studentProgresses.Values)
{
if (expression.Interpret(progress))
{
matchingStudents.Add(progress.StudentId);
}
}
return matchingStudents;
}
public LearningAnalyticsReport GenerateReport(string studentId)
{
var progress = GetStudentProgress(studentId);
if (progress == null) return null;
return new LearningAnalyticsReport
{
StudentId = studentId,
TotalCourses = progress.CourseProgress.Count,
CompletedCourses = progress.CompletedCourses.Count,
AverageScore = progress.CourseScores.Values.Any() ?
progress.CourseScores.Values.Average() : 0,
TotalStudyHours = progress.TotalStudyHours,
LastAccessTime = progress.LastAccessTime
};
}
}
// 5. 抽象工厂模式:不同平台的UI组件
public interface IUIComponentFactory
{
IButton CreateButton();
ITextBox CreateTextBox();
IVideoPlayer CreateVideoPlayer();
string GetPlatformName();
}
public interface IButton
{
Task<string> RenderAsync(string text);
Task OnClickAsync();
}
public interface ITextBox
{
Task<string> RenderAsync(string placeholder);
Task SetValueAsync(string value);
}
public interface IVideoPlayer
{
Task<string> RenderAsync(string videoUrl);
Task PlayAsync();
Task PauseAsync();
}
// Web平台组件工厂
public class WebUIComponentFactory : IUIComponentFactory
{
public IButton CreateButton() => new WebButton();
public ITextBox CreateTextBox() => new WebTextBox();
public IVideoPlayer CreateVideoPlayer() => new WebVideoPlayer();
public string GetPlatformName() => "Web";
}
public class WebButton : IButton
{
public async Task<string> RenderAsync(string text)
{
await Task.Delay(50);
return $"<button class='web-button'>{text}</button>";
}
public async Task OnClickAsync()
{
await Task.Delay(100);
Console.WriteLine("Web按钮被点击");
}
}
public class WebTextBox : ITextBox
{
private string value = "";
public async Task<string> RenderAsync(string placeholder)
{
await Task.Delay(30);
return $"<input type='text' class='web-textbox' placeholder='{placeholder}' value='{value}' />";
}
public async Task SetValueAsync(string value)
{
await Task.Delay(10);
this.value = value;
Console.WriteLine($"Web文本框值设置为: {value}");
}
}
public class WebVideoPlayer : IVideoPlayer
{
public async Task<string> RenderAsync(string videoUrl)
{
await Task.Delay(200);
return $"<video controls class='web-video-player'><source src='{videoUrl}' type='video/mp4'></video>";
}
public async Task PlayAsync()
{
await Task.Delay(100);
Console.WriteLine("Web视频播放器开始播放");
}
public async Task PauseAsync()
{
await Task.Delay(50);
Console.WriteLine("Web视频播放器暂停播放");
}
}
// 移动端组件工厂
public class MobileUIComponentFactory : IUIComponentFactory
{
public IButton CreateButton() => new MobileButton();
public ITextBox CreateTextBox() => new MobileTextBox();
public IVideoPlayer CreateVideoPlayer() => new MobileVideoPlayer();
public string GetPlatformName() => "Mobile";
}
public class MobileButton : IButton
{
public async Task<string> RenderAsync(string text)
{
await Task.Delay(50);
return $"<TouchableOpacity style='mobileButtonStyle'><Text>{text}</Text></TouchableOpacity>";
}
public async Task OnClickAsync()
{
await Task.Delay(150);
Console.WriteLine("移动端按钮被触摸");
}
}
public class MobileTextBox : ITextBox
{
private string value = "";
public async Task<string> RenderAsync(string placeholder)
{
await Task.Delay(40);
return $"<TextInput style='mobileTextInputStyle' placeholder='{placeholder}' value='{value}' />";
}
public async Task SetValueAsync(string value)
{
await Task.Delay(20);
this.value = value;
Console.WriteLine($"移动端文本输入框值设置为: {value}");
}
}
public class MobileVideoPlayer : IVideoPlayer
{
public async Task<string> RenderAsync(string videoUrl)
{
await Task.Delay(300);
return $"<Video source={{uri: '{videoUrl}'}} style='mobileVideoStyle' controls={{true}} />";
}
public async Task PlayAsync()
{
await Task.Delay(200);
Console.WriteLine("移动端视频播放器开始播放");
}
public async Task PauseAsync()
{
await Task.Delay(100);
Console.WriteLine("移动端视频播放器暂停播放");
}
}
// 桌面端组件工厂
public class DesktopUIComponentFactory : IUIComponentFactory
{
public IButton CreateButton() => new DesktopButton();
public ITextBox CreateTextBox() => new DesktopTextBox();
public IVideoPlayer CreateVideoPlayer() => new DesktopVideoPlayer();
public string GetPlatformName() => "Desktop";
}
public class DesktopButton : IButton
{
public async Task<string> RenderAsync(string text)
{
await Task.Delay(30);
return $"[Button: {text}]";
}
public async Task OnClickAsync()
{
await Task.Delay(80);
Console.WriteLine("桌面端按钮被点击");
}
}
public class DesktopTextBox : ITextBox
{
private string value = "";
public async Task<string> RenderAsync(string placeholder)
{
await Task.Delay(20);
return $"[TextBox: {placeholder}] = '{value}'";
}
public async Task SetValueAsync(string value)
{
await Task.Delay(10);
this.value = value;
Console.WriteLine($"桌面端文本框值设置为: {value}");
}
}
public class DesktopVideoPlayer : IVideoPlayer
{
public async Task<string> RenderAsync(string videoUrl)
{
await Task.Delay(150);
return $"[VideoPlayer: {videoUrl}]";
}
public async Task PlayAsync()
{
await Task.Delay(120);
Console.WriteLine("桌面端视频播放器开始播放");
}
public async Task PauseAsync()
{
await Task.Delay(60);
Console.WriteLine("桌面端视频播放器暂停播放");
}
}
// 平台工厂选择器
public class UIComponentFactoryProvider
{
public static IUIComponentFactory GetFactory(PlatformType platformType)
{
return platformType switch
{
PlatformType.Web => new WebUIComponentFactory(),
PlatformType.Mobile => new MobileUIComponentFactory(),
PlatformType.Desktop => new DesktopUIComponentFactory(),
_ => throw new ArgumentException("不支持的平台类型")
};
}
}
// 辅助枚举和类
public enum PlatformType
{
Web,
Mobile,
Desktop
}
public enum ContentType
{
Video,
Text,
Audio,
Quiz,
Assignment
}
public enum CourseDifficulty
{
Beginner,
Intermediate,
Advanced,
Expert
}
public enum LearningEventType
{
ContentViewed,
ContentCompleted,
TestStarted,
TestCompleted,
CourseStarted,
CourseCompleted
}
public class CourseContent
{
public string Id { get; set; }
public string Title { get; set; }
public ContentType Type { get; set; }
public int Order { get; set; }
public ContentContext Context { get; set; }
public IContentFlyweight Flyweight { get; set; }
public CourseContent(string id, string title, ContentType type, int order)
{
Id = id;
Title = title;
Type = type;
Order = order;
Context = new ContentContext { Id = id, Title = title };
string flyweightType = type switch
{
ContentType.Video => "video",
ContentType.Audio => "audio",
_ => "text"
};
Flyweight = ContentFlyweightFactory.GetFlyweight(flyweightType);
}
public async Task<string> RenderAsync()
{
return await Flyweight.RenderAsync(Context);
}
}
public class LearningEvent
{
public string StudentId { get; set; }
public string CourseId { get; set; }
public string ContentId { get; set; }
public LearningEventType EventType { get; set; }
public DateTime Timestamp { get; set; }
public int StudyMinutes { get; set; }
public int Score { get; set; }
public Dictionary<string, object> AdditionalData { get; set; }
public LearningEvent()
{
Timestamp = DateTime.Now;
AdditionalData = new Dictionary<string, object>();
}
}
public class LearningAnalyticsReport
{
public string StudentId { get; set; }
public int TotalCourses { get; set; }
public int CompletedCourses { get; set; }
public double AverageScore { get; set; }
public int TotalStudyHours { get; set; }
public DateTime LastAccessTime { get; set; }
public double CompletionRate => TotalCourses > 0 ? (double)CompletedCourses / TotalCourses * 100 : 0;
}
// 主要的学习平台类
public class LearningPlatform
{
private readonly IUIComponentFactory uiFactory;
private readonly LearningAnalyticsService analyticsService;
private readonly Dictionary<string, Course> courses;
private readonly Dictionary<string, StudentProgress> studentProgresses;
public LearningPlatform(PlatformType platformType)
{
uiFactory = UIComponentFactoryProvider.GetFactory(platformType);
analyticsService = LearningAnalyticsService.Instance;
courses = new Dictionary<string, Course>();
studentProgresses = new Dictionary<string, StudentProgress>();
InitializeSampleCourses();
}
private void InitializeSampleCourses()
{
// 创建示例课程:C# 基础编程
var csharpCourse = new Course("cs001", "C# 基础编程", "张老师", CourseDifficulty.Beginner);
var content1 = new CourseContent("cs001_01", "C# 简介", ContentType.Video, 1);
content1.Context.Url = "https://example.com/videos/csharp_intro.mp4";
content1.Context.Duration = 15;
content1.Context.Quality = "1080p";
var content2 = new CourseContent("cs001_02", "变量和数据类型", ContentType.Text, 2);
content2.Context.Content = "在C#中,变量是存储数据的容器...";
var content3 = new CourseContent("cs001_03", "控制结构讲解", ContentType.Audio, 3);
content3.Context.Url = "https://example.com/audio/control_structures.mp3";
content3.Context.Duration = 20;
csharpCourse.AddContent(content1);
csharpCourse.AddContent(content2);
csharpCourse.AddContent(content3);
courses[csharpCourse.Id] = csharpCourse;
// 创建示例课程:数据结构与算法
var algorithmCourse = new Course("algo001", "数据结构与算法", "李老师", CourseDifficulty.Intermediate);
var algoContent1 = new CourseContent("algo001_01", "数组和链表", ContentType.Video, 1);
algoContent1.Context.Url = "https://example.com/videos/arrays_linkedlists.mp4";
algoContent1.Context.Duration = 25;
algoContent1.Context.Quality = "1080p";
var algoContent2 = new CourseContent("algo001_02", "排序算法", ContentType.Text, 2);
algoContent2.Context.Content = "常见的排序算法包括冒泡排序、快速排序...";
algorithmCourse.AddContent(algoContent1);
algorithmCourse.AddContent(algoContent2);
courses[algorithmCourse.Id] = algorithmCourse;
}
public async Task<string> RenderCoursePageAsync(string courseId, string studentId)
{
if (!courses.ContainsKey(courseId))
{
return "课程不存在";
}
var course = courses[courseId];
var platformName = uiFactory.GetPlatformName();
Console.WriteLine($"为 {platformName} 平台渲染课程页面");
var pageHtml = $"<h1>{course.Title}</h1>\n";
pageHtml += $"<p>讲师: {course.Instructor}</p>\n";
pageHtml += $"<p>难度: {course.Difficulty}</p>\n";
pageHtml += $"<p>内容数量: {course.Count}</p>\n\n";
// 渲染UI组件
var playButton = uiFactory.CreateButton();
var progressText = uiFactory.CreateTextBox();
pageHtml += await playButton.RenderAsync("开始学习");
pageHtml += "\n";
pageHtml += await progressText.RenderAsync("学习进度");
pageHtml += "\n\n";
// 渲染课程内容
var iterator = course.CreateIterator();
while (iterator.HasNext())
{
var content = iterator.Next();
pageHtml += $"<div class='content-item'>\n";
pageHtml += $" <h3>{content.Title}</h3>\n";
pageHtml += $" <p>类型: {content.Type}</p>\n";
if (content.Type == ContentType.Video)
{
var videoPlayer = uiFactory.CreateVideoPlayer();
pageHtml += await videoPlayer.RenderAsync(content.Context.Url);
}
else
{
pageHtml += await content.RenderAsync();
}
pageHtml += "\n</div>\n\n";
}
return pageHtml;
}
public async Task<bool> StartLearningAsync(string studentId, string courseId, string contentId)
{
Console.WriteLine($"学生 {studentId} 开始学习课程 {courseId} 的内容 {contentId}");
var learningEvent = new LearningEvent
{
StudentId = studentId,
CourseId = courseId,
ContentId = contentId,
EventType = LearningEventType.ContentViewed,
StudyMinutes = 10 // 假设观看了10分钟
};
analyticsService.TrackEvent(learningEvent);
await Task.Delay(1000); // 模拟学习时间
// 完成内容学习
var completionEvent = new LearningEvent
{
StudentId = studentId,
CourseId = courseId,
ContentId = contentId,
EventType = LearningEventType.ContentCompleted,
StudyMinutes = 15
};
analyticsService.TrackEvent(completionEvent);
Console.WriteLine($"学生 {studentId} 完成了内容 {contentId} 的学习");
return true;
}
public async Task<bool> CompleteCourseAsync(string studentId, string courseId, int finalScore)
{
Console.WriteLine($"学生 {studentId} 完成课程 {courseId},最终成绩: {finalScore}");
var completionEvent = new LearningEvent
{
StudentId = studentId,
CourseId = courseId,
EventType = LearningEventType.CourseCompleted,
Score = finalScore,
StudyMinutes = 120 // 假设总共学了2小时
};
analyticsService.TrackEvent(completionEvent);
await Task.Delay(500);
return true;
}
public async Task<List<string>> QueryStudentsByProgressAsync(string query)
{
Console.WriteLine($"执行学习进度查询: {query}");
return await analyticsService.QueryStudentsAsync(query);
}
public LearningAnalyticsReport GetStudentReport(string studentId)
{
return analyticsService.GenerateReport(studentId);
}
public async Task<string> RenderStudentDashboardAsync(string studentId)
{
var report = GetStudentReport(studentId);
if (report == null)
{
return "学生数据不存在";
}
var platformName = uiFactory.GetPlatformName();
Console.WriteLine($"为 {platformName} 平台渲染学生仪表板");
var dashboard = $"<h1>学习仪表板 - 学生 {studentId}</h1>\n";
dashboard += $"<p>总课程数: {report.TotalCourses}</p>\n";
dashboard += $"<p>已完成课程: {report.CompletedCourses}</p>\n";
dashboard += $"<p>完成率: {report.CompletionRate:F1}%</p>\n";
dashboard += $"<p>平均分数: {report.AverageScore:F1}</p>\n";
dashboard += $"<p>总学习时长: {report.TotalStudyHours} 小时</p>\n";
dashboard += $"<p>最后访问时间: {report.LastAccessTime:yyyy-MM-dd HH:mm:ss}</p>\n\n";
// 添加UI组件
var refreshButton = uiFactory.CreateButton();
var searchBox = uiFactory.CreateTextBox();
dashboard += await refreshButton.RenderAsync("刷新数据");
dashboard += "\n";
dashboard += await searchBox.RenderAsync("搜索课程...");
dashboard += "\n";
return dashboard;
}
public void PrintFlyweightStatistics()
{
Console.WriteLine($"当前享元对象数量: {ContentFlyweightFactory.GetFlyweightCount()}");
Console.WriteLine("享元模式有效减少了内存使用");
}
}
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
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
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
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
# 完整的测试和使用示例
using System;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("=== 设计模式综合案例演示 ===\n");
// 案例1:电商订单处理系统
await DemoECommerceSystem();
Console.WriteLine("\n" + new string('=', 50) + "\n");
// 案例2:游戏角色系统
await DemoGameCharacterSystem();
Console.WriteLine("\n" + new string('=', 50) + "\n");
// 案例3:文档处理系统
await DemoDocumentProcessingSystem();
Console.WriteLine("\n" + new string('=', 50) + "\n");
// 案例4:智能家居控制系统
await DemoSmartHomeSystem();
Console.WriteLine("\n" + new string('=', 50) + "\n");
// 案例5:在线学习平台
await DemoLearningPlatform();
}
static async Task DemoECommerceSystem()
{
Console.WriteLine("【案例1:电商订单处理系统】");
Console.WriteLine("组合模式:单例 + 工厂 + 观察者 + 状态 + 策略\n");
// 创建订单
var order = new Order("ORD001", PaymentMethod.Alipay);
order.AddItem("商品A", 2, 99.99m);
order.AddItem("商品B", 1, 199.99m);
// 添加观察者
order.AddObserver(new EmailNotificationObserver());
order.AddObserver(new SMSNotificationObserver());
order.AddObserver(new InventoryObserver());
Console.WriteLine($"创建订单 {order.Id},总金额: {order.TotalAmount:C}");
Console.WriteLine($"当前状态: {order.GetCurrentState()}\n");
// 处理订单流程
for (int i = 0; i < 4; i++)
{
await order.ProcessAsync();
await Task.Delay(1000);
Console.WriteLine($"当前状态: {order.GetCurrentState()}\n");
}
}
static async Task DemoGameCharacterSystem()
{
Console.WriteLine("【案例2:游戏角色系统】");
Console.WriteLine("组合模式:建造者 + 装饰器 + 命令 + 观察者 + 工厂\n");
// 创建角色
var warrior = CharacterFactory.CreateCharacter(CharacterClass.Warrior, "勇敢的战士");
var mage = CharacterFactory.CreateAdvancedCharacter(CharacterClass.Mage, "强大的法师");
// 添加观察者
var logger = new CombatLogger();
var expManager = new ExperienceManager();
var achievementSystem = new AchievementSystem();
warrior.AddObserver(logger);
warrior.AddObserver(expManager);
warrior.AddObserver(achievementSystem);
mage.AddObserver(logger);
mage.AddObserver(expManager);
mage.AddObserver(achievementSystem);
Console.WriteLine($"{warrior.GetStatus()}");
Console.WriteLine($"{mage.GetStatus()}\n");
// 战斗模拟
Console.WriteLine("=== 战斗开始 ===");
// 法师攻击战士
if (mage.Skills.Count > 0)
{
await mage.Skills[0].ExecuteAsync(mage, warrior);
}
await Task.Delay(1000);
// 战士反击
if (warrior.Skills.Count > 0)
{
await warrior.Skills[0].ExecuteAsync(warrior, mage);
}
await Task.Delay(1000);
// 给战士施加中毒
warrior.ApplyPoison(3, 15);
// 更新角色状态
for (int turn = 0; turn < 5; turn++)
{
Console.WriteLine($"\n--- 第 {turn + 1} 回合 ---");
warrior.Update();
mage.Update();
await Task.Delay(800);
}
}
static async Task DemoDocumentProcessingSystem()
{
Console.WriteLine("【案例3:文档处理系统】");
Console.WriteLine("组合模式:适配器 + 桥接 + 责任链 + 访问者 + 原型\n");
var legacySystem = new LegacyDocumentSystem();
var documentManager = new DocumentManager(legacySystem);
// 创建文档
var textDoc = new TextDocument(new PlainTextProcessor())
{
Title = "技术文档",
Content = "这是一份重要的技术文档,包含了项目的详细说明...",
Author = "张三"
};
var richDoc = new RichDocument(new MarkdownProcessor())
{
Title = "项目介绍",
Content = "**欢迎使用我们的产品**\n\n这是一个*创新的*解决方案...",
Author = "李四"
};
richDoc.Images.Add("https://example.com/image1.jpg");
richDoc.Links.Add("https://example.com/docs");
// 添加文档
Console.WriteLine("=== 文档验证和添加 ===");
await documentManager.AddDocumentAsync(textDoc);
await documentManager.AddDocumentAsync(richDoc);
// 使用访问者模式分析文档
Console.WriteLine("\n=== 文档分析 ===");
var wordCountVisitor = new WordCountVisitor();
var result1 = await documentManager.AnalyzeDocumentsAsync(wordCountVisitor);
Console.WriteLine($"字数统计结果:总字数 {result1.TotalWords},平均每文档 {result1.AverageWordsPerDocument:F1} 字");
var securityVisitor = new SecurityAnalysisVisitor();
var result2 = await documentManager.AnalyzeDocumentsAsync(securityVisitor);
Console.WriteLine($"安全分析结果:{(result2.IsSecure ? "安全" : "存在安全问题")}");
// 使用原型模式创建模板
Console.WriteLine("\n=== 文档模板创建 ===");
var template = documentManager.CreateDocumentTemplate(textDoc);
Console.WriteLine($"创建模板:{template.Title}");
}
static async Task DemoSmartHomeSystem()
{
Console.WriteLine("【案例4:智能家居控制系统】");
Console.WriteLine("组合模式:外观 + 代理 + 中介者 + 备忘录 + 组合\n");
var smartHome = new SmartHomeFacade();
Console.WriteLine("=== 智能家居控制演示 ===");
// 回家场景
Console.WriteLine(await smartHome.WelcomeHomeAsync());
await Task.Delay(2000);
// 控制具体设备
Console.WriteLine(await smartHome.SetRoomTemperatureAsync("客厅", 22));
await Task.Delay(1000);
Console.WriteLine(await smartHome.ControlLightAsync("卧室", true, 60));
await Task.Delay(1000);
// 睡眠场景
Console.WriteLine(await smartHome.GoToBedAsync());
await Task.Delay(2000);
// 恢复之前的状态
Console.WriteLine(await smartHome.RestoreLastStateAsync());
await Task.Delay(1000);
// 查看家居状态
Console.WriteLine("\n" + await smartHome.GetHomeStatusAsync());
// 外出场景
Console.WriteLine(await smartHome.LeaveHomeAsync());
}
static async Task DemoLearningPlatform()
{
Console.WriteLine("【案例5:在线学习平台】");
Console.WriteLine("组合模式:迭代器 + 解释器 + 享元 + 单例 + 抽象工厂\n");
// 创建不同平台的学习平台
var webPlatform = new LearningPlatform(PlatformType.Web);
var mobilePlatform = new LearningPlatform(PlatformType.Mobile);
Console.WriteLine("=== Web平台课程页面 ===");
var webCoursePage = await webPlatform.RenderCoursePageAsync("cs001", "student001");
Console.WriteLine(webCoursePage.Substring(0, Math.Min(500, webCoursePage.Length)) + "...");
Console.WriteLine("\n=== 移动端课程页面 ===");
var mobileCoursePage = await mobilePlatform.RenderCoursePageAsync("cs001", "student001");
Console.WriteLine(mobileCoursePage.Substring(0, Math.Min(500, mobileCoursePage.Length)) + "...");
// 模拟学习过程
Console.WriteLine("\n=== 学习过程模拟 ===");
await webPlatform.StartLearningAsync("student001", "cs001", "cs001_01");
await webPlatform.StartLearningAsync("student001", "cs001", "cs001_02");
await webPlatform.CompleteCourseAsync("student001", "cs001", 85);
await webPlatform.StartLearningAsync("student002", "algo001", "algo001_01");
await webPlatform.CompleteCourseAsync("student002", "algo001", 92);
// 生成学习报告
Console.WriteLine("\n=== 学习分析报告 ===");
var report1 = webPlatform.GetStudentReport("student001");
var report2 = webPlatform.GetStudentReport("student002");
Console.WriteLine($"学生001报告:完成率 {report1.CompletionRate:F1}%,平均分 {report1.AverageScore:F1}");
Console.WriteLine($"学生002报告:完成率 {report2.CompletionRate:F1}%,平均分 {report2.AverageScore:F1}");
// 使用解释器模式查询学生
Console.WriteLine("\n=== 智能查询演示 ===");
var highPerformers = await webPlatform.QueryStudentsByProgressAsync("score(cs001) >= 80");
Console.WriteLine($"C#课程得分80分以上的学生:{string.Join(", ", highPerformers)}");
var completedStudents = await webPlatform.QueryStudentsByProgressAsync("completed(cs001) OR completed(algo001)");
Console.WriteLine($"已完成任一课程的学生:{string.Join(", ", completedStudents)}");
// 渲染学生仪表板
Console.WriteLine("\n=== 学生仪表板 ===");
var dashboard = await webPlatform.RenderStudentDashboardAsync("student001");
Console.WriteLine(dashboard);
// 显示享元统计
Console.WriteLine("\n=== 性能统计 ===");
webPlatform.PrintFlyweightStatistics();
}
}
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
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
# 总结
通过以上5个综合案例,我们展示了如何将多种设计模式有机结合来解决实际问题:
# 1. 电商订单处理系统
- 单例模式:库存服务、支付工厂的唯一实例
- 工厂模式:支付方式的创建
- 观察者模式:订单状态变化通知
- 状态模式:订单生命周期管理
- 策略模式:不同支付方式的处理
# 2. 游戏角色系统
- 建造者模式:复杂角色对象的构建
- 装饰器模式:装备系统的层次增强
- 命令模式:技能系统的封装
- 观察者模式:战斗事件的响应
- 工厂模式:角色类型的创建
# 3. 文档处理系统
- 适配器模式:旧系统的集成
- 桥接模式:文档格式与处理器分离
- 责任链模式:文档验证流程
- 访问者模式:文档分析功能
- 原型模式:文档模板复制
# 4. 智能家居控制系统
- 外观模式:复杂系统的简化接口
- 代理模式:设备访问控制
- 中介者模式:设备间的协调
- 备忘录模式:状态保存与恢复
- 组合模式:设备层次结构
# 5. 在线学习平台
- 迭代器模式:课程内容的遍历
- 解释器模式:学习进度查询语言
- 享元模式:内容类型的共享
- 单例模式:分析服务的全局访问
- 抽象工厂模式:跨平台UI组件
这些案例展示了设计模式在实际项目中的应用,每个模式都有其特定的职责,通过合理组合可以构建出灵活、可扩展、易维护的软件系统。
编辑 (opens new window)
上次更新: 2026/03/11, 07:20:31