【问题标题】:Understanding Abstract Factory pattern理解抽象工厂模式
【发布时间】:2014-02-11 15:41:32
【问题描述】:

我在wiki 上阅读了有关抽象工厂模式的信息。但我不明白使用这种模式真的能获利。你能举一个很难避免抽象工厂模式的例子吗?考虑以下 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 运算符。为什么我们需要抽象工厂?

【问题讨论】:

    标签: java design-patterns factory-pattern


    【解决方案1】:

    你错过了一半的工作:)

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

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

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

    PS:我的答案故意不完整,并尝试仅回答这个特定问题;关于模式及其好处的讨论太大了!

    【讨论】:

      【解决方案2】:

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

      抽象工厂模式通过聚合相关工厂(例如样本中的不同金融工具工厂)超越了这个概念。

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

      【讨论】:

        【解决方案3】:

        网络上有很多关于这种模式的资源,很难猜测哪种方式可能是解释其目的的最佳方式,而这种方式对您来说听起来“合理”。

        但我认为关键是:

        使用这种模式,想要创建接口的特定实现的实例的人不需要知道这个特定实现是什么new操作符的调用隐藏在工厂内部,工厂的用户不需要知道具体的类。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-06
          • 1970-01-01
          • 2023-03-30
          相关资源
          最近更新 更多