【问题标题】:Design Decision: Generate OrderNumber which depends on a database value设计决策:生成取决于数据库值的 OrderNumber
【发布时间】:2011-12-14 20:36:43
【问题描述】:

我正在使用 C# 构建一个订购系统,但在生成订单号时遇到了问题。

我有一个 Order 类,它有一个 OrderNumber 属性。我想将 OrderNumber 属性设为只读,因为更改 OrderNumber 是不安全的。

因为订购步骤非常复杂(4个步骤,有些步骤可能需要10分钟才能完成),所以我需要在每个步骤中保存订单。但是客户不想浪费OrderNumber(订单号是“Year-Month-An_DB_Value”格式),因为OrderNumber的最后一部分表示当月的订单数。所以 OrderNumber 应该只在用户单击“请求验证”按钮时分配。

为了生成OrderNumber并保持Order类干净(不依赖数据库,可以进行单元测试),我想将IOrderNumberGenerator接口作为Order类的构造函数的参数,如下所示:

public class Order {
    public string OrderNumber { get; private set; }

    public Order(IOrderNumberGenerator generator) {
        // ...
    }
}

但是有一个问题:

可以先保存订单,而无需分配 OrderNumber。因此,如果几天后,用户想要将 Order 传递给订单验证者,他将单击“Request Verification”按钮,系统将通过 O/R Mapper(我使用 NHibernate)从数据库中检索 Order 对象,注意这里我们没有办法传递 IOrderNumberGenerator,因为 Order 对象是从 O/R Mapper 中检索出来的,所以 ORM 将通过调用 Order 类的默认构造函数来重构 Order 对象(所以我们有没有办法通过 IOrderNumberGenerator)。下面是演示代码:

Order order = repository.GetOrder(orderId);

// code to generate the order number

xxx.SubmitChanges();

所以我的问题是,如何解决订单号生成问题,同时仍然保持 Order 类干净且易于进行单元测试。

更新: 我现在正在考虑在订单类中创建一个名为 GenerateOrderNumber() 的方法,并传递 IOrderNumberGenerator,如下所示:

public class Order {
   public void GenerateOrderNumber(IOrderNumberGenerator generator) {
       _orderNumber = generate.Generate();
   }
}

我认为它可以解决问题,但是有更好的解决方案吗?

顺便说一句:这是我上一个问题的扩展问题:Design Decision: OrderNumber property in Order class - Public or Private?

谢谢!

【问题讨论】:

  • 是否需要在code中生成Ordner号?在你的具体情况下,我会让数据库处理这个并重新加载订单......
  • 我更喜欢在代码中生成 OrderNumber,除非没有其他解决方案。

标签: c# .net design-patterns modeling


【解决方案1】:

考虑到您想从代码中生成OrderNumber,并考虑您的注释: “因此,只有在用户单击“请求验证”按钮时才应分配 OrderNumber”

我会说使用OrderNumberGenerator 在“请求验证”上单击生成订单。

类似这样的:

public class OrderNumberGenerator : IOrderNumberGenerator  
{
   public OrderNumberGenerator(Order  order) 
   {
      //generate new order number for order parameter
   }
}

也就是说,在请求的那一刻生成一个订单(仅在必要时),以及类型Order<->IOrderNumberGenerator的反向依赖

编辑

顺便说一下,还要考虑在 DB 级别生成 OrderNumber,如果在您的情况下显然可以,就像 Yahia 建议的那样,最可靠的解决方案。

希望这会有所帮助。

【讨论】:

  • OrderNumberGenerator 无法为一个Order.OrderNumber 赋值。 OrderNumber 属性是只读的。请检查我的更新。
猜你喜欢
  • 2015-04-16
  • 1970-01-01
  • 2014-01-01
  • 1970-01-01
  • 2011-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多