问问自己它们是什么以及我们为什么拥有它们。他们都在那里创建对象的实例。
ElementarySchool school = new ElementarySchool();
ElementarySchool school = SchoolFactory.Construct(); // new ElementarySchool() inside
到目前为止没有区别。现在假设我们有各种学校类型,我们想从使用 ElementarySchool 切换到 HighSchool(它派生自 ElementarySchool 或实现与 ElementarySchool 相同的 ISchool 接口)。代码更改将是:
HighSchool school = new HighSchool();
HighSchool school = SchoolFactory.Construct(); // new HighSchool() inside
如果是接口,我们将拥有:
ISchool school = new HighSchool();
ISchool school = SchoolFactory.Construct(); // new HighSchool() inside
现在,如果您在多个地方都有此代码,您会看到使用工厂方法可能非常便宜,因为一旦您更改了工厂方法,您就完成了(如果我们使用带有接口的第二个示例)。
这是主要的区别和优势。当您开始处理复杂的类层次结构并希望从这样的层次结构中动态创建类的实例时,您会得到以下代码。然后,工厂方法可能会接受一个参数,该参数告诉该方法要实例化哪个具体实例。假设您有一个 MyStudent 类,您需要实例化相应的 ISchool 对象,以便您的学生成为该学校的成员。
ISchool school = SchoolFactory.ConstructForStudent(myStudent);
现在,您的应用程序中有一个位置包含确定要为不同的 IStudent 对象实例化的 ISchool 对象的业务逻辑。
所以 - 对于简单的类(值对象等),构造函数就可以了(你不想过度设计你的应用程序),但对于复杂的类层次结构,工厂方法是一种首选方式。
这样,您就可以遵循四本书“程序到接口,而不是实现”中的第一个设计原则。