Search code examples
javadesign-patternsfactory-pattern

Understanding Abstract Factory pattern


I've read about abstract factory patter on wiki. But I don't understand really profit by using this pattern. Can you get an example in which is hard to avoid abstract factory pattern. Consider the following Java code:

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
    }
}

If we need to just create objects in a code below 1-2 times in a code then we can use just new operator. And why we need in abstract factory?


Solution

  • You are missing half of the work :)

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

    this code works as well as you pass a canadian or european implementation of FinancialToolsFactory (you can externalize the implementor class to external resource and instantiate with a Class.newInstance(), for example).

    In this case one of the real benefits of pattern usage is not writing the code that implements the pattern, but who use that code!

    PS: My answer is intentionally incomplete and try to answer just this specific question; a discussion about pattern and their benefits is too big!