【问题标题】:When should I use new class instead of adding new field (as state)? [closed]我什么时候应该使用新类而不是添加新字段(作为状态)? [关闭]
【发布时间】:2014-06-08 16:06:54
【问题描述】:

我看了一些设计模式书,发现了一个有趣的点:他们创建了很多类。有时我似乎可以添加一个字段而不是创建类。例如

使用类实现:

public class Animal
{

}


public class Dog : Animal
{

}

使用状态实现:

public class Animal
{
    public AnimalType AnimalType;
}

var dog = new Animal();
dog.AnimalType = AnimalType.Dog;

也许还有另一种更好的方法来创建狗对象,我只是想说明一下。那么哪种方法更好呢?

【问题讨论】:

  • 这似乎更适合Programmers SE
  • 您要我们回答的是整个组合与继承的争论。这是非常广泛的,你最好阅读一本关于 OO 设计的书(或一些深入的文章)。在这里我会使用继承,因为狗不能突然变成猫,所以使用组合没有任何好处(只会让它难以使用)。
  • @user3580294 我怎样才能把问题移到那里?
  • 这正是为什么我觉得“偏爱组合胜过继承”这种“带有歧视性的”表达如此令人反感的原因。
  • 认为解决这个问题的方法是将问题标记为 mod 注意并声明您希望将其移至 Programmers SE,但我不是 100%确定...

标签: java c# oop design-patterns


【解决方案1】:

您创建不同的类以具有不同的行为,例如:

public abstract class Animal {
    public abstract void makeASound();
}

public class Dog : Animal {
    public void makeASound() {
        System.out.println("bark, bark!");
    }
}

public class Cat : Animal {
    public void makeASound() {
        System.out.println("mrau, mrau");
    }
}

它们都继承了 Animal 类,因此您可以要求动物对它做一些事情,但您并不关心您获得了哪种实现。

使用类型字段,您必须在条件语句中执行不同的行为

if(animalType == AnimalType.Dog){
    System.out.println("bark, bark!");
} else if(animalType == AnimalType.Cat){
    System.out.println("mrau, mrau!");
}

这将变得非常难以维护。

为什么要有AnimalDogCat等动物,而不是DogCat等其他动物?

继承允许你请求一个可以做某事的类,但你并不关心这个类是如何做到的。您可能想要加密一些数据,因此您编写了一个方法,该方法将EncryptionAlgorithm 类作为参数并使用它。但是应用程序的用户可以选择不同的算法,因此您可以编写不同的类,例如RijndaelDESSerpentTwofish,它们都继承了EncryptionAlgorithm 类,并且它们都可以作为参数传递给采用EncryptionAlgorithm 的方法。所以你不必像

那样创建4个方法
encryptUsingRijndael(Rijndael algorithm)
encryptUsingTwofish(Twofish algorithm)
encryptUsingDES(DES algorithm)
encryptUsingSerpent(Serpent algorithm)

它们都做同样的事情,但针对不同的班级。你只写一个方法的

encrypt(EncryptionAlgorithm algorithm)

您可以传递应用程序用户想要使用的任何算法。

【讨论】:

    【解决方案2】:

    创建子类允许您定义方法的自定义实现。如果您在单个类中使用一个或多个“属性”字段,它会迫使您处理单个位置中每个可能的属性值排列的逻辑。通过使用子类,您可以对功能进行逻辑分组,而不仅仅是属性的另一种组合。

    附带说明,使用字段来描述一个类并不一定意味着它是有状态的。如果该字段是不可变的(例如,使用 final 关键字声明原语),您仍然会避免没有“状态”的继承。

    【讨论】:

      猜你喜欢
      • 2014-07-22
      • 2011-09-11
      • 1970-01-01
      • 1970-01-01
      • 2010-10-13
      • 2010-09-10
      • 1970-01-01
      • 2012-12-23
      • 2021-07-13
      相关资源
      最近更新 更多