工厂模式和抽象工厂模式之间的基本区别是什么?
当前回答
很多人可能会感到惊讶,但这个问题是不正确的。如果你在面试中听到这个问题,你需要帮助面试官理解你的困惑在哪里。
让我们从一个事实开始,即没有具体的模式被称为“工厂”。有一种模式叫做“抽象工厂”,也有一种模式叫做“工厂方法”。
那么,“工厂”是什么意思呢?以下之一(根据引用的范围,都可以认为是正确的):
有些人用它作为“抽象工厂”的别名(快捷方式)。 有些人使用它作为“工厂方法”的别名(快捷方式)。 有些人将其用作所有工厂/创建模式的通用名称。例如,“抽象工厂”和“工厂方法”都是工厂。
不幸的是,许多人使用“Factory”来表示另一种类型的工厂,它创建了一个或多个工厂(或它们的接口)。根据他们的理论:
Product实现了IProduct,它是由Factory创建的 实现了由AbstractFactory创建的IFactory。
为了理解这有多愚蠢,让我们继续我们的方程:
AbstractFactory实现了IAbstractFactory,它由… AbstractAbstractFactory ? ?
我希望你能明白我的意思。不要困惑,请不要发明那些无缘无故存在的东西。
-
附注:产品的工厂是AbstractFactory,而抽象工厂的工厂也是AbstractFactory的另一个例子。
其他回答
此信息的来源:http://java.dzone.com/news/intro-design-patterns-abstract
抽象工厂与工厂方法
抽象工厂的方法被实现为工厂方法。抽象工厂模式和工厂方法模式都通过抽象类型和工厂将客户端系统与实际实现类解耦。 工厂方法通过继承创建对象,而抽象工厂通过组合创建对象。
抽象工厂模式由AbstractFactory、ConcreteFactory、AbstractProduct、ConcreteProduct和客户端组成。
如何实现
抽象工厂模式可以使用工厂方法模式、原型模式或单例模式来实现。ConcreteFactory对象可以作为一个单例对象实现,因为只需要一个ConcreteFactory对象实例。
工厂方法模式是抽象工厂模式的简化版本。工厂方法模式负责创建属于一个家族的产品,而抽象工厂模式处理多个产品家族。
工厂方法使用接口和抽象类将客户端与生成器类和生成的产品解耦。摘要工厂有一个生成器,它是几个工厂方法的容器,以及将客户端与生成器和产品分离的接口。
何时使用工厂方法模式
当需要将客户端与其使用的特定产品解耦时,请使用工厂方法模式。使用Factory方法可以减轻客户端创建和配置产品实例的责任。
何时使用抽象工厂模式
当客户端必须从产品类中解耦时,使用抽象工厂模式。 特别适用于程序配置和修改。抽象工厂模式还可以强制约束哪些类必须与其他类一起使用。建造新的混凝土工厂可能需要做很多工作。
例子:
抽象工厂实例1
本规范适用于制备不同类型面食的圆盘 在面食机中有一个抽象工厂,每个特定的圆盘都是一个工厂。 所有的工厂(意大利面食机磁盘)从抽象工厂继承他们的属性。 每个单独的磁盘都包含如何制作意大利面,而意大利面机没有。
例子2:
冲压设备对应于抽象工厂,因为它是一个 用于创建抽象产品对象的操作接口。 模具对应混凝土工厂,因为他们创造一个混凝土产品。 每个部件类别(罩、门等)都对应于抽象产品。 具体部件(即99凯美瑞的司机侧门)对应 混凝土制品。
工厂方法示例:
玩具公司对应于创造者,因为它可以使用工厂来创建产品对象。制造特定类型玩具(马或汽车)的玩具公司的部门对应于ConcreteCreator。
很多人可能会感到惊讶,但这个问题是不正确的。如果你在面试中听到这个问题,你需要帮助面试官理解你的困惑在哪里。
让我们从一个事实开始,即没有具体的模式被称为“工厂”。有一种模式叫做“抽象工厂”,也有一种模式叫做“工厂方法”。
那么,“工厂”是什么意思呢?以下之一(根据引用的范围,都可以认为是正确的):
有些人用它作为“抽象工厂”的别名(快捷方式)。 有些人使用它作为“工厂方法”的别名(快捷方式)。 有些人将其用作所有工厂/创建模式的通用名称。例如,“抽象工厂”和“工厂方法”都是工厂。
不幸的是,许多人使用“Factory”来表示另一种类型的工厂,它创建了一个或多个工厂(或它们的接口)。根据他们的理论:
Product实现了IProduct,它是由Factory创建的 实现了由AbstractFactory创建的IFactory。
为了理解这有多愚蠢,让我们继续我们的方程:
AbstractFactory实现了IAbstractFactory,它由… AbstractAbstractFactory ? ?
我希望你能明白我的意思。不要困惑,请不要发明那些无缘无故存在的东西。
-
附注:产品的工厂是AbstractFactory,而抽象工厂的工厂也是AbstractFactory的另一个例子。
点击这里查看:http://www.allapplabs.com/java_design_patterns/abstract_factory_pattern.htm 似乎Factory方法使用一个特定的类(不是抽象类)作为基类,而抽象工厂则使用一个抽象类。此外,如果使用接口而不是抽象类,结果将是抽象工厂模式的不同实现。
:D
我认为我们可以通过查看Java8示例代码来理解这两者之间的区别:
interface Something{}
interface OneWhoCanProvideSomething {
Something getSomething();
}
interface OneWhoCanProvideCreatorsOfSomething{
OneWhoCanProvideSomething getCreator();
}
public class AbstractFactoryExample {
public static void main(String[] args) {
//I need something
//Let's create one
Something something = new Something() {};
//Or ask someone (FACTORY pattern)
OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeA = () -> null;
OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeB = () -> null;
//Or ask someone who knows soemone who can create something (ABSTRACT FACTORY pattern)
OneWhoCanProvideCreatorsOfSomething oneWhoCanProvideCreatorsOfSomething = () -> null;
//Same thing, but you don't need to write you own interfaces
Supplier<Something> supplierOfSomething = () -> null;
Supplier<Supplier<Something>> supplierOfSupplier = () -> null;
}
}
现在的问题是你应该使用哪种创造方式以及为什么: 第一种方式(没有模式,只是普通的构造函数):自己创建不是一个好主意,你必须做所有的工作,你的客户端代码绑定到特定的实现。
第二种方式(使用Factory模式):为您提供了可以传递任何类型的实现的好处,这些实现可以基于某些条件(可能是传递给创建方法的参数)提供不同类型的东西。
第三种方法(使用抽象工厂模式):这为您提供了更多的灵活性。您可以根据某些条件(可能是传递的参数)找到不同类型的创建者。
请注意,您总是可以通过将两个条件组合在一起来摆脱工厂模式(这稍微增加了代码的复杂性和耦合),我想这就是为什么我们很少看到抽象工厂模式的实际用例。
使用Factory模式,您可以生成特定接口(例如,IFruit)的实现实例(Apple、Banana、Cherry等)。
使用抽象工厂模式,您可以为任何人提供他们自己的工厂提供一种方法。这使得您的仓库可以是IFruitFactory或IJuiceFactory,而不需要您的仓库了解任何关于水果或果汁的信息。