DDD:订单管理 之 如何组织代码
发布时间:2020-05-22 19:47:09 所属栏目:程序设计 来源:互联网
导读:背景 系统开发最难的是职责的合理分配,或者叫:“如何合理的组织代码”,今天说一个关于这方面问题的示例,希望大家多批评。 示例背景 参考数据字典 需求 OrderCode必须唯一。 Total = Sum(Subtotal)。 订单有三种状态:【未提交】、【待审核】和【已审核
背景系统开发最难的是职责的合理分配,或者叫:“如何合理的组织代码”,今天说一个关于这方面问题的示例,希望大家多批评。 示例背景参考数据字典需求
示例实现项目结构
项目整体采用简单的CQRS架构,Command端采用DDD组织,Query直接从数据库返回dynamic类型。Event可以用来处理跨聚合通信,也可以用来处理长事务或离线事务。 重点介绍的领域层采用状态模式处理状态迁移。 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace Happy.Example.Domain.TestOrders
8 {
9 public interface ITestOrderState
10 {
11 void AddTestOrderDetail(TestOrderDetail testOrderDetail);
12
13 void UpdateTestOrderDetail(Guid testOrderDetailId,decimal subtotal);
14
15 void RemoveTestOrderDetail(Guid testOrderDetailId);
16
17 void Commit();
18
19 void Verify();
20
21 string Status { get; }
22
23 TestOrder TestOrder { set; }
24 }
25 }
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace Happy.Example.Domain.TestOrders
8 {
9 public partial class TestOrder
10 {
11 private abstract class TestOrderState : ITestOrderState
12 {
13 public virtual void AddTestOrderDetail(TestOrderDetail testOrderDetail)
14 {
15 this.ThrowInvalidOperationException();
16 }
17
18 public virtual void UpdateTestOrderDetail(Guid testOrderDetailId,decimal subtotal)
19 {
20 this.ThrowInvalidOperationException();
21 }
22
23 public virtual void RemoveTestOrderDetail(Guid testOrderDetailId)
24 {
25 this.ThrowInvalidOperationException();
26 }
27
28 public virtual void Commit()
29 {
30 this.ThrowInvalidOperationException();
31 }
32
33 public virtual void Verify()
34 {
35 this.ThrowInvalidOperationException();
36 }
37
38 public abstract string Status { get; }
39
40 public TestOrder TestOrder { protected get; set; }
41
42 private void ThrowInvalidOperationException()
43 {
44 throw new InvalidOperationException(string.Format("处于【{0}】的订单不能执行此操作!",this.Status));
45 }
46 }
47 }
48 }
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace Happy.Example.Domain.TestOrders
8 {
9 public partial class TestOrder
10 {
11 private sealed class UnCommitted : TestOrderState
12 {
13 internal static readonly string UnCommittedStatus = "未提交";
14
15 public override void AddTestOrderDetail(TestOrderDetail testOrderDetail)
16 {
17 this.TestOrder.DoAddTestOrderDetail(testOrderDetail);
18 }
19
20 public override void UpdateTestOrderDetail(Guid testOrderDetailId,decimal subtotal)
21 {
22 this.TestOrder.DoUpdateTestOrderDetail(testOrderDetailId,subtotal);
23 }
24
25 public override void RemoveTestOrderDetail(Guid testOrderDetailId)
26 {
27 this.TestOrder.DoRemoveTestOrderDetail(testOrderDetailId);
28 }
29
30 public override void Commit()
31 {
32 this.TestOrder.DoCommit();
33 }
34
35 public override string Status
36 {
37 get { return UnCommittedStatus; }
38 }
39 }
40 }
41 }
采用封装集合手法处理Total的同步问题。 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 using Happy.Domain;
8 using Happy.Domain.Tree;
9 using Happy.Infrastructure.ExtentionMethods;
10 using Happy.Example.Events.TestOrders;
11
12 namespace Happy.Example.Domain.TestOrders
13 {
14 public partial class TestOrder : AggregateRoot<Guid>
15 {
16 private ITestOrderState _orderState;
17
18 protected TestOrder() { }
19
20 public TestOrder(string orderCode,string customer)
21 {
22 orderCode.MustNotNullAndNotWhiteSpace("orderCode");
23 customer.MustNotNullAndNotWhiteSpace("customer");
24
25 this.Id = Guid.NewGuid();
26 this.OrderCode = orderCode;
27 this.Customer = customer;
28 this.OrderState = TestOrderStateFactory.CreateUnCommittedTestOrderState(this);
29 this.TestOrderDetails = new List<TestOrderDetail>();
30 }
31
32 public virtual System.String OrderCode { get; protected set; }
33 public virtual System.String Customer { get; protected set; }
34 public virtual System.Decimal Total { get; protected set; }
35 public virtual System.String Status { get; protected set; }
36 public virtual ICollection<TestOrderDetail> TestOrderDetails { get; protected set; }
37
38 private ITestOrderState OrderState
39 {
40 get
41 {
42 if (_orderState == null)
43 {
44 _orderState = TestOrderStateFactory.Create(this,this.Status);
45 }
46
47 return _orderState;
48 }
49 set
50 {
51 _orderState = value;
52 this.Status = value.Status;
53 }
54 }
55
56 public void AddTestOrderDetail(TestOrderDetail testOrderDetail)
57 {
58 this.OrderState.AddTestOrderDetail(testOrderDetail);
59 }
60
61 public void UpdateTestOrderDetail(Guid testOrderDetailId,decimal subtotal)
62 {
63 this.OrderState.UpdateTestOrderDetail(testOrderDetailId,subtotal);
64 }
65
66 public void RemoveTestOrderDetail(Guid testOrderDetailId)
67 {
68 this.OrderState.RemoveTestOrderDetail(testOrderDetailId);
69 }
70
71 public void Commit()
72 {
73 this.OrderState.Commit();
74 }
75
76 public void Verify()
77 {
78 this.OrderState.Verify();
79 }
80
81 private void DoAddTestOrderDetail(TestOrderDetail testOrderDetail)
82 {
83 this.TestOrderDetails.Add(testOrderDetail);
84
85 this.Total += testOrderDetail.Subtotal;
86 }
87
88 private void DoUpdateTestOrderDetail(Guid testOrderDetailId,decimal subtotal)
89 {
90 var testOrderDetail = this.TestOrderDetails.First(x => x.Id == testOrderDetailId);
91
92 this.Total -= testOrderDetail.Subtotal;
93 testOrderDetail.Subtotal = subtotal;
94 this.Total += testOrderDetail.Subtotal;
95 }
96
97 private void DoRemoveTestOrderDetail(Guid testOrderDetailId)
98 {
99 var testOrderDetail = this.TestOrderDetails.First(x => x.Id == testOrderDetailId);
100
101 this.TestOrderDetails.Remove(testOrderDetail);
102 this.Total -= testOrderDetail.Subtotal;
103 }
104
105 private void DoCommit()
106 {
107 this.OrderState = TestOrderStateFactory.CreatePendingVerificationTestOrderState(this);
108 }
109
110 private void DoVerify()
111 {
112 this.OrderState = TestOrderStateFactory.CreateVerifiedTestOrderState(this);
113
114 this.PublishEvent(new TestOrderVerified());
115 }
116 }
117 }
效果图背景写这个简单的Demo过程,遇到了很多小的决策,这篇文章就看做一个开头吧,后边重点介绍每个决策点,在一篇文章中真的很难说完,喜欢看代码的朋友,先去https://happy.codeplex.com/下载。 (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
