工厂和抽象工厂模式之间的基本区别是什么?
同工厂模式,你生产实现的实例(Apple
,Banana
,Cherry
特定的接口等) -说IFruit
.
使用抽象工厂模式,您可以为任何人提供自己的工厂.这使您的仓库可以是一个IFruitFactory
或一个IJuiceFactory
,而不需要您的仓库知道有关水果或果汁的任何信息.
此信息的来源取自:http://java.dzone.com/news/intro-design-patterns-abstract
抽象工厂的方法是作为工厂方法实现的.抽象工厂模式和工厂方法模式都通过抽象类型和工厂将客户端系统与实际实现类分离.Factory方法通过继承创建对象,其中Abstract Factory通过合成创建对象.
抽象工厂模式由AbstractFactory,ConcreteFactory,AbstractProduct,ConcreteProduct和Client组成.
抽象工厂模式可以使用工厂方法模式,原型模式或单例模式来实现.ConcreteFactory对象可以实现为Singleton,因为只需要ConcreteFactory对象的一个实例.
Factory Method模式是Abstract Factory模式的简化版本.Factory Method模式负责创建属于一个系列的产品,而Abstract Factory模式负责处理多个产品系列.
Factory方法使用接口和抽象类将客户端与生成器类和生成的产品分离.Abstract Factory有一个发生器,它是几种工厂方法的容器,以及将客户端与发生器和产品分离的接口.
当需要将客户端与其使用的特定产品分离时,请使用Factory Method模式.使用工厂方法减轻客户对创建和配置产品实例的责任.
当客户端必须与产品类分离时,请使用抽象工厂模式.特别适用于程序配置和修改.抽象工厂模式还可以强制限制哪些类必须与其他类一起使用.建造新的混凝土工厂可能需要做很多工作.
用于在面食制作机中准备不同类型面食的盘的规范是抽象工厂,并且每个特定盘是工厂.所有工厂(面食制造商磁盘)从抽象工厂继承他们的属性.每个单独的磁盘包含如何创建面食的信息,而面食制造商则没有.
Stamping Equipment对应于Abstract Factory,因为它是创建抽象产品对象的操作的接口.模具对应于混凝土工厂,因为它们创造了一种混凝土产品.每个零件类别(引擎盖,门等)对应于抽象产品.特定部件(即99 camry的驾驶员侧门)对应于混凝土产品.
玩具公司对应于造物主,因为它可以使用工厂来创建产品对象.制造特定类型玩具(马或汽车)的玩具公司的分部对应于ConcreteCreator.
工厂模式:工厂生产IProduct实现
抽象工厂模式:工厂 - 工厂生产IFactories,反过来生产IP产品:)
[根据评论更新]至少
根据维基百科,我之前写的内容并不正确.抽象工厂只是一个工厂界面.有了它,您可以在运行时切换工厂,以允许不同的工厂在不同的环境中.示例可以是针对不同操作系统,SQL提供程序,中间件驱动程序等的不同工厂.
提供用于创建相关或从属对象族的接口,而无需指定其具体类.
抽象工厂模式与工厂方法模式非常相似.两者之间的一个区别是,使用抽象工厂模式,类通过组合将对象实例化的责任委托给另一个对象,而工厂方法模式使用继承并依赖子类来处理所需的对象实例化.
实际上,委托对象经常使用工厂方法来执行实例化!
工厂模式
工厂模式是创作模式的例子
创建模式抽象对象实例化过程.它们隐藏了如何创建对象,并帮助使整个系统独立于其对象的创建和组合方式.
类创建模式侧重于使用继承来决定要实例化的对象Factory Method
对象创建模式专注于将实例化委托给另一个对象Abstract Factory
参考: 工厂与抽象工厂
工厂方法:您有一个工厂,可以创建从特定基类派生的对象
抽象工厂:您有一个创建其他工厂的工厂,而这些工厂又创建从基类派生的对象.这样做是因为您通常不只是想创建单个对象(与Factory方法一样) - 而是要创建相关对象的集合.
抽象工厂是用于创建相关对象的接口,但工厂方法是一种方法.抽象工厂是通过工厂方法实现的.
基本差异:
Factory:创建对象而不将实例化逻辑暴露给客户端.
工厂方法:定义用于创建对象的接口,但让子类决定实例化哪个类.Factory方法允许类将实例化延迟到子类
抽象工厂:提供用于创建相关或从属对象族的接口,而无需指定其具体类.
AbstractFactory模式使用组合将创建对象的责任委托给另一个类,而Factory方法模式使用继承并依赖派生类或子类来创建对象
来自oodesign文章:
工厂类图:
示例:StaticFactory
public class ShapeFactory { //use getShape method to get object of type shape public static Shape getShape(String shapeType){ if(shapeType == null){ return null; } if(shapeType.equalsIgnoreCase("CIRCLE")){ return new Circle(); } else if(shapeType.equalsIgnoreCase("RECTANGLE")){ return new Rectangle(); } else if(shapeType.equalsIgnoreCase("SQUARE")){ return new Square(); } return null; } }
本文提供了实现FactoryMethod示例的非静态工厂:
设计模式:工厂与工厂方法与抽象工厂
何时使用:客户端只需要一个类,而不关心它所获得的具体实现.
工厂方法类digaram:
何时使用:客户端不知道在运行时需要创建哪些具体类,但只是想获得一个可以完成工作的类.
从 dzone的抽象工厂类图
何时使用:当您的系统必须创建多个系列的产品或您想要提供产品库而不暴露实施细节时.
上面文章中的源代码示例非常有助于清楚地理解这些概念.
与代码示例相关的SE问题:
工厂模式.何时使用工厂方法?
区别:
抽象工厂类通常使用工厂方法实现,但也可以使用Prototype实现
设计开始使用工厂方法(不太复杂,可定制,子类增加),并演变为其他创建模式(更灵活,更复杂),需要更多的灵活性.
工厂方法通常在模板方法中调用.
其他有用的文章:
factory_method从sourcemaking
abstract_factory从sourcemaking
来自journaldev的抽象工厂设计模式
抽象工厂的示例/场景
我住在雨季下雨的地方,冬天下雪,夏天炎热,阳光充足.我需要不同种类的衣服来保护自己免受这些因素的影响.为此,我去了我家附近的商店,要求衣服/物品来保护自己.店主根据口袋的环境和深度给我合适的物品.他给我的物品质量和价格范围相同.由于他了解我的标准,因此他很容易这样做.但是,当街对面的富人提出相同的要求时,他会获得一件昂贵的品牌商品.一个值得注意的事情是他给我的所有项目在术语质量,标准和成本方面相互补充.可以说他们互相帮助.这个有钱人得到的物品也是如此.
因此,通过观察上面的场景,我现在欣赏店主的效率.我可以用抽象商店取代这个店主.我们通过抽象项目和我以及富人作为透视客户获得的项目.我们所需要的只是符合我们需求的产品/产品.
现在我可以很容易地看到自己正在考虑一个为其众多客户提供一系列服务的在线商店.每个客户都属于三个组中的一个.当高级组用户打开网站时,他获得了很棒的UI,高度定制的广告窗格,菜单中的更多选项等.这些相同的功能集呈现给黄金用户,但菜单中的功能较少,广告大多是相关的,并且略微减少了egronomic UI.最后是我的用户,一个"免费组"用户.我的服务足够让我不被冒犯.用户界面是最低限度的,广告偏离轨道太多,所以我不知道它的内容,最后菜单只有注销.
如果我有机会建立类似这个网站的东西,我肯定会考虑抽象工厂模式.
抽象产品:广告窗格,菜单,UI画家.
抽象工厂:网上商店用户体验
Concreate工厂:高级用户体验,金牌用户体验,一般用户体验.
许多人可能会感到惊讶,但这个问题是不正确的.如果您在面试中听到这个问题,您需要帮助面试官了解混淆的位置.
让我们从没有具体模式被称为"工厂"的事实开始.有被称为"抽象工厂"的模式,有被称为"工厂方法"的模式.
那么,"工厂"是什么意思呢?以下之一(根据参考范围,所有都可以认为是正确的):
有些人将它用作" 抽象工厂 " 的别名(快捷方式).
有些人将它用作" 工厂方法 " 的别名(快捷方式).
有些人将它用作所有工厂/创作模式的更通用的名称.例如,"抽象工厂"和"工厂方法"都是工厂.
并且,不幸的是,许多人使用"工厂"来表示另一种工厂,它创建工厂或工厂(或他们的接口).根据他们的理论:
产品实现了由Factory创建的IProduct,它实现了由AbstractFactory创建的IFactory.
要理解这是多么愚蠢,让我们继续我们的等式:
AbstractFactory实现了IAbstractFactory,它是由... AbstractAbstractFactory创建的.
我希望你明白这一点.不要混淆,请不要发明不合理的东西.
-
PS:Factory for Products是AbstractFactory,而Factory For Abstract Factory也是AbstractFactory的另一个例子.
//Abstract factory - Provides interface to create factory of related products interface PizzaIngredientsFactory{ public Dough createDough(); //Will return you family of Dough public Clam createClam(); //Will return you family of Clam public Sauce createSauce(); //Will return you family of Sauce } class NYPizzaIngredientsFactory implements PizzaIngredientsFactory{ @Override public Dough createDough(){ //create the concrete dough instance that NY uses return doughInstance; } //override other methods }
其他答案已经提供了教科书定义.我想我也会提供一个例子.
所以这里PizzaIngredientsFactory
是一个抽象工厂,因为它提供了创建相关产品系列的方法.
请注意,Abstract工厂中的每个方法本身都是Factory方法.就像createDough()
本身就是一个工厂方法,其具体实现将由子类提供NYPizzaIngredientsFactory
.因此,使用此每个不同的位置可以创建属于其位置的具体成分的实例.
提供具体实现的实例
在示例中:
- createDough()
- 提供面团的具体实现.所以这是一种工厂方法
提供用于创建相关对象族的界面
在这个例子中:
- PizzaIngredientsFactory
是一个抽象的工厂,因为它允许创建一组相关的状物体Dough
,Clams
,Sauce
.为了创建每个对象系列,它提供了一个工厂方法.
Head First设计模式的示例
我有一些观点可以用John的答案作出如下贡献:
随着"工厂法"(因为只是"工厂"是不明确的),你生产的实现(Lemon
,Orange
特定的接口等) -说IFruit
.可以调用这个工厂CitricFruitFactory
.
但现在你想要创造另一种水果,而CitricFruitFactory无法创造.也许CitricFruitFactory
如果你Strawberry
在里面创造一个没有意义的代码(草莓不是柠檬水果!).
所以,你可以创建一个名为新厂RedFruitFactory
产生Strawberry
,Raspberry
等等.
就像John Feminella所说:
"使用抽象工厂模式,您可以生成特定工厂界面的实现 - 例如,IFruitFactory
每个人都知道如何创建不同种类的水果."
那个实现IFruitFactory
是CitricFruitFactory
和RedFruitFactory
!