了解抽象工厂模式

我在维基上读过关于抽象工厂模式的文章。 但是我不明白使用这种模式真的有利可图。 你能得到一个很难避免抽象工厂模式的例子吗? 请考虑以下Java代码:

public abstract class FinancialToolsFactory { public abstract TaxProcessor createTaxProcessor(); public abstract ShipFeeProcessor createShipFeeProcessor(); } public abstract class ShipFeeProcessor { abstract void calculateShipFee(Order order); } public abstract class TaxProcessor { abstract void calculateTaxes(Order order); } // Factories public class CanadaFinancialToolsFactory extends FinancialToolsFactory { public TaxProcessor createTaxProcessor() { return new CanadaTaxProcessor(); } public ShipFeeProcessor createShipFeeProcessor() { return new CanadaShipFeeProcessor(); } } public class EuropeFinancialToolsFactory extends FinancialToolsFactory { public TaxProcessor createTaxProcessor() { return new EuropeTaxProcessor(); } public ShipFeeProcessor createShipFeeProcessor() { return new EuropeShipFeeProcessor(); } } // Products public class EuropeShipFeeProcessor extends ShipFeeProcessor { public void calculateShipFee(Order order) { // insert here Europe specific ship fee calculation } } public class CanadaShipFeeProcessor extends ShipFeeProcessor { public void calculateShipFee(Order order) { // insert here Canada specific ship fee calculation } } public class EuropeTaxProcessor extends TaxProcessor { public void calculateTaxes(Order order) { // insert here Europe specific tax calculation } } public class CanadaTaxProcessor extends TaxProcessor { public void calculateTaxes(Order order) { // insert here Canada specific tax calculation } } 

如果我们只需要在代码中创建1-2代以下的代码中的对象,那么我们就可以使用new运算符。 为什么我们需要抽象工厂?

你错过了一半的工作:)

 void processOrder(FinancialToolsFactory ftf,Order o) { tft.createTaxProcessor().calculateTaxes(o); tft.createShipFeeProcessor().calculateShipFee(o); } 

此代码与您传递FinancialToolsFactory的加拿大或欧洲实现一样有效(您可以将实现者类外部化为外部资源,并使用Class.newInstance()进行实例化)。

在这种情况下,模式使用的一个真正好处是不是编写实现模式的代码,而是使用该代码的代码!

PS:我的回答是故意不完整的,试着回答这个具体问题; 关于模式及其好处的讨论太大了!

如果您要透明地支持不同的实现,则可以利用此模式。 通过将要使用的实现的决策委托给工厂,您在代码中有一个点可以做出决定(也就是单一责任)。

抽象工厂模式通过聚合相关工厂(例如样本中的不同金融工具工厂)来实现这一概念。

现在,如果您只在代码中实例化一次或两次财务工具,那么使用工厂就会过度工程化。 当您需要多次在不同位置实例化相同接口的不同实现并且您希望能够工作而不必担心您正在使用哪个实现或如何做出决策时,就会获得收益。

在网络上有关于这种模式的相当多的资源,并且很难猜测什么是以对你来说听起来“合理”的方式解释其目的的最佳方式。

但我认为关键点是:

使用此模式,想要创建接口的特定实现的实例的人不需要知道该特定实现什么。 对new运算符的调用隐藏在工厂内部,工厂用户不需要知道具体类。

这使得以后更容易切换实现:您不必查找和调整调用new ConcreteClass()所有位置,并将其更改为new OtherConcreteClass()以使用不同的实现。 你只是通过一个不同的工厂,每个使用这个工厂的人都会自动创建OtherConcreteClass实例(甚至不知道他这样做……)