我正在建立一个订购系统。在这里,我有一个Order
类,它有一个名为OrderNumber
的属性。如您所知,OrderNumber
只能分配一次,因此我不想将其设为public
(因此我将其设为private
)。
但是,订单号是根据存储在数据库中的顺序值生成的。
例如,数据库中的值为10,现在我生成一个订单号,订单号将为“Year-Month-10
”,值将增加到11.该值将每月重置。
您会看到,订单号生成依赖于数据库。如果我创建OrderNumber
private
,我只能调用Order
类中的生成订单号方法(可能在构造函数中),这对单元测试来说并不好,也很难。而且,我不想在ServiceLocator
课程中使用任何Order
,我认为它也是错误。
如果我订购了订单号public
,则可以解决上述问题。但订单编号可能会因某些编码人员的错误而改变,这是不安全。
那么,我可以公开OrderNumber
属性吗?你的理由?
更新
感谢Yahia给了我一个提示。 现在我考虑将OrderNumber属性设置为readonly,并将生成器(例如IOrderNumberGenerator)传递给Order类的构造函数。
但还有另一个问题: 在我的senario中,创建Order对象时,订单号为不。客户可以创建并保存订单,而无需将订单传递给订单验证程序。 因此,在将订单传递给订单验证程序之前,不会分配订单编号。仅当客户单击“请求订单验证”按钮时才会分配OrderNumber,然后无法再次更改OrderNumber。然后工作流程进入下一步(订单验证)。
我已经创建了一个新问题,请查看此处:Design Decision: Generate OrderNumber which depends on a database value
BTW :我正在使用C#
谢谢!
答案 0 :(得分:3)
我建议根据私人字段设置一个公开的只读属性OrderNumber
(即使set
私有)......这样可以为您提供两者的好处,而不会有任何负面影响。
你应该考虑的事情:
您所描述的案例通常通过实施工厂模式来解决......
编辑 - 关于OP的更新:
创建一个类OrderNumber
并将其作为公共属性放入Order
类。
OrderNumber class
只有私有构造函数,只能通过Factory模式创建。
因此,您的Order
最初null
已分配给OrderNumber
属性...此属性具有private set
方法,该方法仅允许在内部字段为{{时}进行分配1}} ...分配一个null
,例如OrderNumber
属性,当更改为Status
时,调用已保存的对Order Verification
的引用(来自构造函数)和设置IOrderNumberGenerator
一次......
答案 1 :(得分:1)
请记住,您可以设置属性的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