我何时应该使用新类而不是添加新字段(作为状态)?

时间:2014-06-08 16:06:54

标签: java c# oop design-patterns

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

使用class实现:

public class Animal
{

}


public class Dog : Animal
{

}

使用州实施:

public class Animal
{
    public AnimalType AnimalType;
}

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

也许有另一种更好的方法来创建狗对象,我只是试图说明问题。那么哪种方法更好?

2 个答案:

答案 0 :(得分:2)

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

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)

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

答案 1 :(得分:0)

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

在旁注中,使用字段来描述一个类并不一定意味着它是有状态的。如果该字段是不可变的(例如,使用final关键字声明一个原语),那么在没有"状态"的情况下仍然可以避免继承。