对象模型,正确或最直观的方式

时间:2013-02-20 22:53:41

标签: c# object inheritance

我正在试图找出设置此模型的最佳方法。我几乎是这样做的,但我正在考虑采取另一种方式。这是一次学习经历,所以浪费时间并不重要。

namespace FirstWay
 {

public class CrateOfBags
{
    public string crateId { get; set; }
    public string originCountry { get; set; }
    public List<BagOfApples> bagList { get; set; }
}

public class BagOfApples
{
    public double weight { get; set; }
    public string bagId { get; set; }
    public List<apple> appleList { get; set; }
}

public class apple
{
    public string appleId { get; set; }
    public string color { get; set; }
    public Boolean rotten { get; set; }
}
}

//或者这个

 namespace SecondWay
   {
public class CrateOfBags
{
    public string crateId { get; set; }
    public string originCountry { get; set; } 
}

public class BagOfApples : CrateOfBags
{
    public string bagId { get; set; }
    public double weight { get; set; }
}

public class apple : BagOfApples
{
    public string appleId {get;set;}
    public string color { get; set; }
}

}

可能的问题

Apple问题:     交付了多少烂苹果?  哪个袋子和/或哪个板条箱腐烂的苹果来自哪里?  第一种方式:可以循环每个箱子,然后包,然后苹果和计数。  第二种方式:可以通过苹果循环并将父属性添加到HashSet(一种方法来防止重复)

Crate Questions。查找每个国家/地区的箱子数量? 第一种方式:只通过板条箱并保留计数列表,数组等等。 第二种方式:必须遍历所有苹果,只关心板条箱。

我遇到的一个问题是我对苹果作为自己的实体知之甚少。我只知道来自箱子的foreach循环来自哪个箱子

但是,如果我想问一个问题,例如“特定批次中有多少青苹果(按ID)?”我也有问题取决于方式。

我觉得苹果是一个袋子的孩子似乎很尴尬,就像狗是动物的孩子一样。然而,我喜欢能够自由移动操纵苹果的想法,例如通过更改父属性bagid来切换它们所处的袋子。我不是在寻找特定问题的解决方案,只要其中一个更好(更灵活,更有效,更直观)然后另一个,或者如果我完全缺少某些东西,比如使用其他技术。非常感谢。

P.S。这不是真正的模型,而是一种相当不错的表现形式。

2 个答案:

答案 0 :(得分:5)

从数据建模的角度来看,第二种方法显然是错误的:苹果不是 BagOfApples。继承应该创造可替代性:你能总是把苹果放在预期的BagOfApples吗?我不这么认为。这是Liskov替换原则(并且它被违反)。

在数据库术语中,第二个模型是非规范化的。它可以通过将所有3个表连接在一起从第一个模型创建,从而创建冗余数据。这是一种反模式,因为当你改变某些东西时,你必须在不止一个地方改变它(如果你忘记它是一个无声的数据损坏)。

答案 1 :(得分:3)

  

我说苹果是一个包的孩子似乎很尴尬

上帝,因为那是错的。苹果不是一个包,因此不应继承它。

你的第一个模型看起来很好。我考虑的唯一建议是对Bag进行泛化,以便可以重复使用:

public class CrateOfBags<T>
{
    public string crateId { get; set; }
    public string originCountry { get; set; }
    public List<Bag<T> bagList { get; set; }
}

public class Bag<T>
{
    public double weight { get; set; }
    public string bagId { get; set; }
    public List<T> ItemList { get; set; }
}

public class apple
{
    public string appleId { get; set; }
    public string color { get; set; }
    public Boolean rotten { get; set; }
}
  

我对苹果作为自己的实体知之甚少。我只知道它来自箱子的foreach循环来自哪个箱子。

这是通过使用反向引用来解决的,这意味着苹果引用了它的包,它引用了它的创建。然而,这并不总是有意义的,特别是如果有多个容器类型可能包含Apple或者Apple不应该知道它的包。