Design Decision: OrderNumber property in Order class - Public or Private?

人走茶凉 提交于 2019-12-11 23:56:08

问题


I'm building an ordering system. And here I have an Order class, which has a property named OrderNumber. As you know, OrderNumber can only be assigned once, so I don't want to make it public (so I made it private).

However, the order number is generated according to a sequencial value stored in database. For example, the value in database is 10, now I genearte an order number, the order number will be "Year-Month-10", and the value will increase to 11. The value will be reset every month.

You see, the order number generation has a dependency to database. If I make OrderNumber private, I can only call the generate order number method in the Order class (maybe in the constructor), that's not good and hard to do unit testing. And, I don't want to use any ServiceLocator in the Order class, I think it's bad too.

If I make the order number public, the problems above can be resolved. But the order number might be changed by some coders' mistake now, it's not safe.

So, can I make the OrderNumber property public? And your reasons?

Updates:

Thanks to Yahia for giving me a hint. Now I consider making OrderNumber property readonly, and pass the generator (e.g. IOrderNumberGenerator) to the constructor of the Order class.

But there's another problem: In my senario, the order number is not assigned when the Order object is created. The customer can create and save an order without passing the order to the order verifier. So before the order is passed to the order verifier, the order number is not assigned. OrderNumber is assigned only when the customer click the "Request Order Verification" button, and then the OrderNumber cannot be changed again. And the workflow moves to the next step (Order Verification).

I've created a new question, please look here: Design Decision: Generate OrderNumber which depends on a database value

BTW: I'm using C#

Thanks!


回答1:


I would recommend having a public readonly property OrderNumber (i.e. make set private) based on a private field... this gives you the benefits of both without any negative aspects.

Something you should consider:

Cases like the ones you describe are usually solved by implementing the Factory pattern...

EDIT - regarding the update of the OP:

Make a class OrderNumber and put it as a public property into your Order class. The OrderNumber class has only private constructor and is only created via Factory pattern.

Thus your Order has initially null assigned to the OrderNumber property... this property has a private set method which only allows assignment when the internal field is null... to assign an OrderNumber you have for example a Status property which when changed to Order Verification calls the saved reference to IOrderNumberGenerator (from the constructor) and set the OrderNumber once...




回答2:


Remember, you can set the visibility of the get/set methods of a property:

public class Order
{
    private string orderNumber_;

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

Update

Given your requirement, why not implement a second constructor, that takes an order number generator and an existing order?

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


来源:https://stackoverflow.com/questions/7885931/design-decision-ordernumber-property-in-order-class-public-or-private

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!