大型对象/类的超薄版本

时间:2010-01-01 14:44:57

标签: asp.net vb.net inheritance oop class-design

我有一个包含11个公共字段的产品类。

ProductId
ShortTitle
LongTitle
Description
Price
Length
Width
Depth
Material
Img
Colors
Pattern

字段数可能随着更具体产品的属性而增长。描述可能包含大量数据。

我想创建此产品类的精简版,仅包含所需的数据。在类别页面上列出产品时,我只显示12个字段中的4个。当大多数数据未被使用时,检索所有数据似乎是浪费。

我创建了一个ProductListing的父类,其中包含类别页面所需的4个字段

ProductId
ShortTitle
Price
Img

然后创建了一个Product类,它继承自包含所有产品数据的ProductListing。它似乎倒退了,因为“ProductListing”不是一种“产品”,但几个月前我才开始阅读有关继承的知识,所以它对我来说有点新鲜。

有没有更好的方法来获得一个苗条的物体,所以我不会提取我不需要的数据? 我的解决方案是否很好?

3 个答案:

答案 0 :(得分:1)

我个人不赞成继承这些问题,因为它会随着时间的推移而变得混乱。具体来说,我试图避免在我的继承层次结构中有两个具体的类,其中一个继承自另一个,并且两者都可以实例化和使用。

如何创建一个具有所需基本字段的ProductCoreDetail类,并将其聚合在Product类中。您仍然可以通过将公共字段声明为公共字段并将它们代理到嵌套的ProductCoreDetail实例来公开公共字段。

此模型的好处是任何共享的实现代码都可以放在ProductCoreDetail中。此外,您可以选择定义IProductCoreDetailProduct实现的其他接口ProductCoreDetail,以便您可以将任一实例传递给只关心代码信息的方法。我也绝不会将聚合实例公开公开给Product的消费者。

这是一个代码示例:

// interface that allows functional polymorphism
public interface IProductCoreDetail
{
    public int ProductId { get; set; }
    public string ShortTitle { get; set; }
    public decimal Price { get; set; }
    public string Img { get; set; }
}

// class used for lightweight operations
public class ProductCoreDetail : IProductCoreDetail
{
    // these would be implemented here..
    public int ProductId { get; set; }
    public string ShortTitle { get; set; }
    public decimal Price { get; set; }
    public string Img { get; set; }

    // any additional methods needed...
}

public class Product : IProductCoreDetail
{
    private readonly ProductCoreDetail m_CoreDetail;

    public int ProductId    { get { return m_CoreDetail.ProductId; } }
    public string ShortTitle { get { return m_CoreDetail.ShortTitle; } }
    public decimal Price { get { return m_CoreDetail.Price; } }
    public string Img { get { return m_CoreDetail.Img; } }

    // other fields...
    public string LongTitle
    public string Description
    public int Length
    public int Width
    public int Depth
    public int Material
    public int Colors
    public int Pattern
}

答案 1 :(得分:0)

我同意LBushkin的观点,认为继承是错误的做法。继承性表明TypeB TypeA。在你的情况下,这种关系并不完全相同。我曾经创建过类似于搜索结果,列表框项等大型实体的子集的类。但是现在使用C#3.5的匿名类型支持和LINQ投影,我很少再这样做了。

// C#
var results = from p in products
              select new {
                  p.ProductId,
                  p.ShortTitle,
                  p.Price,
                  p.Img };

// VB.NET
Dim results = From p in products _
              Select p.ProductId, p.ShortTitle, p.Price, p.Img

这会创建一个“动态”的未命名类型,它只包含您指定的字段。它是不可变的,所以字段不能通过这个“迷你”类来改变,但它支持相等和比较。

但是当我确实需要创建一个命名类型时,我通常只创建一个与主类没有关系的单独类,而不是对该对象的“完整”版本的延迟加载引用。

答案 2 :(得分:0)

我不会使用单独的类或继承。

对于您的超薄版本,为什么不只检索您需要的数据,并将其他字段留空?您可能有两个查询:一个填充所有字段,另一个只填充细长字段。如果你需要区分这两者,那么如果你的数据库中的一个非细长字段是NOT NULL,这很容易;只需在对象中检查null。