什么时候我应该使用新的类而不是添加新的字段(作为状态)

本文关键字:字段 添加 状态 我应该 什么时候 | 更新日期: 2023-09-27 18:07:20

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

使用class:

实现
public class Animal
{
}

public class Dog : Animal
{
}

使用state实现:

public class Animal
{
    public AnimalType AnimalType;
}
var dog = new Animal();
dog.AnimalType = AnimalType.Dog;

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

什么时候我应该使用新的类而不是添加新的字段(作为状态)

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

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!");
}

这将变得非常难以维护。

为什么有Animal, Dog, Cat和其他动物,而不是只有Dog, Cat,其他动物?

继承允许你请求一个能做某事的类,但你不关心这个类到底是怎么做的。你可能想加密一些数据,所以你写了一个方法,作为一个参数接受EncryptionAlgorithm类并使用它。但是应用程序的用户可以选择不同的算法,所以您编写不同的类,如Rijndael, DES, Serpent, Twofish,它们都继承EncryptionAlgorithm类,并且它们都可以作为参数传递给接受EncryptionAlgorithm的方法。所以你不需要创建像

这样的4个方法
encryptUsingRijndael(Rijndael algorithm)
encryptUsingTwofish(Twofish algorithm)
encryptUsingDES(DES algorithm)
encryptUsingSerpent(Serpent algorithm)

都做同样的事情,但对不同的类。你只写了一个方法

encrypt(EncryptionAlgorithm algorithm)

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

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

顺便说一句,使用字段来描述类并不一定意味着它是有状态的。如果字段是不可变的(例如用final关键字声明一个原语),你仍然可以避免没有"状态"的继承。