了解抽象工厂模式

3

我在维基百科上读到了关于抽象工厂模式的内容。但我不太明白使用这种模式真正的好处。你能否给出一个例子,说明在某些情况下很难避免使用抽象工厂模式。考虑以下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运算符。那么为什么我们需要抽象工厂?
3个回答

3

如果您需要透明地支持不同的实现,那么您可以利用这种模式。通过将使用哪个实现的决策委托给工厂,您在代码中只有一个点来做出该决策(即单一职责)。

抽象工厂模式将此概念推广到聚合相关工厂,例如在示例中的不同金融工具工厂。

如果您只在代码中实例化财务工具一次或两次,使用工厂就会过度设计。当您需要在许多地方多次实例化相同接口的不同实现,并且希望能够在不担心使用哪个实现或如何做出该决策的情况下工作时,才能获得收益。


3
你错过了一半的工作 :)
void processOrder(FinancialToolsFactory ftf,Order o) {

  tft.createTaxProcessor().calculateTaxes(o);
  tft.createShipFeeProcessor().calculateShipFee(o);
}

只要传递一个加拿大或欧洲的FinancialToolsFactory实现,这段代码就可以正常工作(你可以将实现类外部化到外部资源中,并使用Class.newInstance()进行实例化,例如)。

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

提示:我的答案故意不完整,仅回答了这个特定的问题;有关模式及其优点的讨论太大了!


2
在网络上有很多关于这种模式的资源,很难猜测以一种“合理”的方式解释其目的可能是最好的方法。
但我认为关键点是:
使用此模式,想要创建特定接口实现的实例的人不需要知道这个特定实现是什么。调用new运算符被隐藏在工厂内部,工厂的用户不需要知道具体类。
这使得稍后切换实现更容易:您不必查找和调整所有调用`new ConcreteClass()`并将其更改为`new OtherConcreteClass()`以使用不同实现的地方。您只需传递不同的工厂,并且使用该工厂的每个人都自动创建`OtherConcreteClass`的实例(甚至不知道他这样做...)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接