空派生类与类型属性相对应

时间:2016-09-20 19:23:36

标签: architecture uml

我无法确定下面这两个例子的优缺点。理想情况下,我想知道哪个重量最高的设计:

示例1(类型属性):

public abstract class Animal : /* all relevant interfaces*/
{
    /*
    All necessary implementations
    */
}

Public class Dog : Animal
{
    Public string Name {get; set;}
    Public Breed Type {get; set;}

    /* 
    All necessary implementations
    */
}

Public Type Breed
{
    Bulldog,
    Chihuahua,
    Labrador,
    /*
    So on……
    This can grow without limitation, 
    you dno't know how much it will grow into, or 
    what breed you will have tomorrow e.g BulldogChihuahuaCross, 
    or BulldogLabradorCross.
    */
}

示例2(空派生类):

public abstract class Animal : /* all relevant interfaces*/
{
    /*
    All necessary implementations
    */
}

Public class Dog : Animal
{
    Public string Name {get; set;}

    /* 
    All necessary implementations
    */
}

Public class Bulldog : Dog
{
   /* Empty Class */
}

Public class Chihuahua: Dog
{
   /* Empty Class */
}

Public class Labrador: Dog
{
   /* Empty Class */
}

修改

在示例1中,创建了Dog的实例,并将其类型指定为属性,在示例2中,创建了该特定类型的实例。

如果有1000种类型的品种,运行查询的成本等,我正在寻找一些深入的论证,可扩展性,可维护性,CPU成本。

3 个答案:

答案 0 :(得分:2)

频谱有两个极端。一方面是一组仅仅是信息性的东西,并作为文本,数字或对枚举实例的引用进行操作。例如,狗沙龙应用程序可能会记录您的宠物的名称,颜色和品种,仅作为识别用途的文本。另一方面,需要具有不同属性,操作或方法的事物集合。例如,视频游戏可能希望在每个品种的狗吠时发出不同的声音。

作为设计师必须做出的决定是如何准确地反映“话语领域”与何时采用特定应用的捷径。在话语领域,每个品种都具有使其独特的特征,但出于狗沙龙应用的目的,您只是不在乎。在这种情况下,您可以设计细节,并希望将来不再需要它。

问题出在那个频谱的中间,有人做出了错误的决定。我曾在大型企业系统上工作,有人将继承层次结构压缩为显式编码为一个或多个数据库列中的值的类型。这是可怕的,因为知道哪些其他列对每种编码类型都有效成为程序员的问题。系统在所有地方都有切换语句,以实现随时间演变成非常复杂的业务规则。系统有很多错误。

出于这个原因,在频谱的中间,事情并没有那么明确,我会错误地站在很多班级的一边。原因是准确地反映域使得更容易判断是否满足需求,并且可以使代码更直观地维护(假设它是DDD)。反映域名的关键是准确地表示事物的集合。例如,“Fido”是Dog set和Animal superset的成员; “西尔维斯特”是Cat集和动物超集的成员。这对于人们来说很容易理解,并且每个类可以具有从外部隐藏的不同实现。一旦你开始解释显式编码为字符串,整数或枚举文字引用的类型,你就开始需要遍布各地的switch语句,并且你有一个难以维护,难以理解的混乱。许多OO语言可以为您节省所有这些,但您必须创建一个包含完整类型列表的工厂。运行时开销可以忽略不计(特别是如果您将工厂实现为在常量时间运行),并且类型可以映射到关系数据库中的值,以便您可以查询和报告它们。此外,正如您所指出的,您可以利用泛型。

如果你知道你的课程总是空的,就像狗沙龙应用程序一样,不要打扰课程。如果您知道它们将具有不同的属性,操作和方法,或者您不确定,请使用类。

答案 1 :(得分:1)

第一种方法可以让你确定狗是哪个品种,但第二种方法可以让你为子类做出特定的实现。

如果您需要对象为每个不同的狗品种提供不同的方法或属性,请使用派生类,否则只需拥有type属性和单个类就更简单了。

答案 2 :(得分:1)

好的,所以这是我的2美分:如果你正在寻找一个快速访问任何东西,你会把它放在一个关联数组。这两个实现都提供了一个要使用的哈希码(作为对象地址),这使得它们可以以相同的速度访问。仅当您打算添加功能时,子类才有意义(基本上)。从分类器中获取类型与从枚举中获取类型没有什么不同。如果您需要聪明的查询,请创建一个聪明的关联数组。