代码之家  ›  专栏  ›  技术社区  ›  THX-1138

数据结构设计是静态类型语言

  •  -1
  • THX-1138  · 技术社区  · 14 年前

    我用C#编写一个(假设的)应用程序-在线商店。

    我有一个产品数据库,每个产品都有以下相关信息:

    • 产品编号(必需)
    • 名称(必需)
    • 价格(必需)
    • 额定值(可选)
    • 销售数量(可选)--这是该产品的总销售额

    我有4页显示过滤后的产品列表。页面显示每个产品的不同信息:

    • 第1页:PN、名称、价格
    • 第2页:PN、名称、价格、评级
    • 3d页面:PN、名称、价格、销售数量
    • 第4页:PN、名称、价格、评级、销售数量

    我的问题是 ,如何设计数据结构以容纳所有页面而不重复?

    暴力方法是为每个页面创建一个类型:

    IList<Product>
    IList<ProductWithRating>
    IList<ProductWithSoldQuantity>
    IList<ProductWithRatingAndSoldQuantity>
    

    后面的3可以从 Product 但由于缺乏多重继承 ProductWithRatingAndSoldQuantity 不能同时从额定值和可焊量产品中派生。

    在动态语言中,我只需要添加任何需要的字段就可以了。

    因此,我可以通过在单独的听写中存储额外的信息(评分、销售量)来模拟动态语言方法,例如:

    {
        IList<Product> Products;
        IDictionary<Product, Rating> ProductRatings;
        IDictionary<Product, SoldQuantity> ProductSoldQuantities;
    }
    // is equivalent to
    IList<ProductWithRatingAndSoldQuantities>
    

    构建一个包含所有内容并传递部分初始化对象的产品结构是 我正在寻找解决办法。

    有什么建议吗?

    4 回复  |  直到 14 年前
        1
  •  1
  •   RichardW1001    14 年前

    抱歉,没有足够的字符回复评论。

    你应该有一个域对象,产品。它将有不可为空的名称、产品编号和价格,因为您不能有没有这些东西的产品。

    评级应该为空,因为可能有一个产品没有评级。不管一个产品是否有评级,它始终是一个产品。我将保留QuantitySelled,因为我实际上不会将其存储为产品的属性,我将拥有订单和订单行集合,并根据这些集合计算售出的数量(标准化)。但是,在没有其他集合的情况下,可以将其作为字段存储在产品上。如果我要这样做,它将是一个不可为空的整数属性,默认值为零。

    你只需要一个集合来过滤,这个集合可能是IEnumerable或IQueryable的实现,或者两者兼而有之,很可能你会选择实体框架之类的东西,并且实际上有一个对象集,但是我会尽量保持我的设计与我正在使用的存储方法无关,并针对这些接口工作。

    然后,您可以查询单个集合,以确定域模型中产品的哪些属性为空。语法可能不完美,但没有什么智能感知不起作用,我99%的时间都是VB人。

    var productsWithNoSales = Context.Products.Where(p=> p.QuantitySold == 0);
    var productsWithNoRating = Context.Products.Where(p=> p.Rating == nothing);
    var productsWithNoSalesOrRating = Context.Products.Where(p=> p.QuantitySold == 0).Where(p=> p.Rating == nothing);
    

    对于你所追求的领域来说,这几乎是最干净的领域模型。

    如果你的产品有特殊的衍生产品,它们要么有额外的属性,要么有不同的行为,那么继承就是。例如,我自己的系统有一个基本产品类,以及一个EbayProduct和AmazonProduct实体,它们都继承自Product,并且只包含与使用这些站点相关联的额外逻辑和属性。我的产品类有大约20个属性——大部分是可以为空的,因为当我们列出产品时,我们不一定拥有所有可用的信息。在这20个页面中,我在任何一个页面上显示的最多的是15个。我可能会做一些与您所做的类似的事情,即使用所述的确切方法筛选出尚未准备好列出的产品,即筛选缺少字段的产品集合。

        2
  •  1
  •   David    14 年前

    为什么不能 Rating SoldQuantity 只是可以作废?或者总是在场但不总是展示?

        3
  •  1
  •   robert vano    14 年前

    你能将评级和销售量存储为属性,然后存储指示它们是否存在的布尔值吗?我认为你应该在创作的时候使用继承。

        4
  •  0
  •   RichardW1001    14 年前

    你也许可以指定你在用什么?你的“页面”是从什么开始的?你的数据存储方法是什么?

    听起来你把数据的显示和存储混在一起了?没有义务仅仅因为它存在而显示数据。

    您的对象域几乎肯定应该只有产品。数据存储将被设置为属性可以为空,并检查是否为空以获取数据。

    如果你用的是像Linq这样的东西,你可以简单地做

    var productsWithoutRating = Context.Products.Where(p => p.Rating == nothing);
    

    词典的构思、继承和编撰都显得有点枯燥。存储一个单独的布尔值告诉你一个属性是否存在是杂乱的,这将是一个维护的噩梦——只需检查它是否存在。