C# 如何围绕对象的状态设计系统,以避免代码和后端中的机制重复?

C# 如何围绕对象的状态设计系统,以避免代码和后端中的机制重复?,c#,sql,oracle,architecture,state,C#,Sql,Oracle,Architecture,State,我使用的ATM系统是C#和oracle,但我遇到的问题是系统不可知的(可能发生在使用java和mysql或任何其他前端和后端组合的系统上): 我有一个可以有9种状态的TransactionDetail对象 Open, Complete, Cancelled, No Quote, Quoted, Instructed, Declined, Refunded, Removed 根据我的经验,当一个人必须在前端代码中处理状态时,他应该尽一切努力避免对象状态有一个setter。这是因为状

我使用的ATM系统是C#和oracle,但我遇到的问题是系统不可知的(可能发生在使用java和mysql或任何其他前端和后端组合的系统上):

我有一个可以有9种状态的
TransactionDetail
对象

Open, 
Complete, 
Cancelled,
No Quote, 
Quoted, 
Instructed, 
Declined, 
Refunded, 
Removed
根据我的经验,当一个人必须在前端代码中处理状态时,他应该尽一切努力避免对象状态有一个setter。这是因为状态是固有的质量,必须在需要时确定——换句话说,状态应该始终由方法或get only属性确定,而不是设置

因此,使用类似这样的机制来检索状态(这只是一段代码,但应该可以告诉您它是如何工作的)

MI在SQL视图中请求这些事务状态,该视图还将包含与事务相关的所有数据

若只能从对象本身的数据确定对象状态,那个么在数据库中创建计算列可以解决这个问题。但是像
TransactionDetail
这样跨越多个表的对象呢?没有允许“窥视”其他表的计算列机制

我能想到的唯一解决方案是添加确定状态的SQL函数,然后创建一个包含函数+表中数据的SQL视图。我不喜欢这种方法,因为它需要在代码和数据库中复制逻辑


如何围绕待确定对象的状态设计系统需要来自多个表的信息,而不需要在代码和后端复制机制?

如果这是我正在进行的项目,我不会创建一个视图来计算这些数据

我将查看我的应用程序业务逻辑

虽然完全规范化的数据库对DBA来说非常有意义,但在某些情况下,应用程序性能和可伸缩性可以从稍微的去规范化中受益匪浅

如果您有可靠的业务逻辑框架(即定义良好的业务对象、良好的封装、可靠的单元测试),那么我个人希望将其添加到业务对象中

然后,这允许您在代码中定义自己的状态行为,并更新显式状态。例如,如果对业务对象进行了更改,并将其放入不同的
TransactionStatus
,则可以在业务对象上显式更改该状态,并将整个更改保留到数据库中

对于这种设计建议,通常的反应是,您必须确保您有责任保持这两件事情的同步(明确的状态与对象的状态)——答案是确保只有一条逻辑来执行这些更改,并且您的业务逻辑如前所述是防水的

例如:

  • 发票包含一个或多个InvoiceItem
  • InvoiceItem有一个值
  • 显示发票时,需要发票总值
通常的方法是使用
SUM()
计算数据库中“动态”的发票总额,以填充发票。总值

但是,如果我的业务逻辑定义良好-可能我在代码中将InvoiceItem添加到Invoice对象中,
add
逻辑也从InvoiceItem中获取值并将其添加到
Invoice.Total
value-那么当我提交更改时,我也可以提交该Invoice.Total值

当我想显示总数时,我只有一个值,而不必在数据库中进行聚合

public TransactionStatus TransactionStatus()
{
    if (db.DeclinedTransactions.Any(o => o.TransactionId == this.TransactionId))
        return TransactionStatus.Declined;
}