如何围绕对象状态设计系统,以免在代码和后端重复机制

本文关键字:代码 后端 机制 状态 对象 何围绕 系统 | 更新日期: 2023-09-27 18:31:47

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

我有TransactionDetail对象可以有 9 种状态

Open, 
Complete, 
Cancelled,
No Quote, 
Quoted, 
Instructed, 
Declined, 
Refunded, 
Removed

根据我的经验,当一个人必须处理前端代码中的状态时,他应该尽一切努力避免对象状态有一个 setter。这是因为状态是内在的品质,必须在需要的时候确定——换句话说,地位应该始终由一种方法确定,或者只获得属性而不是设置。

因此,使用

这样的机制检索状态(这只是代码片段,但应该为您提供指示它的工作原理)

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

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

如果对象状态只能从对象本身的数据中确定,则创建计算列可以解决数据库中的此问题。但是像TransactionDetail这样的对象跨越多个表呢 - 没有计算的列机制可以"窥视"其他表。

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

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

如何围绕对象状态设计系统,以免在代码和后端重复机制

如果这是我正在从事的项目,我就不会希望创建一个视图来计算这些数据。

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

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

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

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

对这种设计建议的通常反应是,您必须确保承担保持两件事同步(显式状态与对象状态)的负担 - 答案是确保只有一个逻辑来执行这些更改,并且您的业务逻辑如前所述是无懈可击的。

举个例子:

  • 发票包含一个或多个发票项
  • 发票项具有值。
  • 显示发票时需要发票总值

执行此操作的常用方法是使用SUM()在数据库中"动态"计算发票总计,以填充 Invoice.Total 值。

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

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