Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Transitioning from Factory Method to Abstract Factory Pattern in Java

Tech May 8 5

Suppose a business originally focused on agricultural goods now wants to expand into the apparel industry. Fruit and clothing items clearly belong to different production lines, so they cannot be manufactured in the same facility. Each production line may offer multiple specific products, yet all factories share the common trait of being production units under the same ownership. To manage this structure efficiently, we can apply the Abstract Factory pattern.

Product Interfaces and Implementations

First, define the Produce interface for agricultural goods:

public interface Produce {
    void display();
}

Implement two concrete fruit products:

public class Orange implements Produce {
    @Override
    public void display() {
        System.out.println("Orange crop harvested.");
    }
}

public class Banana implements Produce {
    @Override
    public void display() {
        System.out.println("Banana crop harvested.");
    }
}

Next, define the Apparel interface for clothing items:

public interface Apparel {
    void manufacture();
}

Implement two clothing products:

public class TShirt implements Apparel {
    @Override
    public void manufacture() {
        System.out.println("T-Shirt manufactured.");
    }
}

public class Jacket implements Apparel {
    @Override
    public void manufacture() {
        System.out.println("Jacket manufactured.");
    }
}

Abstract Factory Definition

Create a base factory class that declares methods for producing both product families:

public abstract class BaseManufacturer {
    public abstract Produce createProduce(String type);
    public abstract Apparel createApparel(String type);
}

Concrete Factories

The agriculture-focused factory only handles produce:

public class AgricultureFactory extends BaseManufacturer {
    @Override
    public Produce createProduce(String type) {
        if (type == null) return null;
        switch (type.toLowerCase()) {
            case "orange": return new Orange();
            case "banana": return new Banana();
            default: return null;
        }
    }

    @Override
    public Apparel createApparel(String type) {
        return null;
    }
}

The clothing-focused factory only handles apparel:

public class GarmentFactory extends BaseManufacturer {
    @Override
    public Produce createProduce(String type) {
        return null;
    }

    @Override
    public Apparel createApparel(String type) {
        if (type == null) return null;
        switch (type.toLowerCase()) {
            case "tshirt": return new TShirt();
            case "jacket": return new Jacket();
            default: return null;
        }
    }
}

Factory Producer

A producer class acts as a factory of factories:

public class ManufacturerHub {
    public static BaseManufacturer getManufacturer(String category) {
        if (category == null) return null;
        switch (category.toLowerCase()) {
            case "produce": return new AgricultureFactory();
            case "apparel": return new GarmentFactory();
            default: return null;
        }
    }
}

Usage Example

public class ManufacturerDemo {
    public static void main(String[] args) {
        BaseManufacturer agriculture = ManufacturerHub.getManufacturer("produce");
        Produce orange = agriculture.createProduce("orange");
        orange.display();

        Produce banana = agriculture.createProduce("banana");
        banana.display();

        BaseManufacturer garment = ManufacturerHub.getManufacturer("apparel");
        Apparel tshirt = garment.createApparel("tshirt");
        tshirt.manufacture();

        Apparel jacket = garment.createApparel("jacket");
        jacket.manufacture();
    }
}

Output:

Orange crop harvested.
Banana crop harvested.
T-Shirt manufactured.
Jacket manufactured.

The Abstract Factory pattern is a creational design pattern that provides a way to encapsulate a group of individual factories with a common goal. It is often described as a factory of factories. Each concrete factory is responsible for creating products of a specific family, while the abstract layer ensures consistency across different factory implementations.

  • Advantages: Easy to introduce new product families or extend existing ones. It promotes consistency among products and hides creation logic from the client.
  • Disadvantages: Increases system complexity due to additional layers of abstraction, which may affect readability for beginners.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.