我有一个Cart类,它具有很多属性:
public class Cart
{
public Customer Customer { get; set; }
public Products Products { get; set; }
public Payments Payments { get; set; }
public DateTime TimeOfArrival { get; set; }
//...and so on
}
每当我要实例化新的Cart
时,都需要启动这些属性。其中一些是已知的(例如,客户),而另一些则不是(例如,产品和付款)。因此,当我实例化一张新票证时,这就是我要做的:
Cart Cart = new Cart
{
// for know properties:
Customer = currentCustomer,
TimeOfArrival = DateTime.Now,
// for properties that are going to be filled later:
Products = new List<Product>(),
Payments = new List<Payment>(),
// ...and so on
};
此解决方案显然有效,但在实例化时看起来非常庞大,而且在启动器中完成了很多工作,我认为这是一件坏事。
我是正确的做法还是在实例化时启动了许多属性,这不是一个好习惯吗?如果是这样,我该怎么办?
预先感谢
答案 0 :(得分:2)
是的,还有改进的空间。但是要小心,很大程度上取决于要求,基本上,它们在很多情况下都应该领先。这是一个品味问题。有些人比其他人更纯粹。
这取决于您的项目:它有多重要?是辅助项目还是您的核心业务?
是的,还有改进的空间;总会有...现在,明年,每次审查...等等。只是说:没有完美的设计。
您的设置代表了域驱动设计中的典型情况。我稍后会发送链接。
通常,在域驱动设计中,您尝试确定特定的业务功能/概念,并将其包装起来,最好是最具描述性的对象。基本上,您的购物车处在正确的轨道上。
但是,似乎购物车中只有一点点领域知识。
特别是嵌套的复杂类型可能表示您正在跨越某些域边界。
例如:customer
;它位于购物车内。客户可能依次包含一个地址。 ...等等。
很显然,地址与购物车本身无关。
也;付款。我认为它通常不会绑定到购物车,也许更多地绑定到订单。
关于产品;一个简短的描述和指向实际产品的链接就足够了。除了明显的课程价格和数量。
对于购物车,您可能希望考虑仅存储客户ID,如果需要其他数据,则提取客户。
无论如何,这通常是一个主题。最好的建议是:不要尝试包含太多复杂的类型,而只将对特定“事物”有意义的事物放入模型中
答案 1 :(得分:2)
使用构造函数:
public class Cart
{
// shorthand constructor, only 1 setting, else use a normal function style constructor
public Cart (Customer cust) => Customer = cust;
public Customer Customer { get; set; }
public Products Products { get; set; } = new List<Product>();
public Payments Payments { get; set; } = new List<Payment>();
public DateTime TimeOfArrival { get; set; } = DateTime.Now;
//...and so on
}
var cart = new Cart( my_customer_instance ); // all thats needs to be done
如果您只为自己的业务开发产品,则比Lazy<...>
方法更容易。懒惰的岩石,如果您需要创建昂贵的东西,或者根本不需要。空列表不会花费您太多的钱-如果您真的很担心,甚至可以创建带有0个元素的列表(如果您“填充”它们,它们会增加内部缓冲区)。
最大的优点是,您不需要 如果需要new Cart(customer)
,该怎么办-该类自行处理初始化。
答案 2 :(得分:1)
如果您担心预先初始化属性的成本(在这种情况下,这似乎不成问题),则可以使用Lazy<T>
在需要时方便地实例化属性。
例如
private Lazy<List<Product>> products;
constructor() {
products = new Lazy<List<Product>>(()=>new List<Product>());
}
public List<Product> Products => products.Value;
对于类似列表的内容,这是很愚蠢的,但是对于更昂贵的初始化,Lazy<T>
可能会有用。