在实例化时启动许多属性是一种好习惯吗?

时间:2019-05-05 20:42:59

标签: c# oop constructor

我有一个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
                    };

此解决方案显然有效,但在实例化时看起来非常庞大,而且在启动器中完成了很多工作,我认为这是一件坏事。

我是正确的做法还是在实例化时启动了许多属性,这不是一个好习惯吗?如果是这样,我该怎么办?

预先感谢

3 个答案:

答案 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>可能会有用。