什么时候我应该使用新的类而不是添加新的字段(作为状态)
本文关键字:字段 添加 状态 我应该 什么时候 | 更新日期: 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
的方法。所以你不需要创建像
encryptUsingRijndael(Rijndael algorithm)
encryptUsingTwofish(Twofish algorithm)
encryptUsingDES(DES algorithm)
encryptUsingSerpent(Serpent algorithm)
都做同样的事情,但对不同的类。你只写了一个方法
encrypt(EncryptionAlgorithm algorithm)
你可以传递应用程序的用户想要使用的任何算法
创建子类允许您定义方法的自定义实现。如果在单个类中使用一个或多个"属性"字段,就会迫使您处理单个位置中属性值的每种可能排列的逻辑。通过使用子类,您可以对功能进行逻辑分组,而不仅仅是属性的另一个组合。
顺便说一句,使用字段来描述类并不一定意味着它是有状态的。如果字段是不可变的(例如用final
关键字声明一个原语),你仍然可以避免没有"状态"的继承。