我以Java为例,但这是一个更一般的面向对象设计相关问题。
以Java中的 IOException
为例。例如,为什么有一个 FileNotFoundException
类?难道不应该是一个IOException
的实例,其中cause是FileNotFound
吗?我会说FileNotFoundException
是IOException
的一个实例。这个结束于何处? FileNotFoundButOnlyCheckedOnceException
,FileNotFoundNoMatterHowHardITriedException
..?
我还在我工作的项目中看到过代码,其中存在FirstLineReader
和LastLineReader
等类。对我来说,这些类实际上代表实例,但我在许多地方都看到了这样的设计。例如,看看Spring Framework源代码,它带有数百个这样的类,每次看到一个类时,我都看到了一个实例,而不是蓝图。类不是用来表示蓝图的吗?
我想问的是,如何在这两个非常简单的选项之间做出决策:
选项1:
enum DogBreed {
Bulldog, Poodle;
}
class Dog {
DogBreed dogBreed;
public Dog(DogBreed dogBreed) {
this.dogBreed = dogBreed;
}
}
选项2:
class Dog {}
class Bulldog extends Dog {
}
class Poodle extends Dog {
}
第一种选项要求调用者配置它正在创建的实例。在第二个选项中,该类已经代表了实例本身(就我所看到的而言,这可能是完全错误的..)。
如果您同意这些类代表实例而不是蓝图,那么您会说创建代表实例的类是一个好习惯,还是像我所说的那样完全错误,我的声明 "代表实例的类" 纯属胡说八道?
if( dogBreed == Bulldog) {} ...
这样的代码,而在第二个选项中,你只需覆盖方法即可。但仍然有一些情况下,选项1是完全适合的。只是对于问题描述中的语义不适用。换句话说:选项1是“有一个”关系,而选项2是“是一个”关系。 - Fildorcatch(IOException ioe)
,你也会捕获到FileNotFoundException。 - Fildor