问问自己它们是什么以及我们为什么拥有它们。他们都在那里创建对象的实例。
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 对象。
所以 - 对于简单的类(值对象等),构造函数就可以了(您不想过度设计您的应用程序),但对于复杂的类层次结构,工厂方法是首选方法。
这样你就遵循gang of four book“程序到接口,而不是实现”的第一个设计原则。