我正在开发一个删除其他系统信息的系统。例如,有一个客户数据库,如果最近的订单是六年或更长时间,则可以删除客户。
我可以想到两种方法:
我无法确定哪个选项更好。
答案 0 :(得分:2)
我会对你的第一种方法提出异议。我不确定所有单独的业务类是否会以某种方式共享Delete
方法的相同接口。删除客户所需的参数可能与删除订单所需的参数不同。迫使他们共享相同的界面似乎很奇怪。这样做可能会在将来不必要地限制代码的灵活性。此外,删除客户的业务逻辑涉及盲目地循环遍历其他对象,没有特定的顺序,并在所有对象上调用Delete
方法,这似乎很奇怪。我认为你想要更多地控制它们被删除的顺序以及当其中一个删除方法失败时如何处理它。
我建议先从更高层次考虑它。您实际需要哪些商业方法?根据您描述的方案,我可以看到两种业务方法:
由于这两种方法都与客户相关,因此将它们组合成一个单独的客户业务类是有意义的。例如:
Public Interface ICustomerBusiness
Function GetStaleCustomers(timeSinceLastOrder As TimeSpan) As IList(Of CustomerDto)
Sub DeleteCustomer(customerId As Integer)
End Interface
一旦你封装了这样的业务逻辑,现在无论数据访问层是如何实现的都无关紧要。客户端调用这些简单的业务层方法,而不必关心逻辑如何在幕后工作。将业务逻辑封装在自己的层中,您可以自由地以不同方式重写它,而无需重写任何客户端代码。
那么业务类中的逻辑会是什么样子?它可以是对数据访问方法的单个调用,通过一个大型SQL命令完成所有工作,也可以进行多次调用以分别执行每个步骤。这真的取决于你。显然前者会更有效率,但后者会更灵活。这一切都取决于您的需求。以下是每种情况的简单示例:
Public Sub DeleteCustomer(id As Integer)
_customerDataAccess.DeleteCustomerAndOrders(id)
End Sub
' or...
Public Sub DeleteCustomer(id As Integer)
For Each i As OrderDto In _orderBusiness.GetOrdersByCustomer(id)
_orderBusiness.DeleteOrder(i.Id)
Next
_customerDataAccess.DeleteCustomer(id)
End Sub
由于多种原因,第二种选择会更灵活。例如:
答案 1 :(得分:1)
两者似乎都有其优点和缺点,我个人会走第二条路线,特别是如果你处理的是非常大量的记录,而不是连续点击数据库以删除记录。
答案 2 :(得分:1)
第三种方法是使用具有多个代理的消息传递系统。这种方法非常适用于非常复杂的场景。
这是一个场景:
用户运行命令以删除实体(订单,客户等)。 用户正在使用的工具在工作队列中创建一条消息 表示用户的意图(例如“删除客户123”)
邮件由一个或多个代理处理。每个代理都是特定的 对一个较大的操作的一部分,并只听取相关的 消息。所有代理都在单个分布式事务中工作。 这意味着每个代理都有一个非常狭窄的特定范围,但任何代理 可以拒绝整体操作。如果代理需要执行其他操作 子任务,它可以为这些操作排队其他消息(例如 删除属于客户的每个订单。)
这种方法可以很好地扩展,特别是对于非常复杂的交互。它避免任何一个系统必须知道所有其他系统。每个代理都知道要处理的消息,并处理与该消息相关的非常具体的任务。
最初设置更多,但是非常易于扩展(您可以添加新代理,消息等,而不会影响现有代理,消息等)。
如果您决定使用此方法,请查看MassTransit以获取框架(还有其他框架)。如果你在.NET工作,这是一个非常好的系统,功能强大,但平易近人。它Sagas特别适合协调多个代理之间的复杂交互。