设计决策:Order类中的OrderNumber属性- Public或Private

本文关键字:属性 OrderNumber Public Private 决策 Order | 更新日期: 2023-09-27 18:12:12

我正在构建一个订购系统。这里我有一个Order类,它有一个属性叫OrderNumber。如您所知,OrderNumber只能分配一次,所以我不想将其设置为public(所以我将其设置为private)。

是根据存储在数据库中的顺序值生成的。例如,数据库中的值是10,现在我生成一个订单号,订单号将是"Year-Month-10",该值将增加到11。每个月重置一次。

您可以看到,订单号生成依赖于数据库。如果我将OrderNumber设置为private,我只能在Order类中调用生成订单号方法(可能在构造函数中),这是不好的,并且很难进行单元测试。而且,我不想在Order类中使用任何ServiceLocator,我认为它也不好

如果我做订单号public,以上问题就可以解决了。但是订单号现在可能会因为一些编码员的错误而改变,不安全

那么,我可以使OrderNumber属性公开吗?你的理由呢?

更新:

感谢Yahia给我的提示。现在我考虑使OrderNumber属性只读,并将生成器(例如IOrderNumberGenerator)传递给Order类的构造函数。

但是还有一个问题:在我的场景中,订单号是在创建order对象时分配的,而不是。客户可以创建和保存订单,而无需将订单传递给订单验证者。因此,在将订单传递给订单验证器之前,不会分配订单号。只有当客户点击"请求订单验证"按钮时,才会分配OrderNumber,然后OrderNumber不能再更改。然后工作流移动到下一步(订单验证)。

我创建了一个新问题,请看这里:设计决策:生成OrderNumber,这取决于数据库值

BTW:我正在使用c#

谢谢!

设计决策:Order类中的OrderNumber属性- Public或Private

我建议有一个基于私有字段的公共只读属性OrderNumber(即使set私有)…这给了你两者的好处,而没有任何负面影响。

你应该考虑的事情:

像你描述的这些情况通常通过实现工厂模式来解决…

EDIT -关于OP的更新:

创建一个类OrderNumber,并将其作为公共属性放入Order类。OrderNumber class只有私有构造函数,并且只能通过工厂模式创建。

因此你的Order最初将null分配给OrderNumber属性…这个属性有一个private set方法,只有当内部字段是null时才允许赋值…分配一个OrderNumber,例如,你有一个Status属性,当改变为Order Verification调用保存的引用到IOrderNumberGenerator(从构造函数),并设置OrderNumber一次…

记住,您可以设置属性的get/set方法的可见性:

public class Order
{
    private string orderNumber_;
    public string OrderNumber
    {
        get { return orderNumber_; }
        private set { orderNumber_ = value; }
    }
}

给定您的需求,为什么不实现第二个构造函数,它接受订单号生成器一个现有订单?

public interface IOrderNumberGenerator
{
    string Generate();
}
public class Order
{
    private string orderNumber_;
    // default ctor
    public Order()
    {
    }   // eo ORder
    public Order(IOrderNumberGenerator generator, Order order)
    {
        orderNumber_ = generator.Generate();
        /* copy other fields from the existing Order*/
    }
    public string OrderNumber
    {
        get { return orderNumber_; }
    }
}   // eo class Order