Is Factory method more suitable for frameworks and Abstract facory for Library?
Abstract Factory和Factory方法模式都是创建设计模式,它解决了不同场景下的对象创建问题。
根据GOF工厂方法模式
Define an interface for creating an object, but let the subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclass.
我的理解 :
客户的动机是获取基础工厂类中存在的方法得到执行,这取决于现在不知道具体类的对象(在这种情况下,无论是在向客户提供软件期间,它都将被定义,或者它将是客户自己编写的具体实现,很可能是在Framework的情况下)。未知(或可能更改)的产品提供了一个抽象类型:IProduct,并设置一个合同,以后在任何产品实现中都必须实现此接口。
IProduct接口
1 2 3 4 | package com.companyx; public interface IProduct { public void serve(); } |
带有'a method'的工厂类需要执行
1 2 3 4 5 6 7 8 9 10 11 12 13 | package com.companyx; public abstract class Factory { public abstract IProduct createProduct(); private void performCriticalJob(){ IProduct product = createProduct(); product.serve(); } public void executeJob(){ //some code performCriticalJob(); //some more code } } |
一些具体的产品
1 2 3 4 5 6 7 | package com.companyx; class AppAProductFeatureX implements IProduct{ @Override public void serve() { //some code } } |
工厂的混凝土产品
1 2 3 4 5 6 7 | package com.companyx; public class AppAFeatureXProductFactory extends Factory{ @Override public IProduct createProduct() { return new AppAProductFeatureX(); } } |
客户代码
1 2 3 4 5 6 7 8 9 | package com.clientcompany; import com.companyx.AppAFeatureXProductFactory; import com.companyx.Factory; public class Client { public static void main(String[] args) { Factory fact = new AppAFeatureXProductFactory(); fact.executeJob(); } } |
根据GOF抽象工厂模式
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
我的理解
客户对产品感兴趣,这种模式通过隐藏工厂类后面的具体产品类来帮助提供产品。
客户需要的产品类型
1 2 3 4 | package com.companyb; public interface IProductA { public void performAJob(); } |
实施该产品
1 2 3 4 5 6 7 8 | package com.companyb; //can be named better, but lets go with this name for this time public class ProductAVersion1 implements IProductA{ @Override public void performAJob() { // some code } } |
工厂界面,(也可以是抽象类)
1 2 3 4 | package com.companyb; public interface IFactory { public IProductA createProduct(); } |
Factory的具体实现o创建ProductA
package com.companyb;
1 2 3 4 5 6 | public class FactoryA implements IFactory{ @Override public IProductA createProduct() { return new ProductAVersion1(); // concrete class of product is hidden } } |
客户代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package com.clientcompany.productprovider; import com.companyb.IFactory; import com.companyb.IProductA; public class SomeClientClass { private IFactory factory; private IProductA product; public void doSomeJobWithProductA() { // some code product.performAJob(); //someCode(); } public void setFactory(IFactory factory) { this.factory = factory; this.product = factory.createProduct(); } } package com.clientcompany.productprovider; import com.companyb.FactoryA; public class SomeOtherClientCode { public static void main(String[] args) { SomeClientClass someClientClass = new SomeClientClass(); someClientClass.setFactory(new FactoryA()); someClientClass.doSomeJobWithProductA(); } } |
Q1:抽象工厂模式中是否需要相关产品系列,如果只有一种产品(如上所述)有各种子类型而不是各种相关类型,那么这种模式是否仍然相关?
Q2我的理解是否正确?
Q3 Above在我的脑海中带来了另一个疑问:Factory方法是否更适合于框架(客户端可以提供产品的实现),就像模板方法模式一样,工厂调用用户提供的具体工厂实现的
同样,抽象工厂更适合图书馆开发,具体的产品类别(可能会有所不同)隐藏在更稳定的工厂类别背后?
我很难穿上你的鞋子。但我对这个问题很感兴趣,所以我会试一试。这里涉及的概念包括
首先,
所以问题归结为你应该使用哪种模式?它不是关于差异,这是明确的,而是关于在哪种场景中使用哪一个。在此上下文中,
在键入任何代码(无论框架或库状态)时,有时我们需要获取某些对象的实例。可能是我们需要一个
我们可能不知道实例的具体类。现在质疑客户端代码是否有此信息?如果客户端代码知道实际的具体类,但我不知道那么我们使用
如果我们需要一个
如果有许多不同的类通过继承而不是与家族相关,我们可以使用
希望这有助于您在工厂模式和抽象工厂模式之间进行选择。
在我的理解中:
A1:产品系列不一定需要相关,如示例图所示,只需要具有产品类型知识的客户。 这种关系大多是自然的,因为你可能不希望同一个客户端创建2个不相关的对象,例如,如果你有一个创建Pizza和Cars的"AbstractPizzaFactory",它看起来会很奇怪,不是吗?
A2:从技术上讲,您可以在Factory模式中提供默认的工厂方法,这样您仍然可以创建(默认)新对象,而无需始终对其进行子类化。
A3:我同意你的观点,尽管创建一个图书馆或一个框架绝不是黑白分明的。
抽象工厂可以看作是工厂方法的集合。
为了更好地理解现实生活中的例子可以帮助:
工厂方法 - 橡皮泥/模具
抽象工厂 - 卡片厂