Java Design Pattern - Creational - Factory Pattern
Understanding the Factory Design Pattern: A Practical Example
The Factory Design Pattern is a creational design pattern used to create objects without specifying the exact class of object that will be created. It provides a way to delegate the instantiation logic to subclasses. This pattern is particularly useful when the exact type of object required can vary and must be determined at runtime. In this blog post, we will explore the Factory Design Pattern using a practical example involving a shop that makes different types of puffs.
The Concept
In our example, we have a Shop
class that is responsible for creating Puff
objects. The specific type of puff (e.g., egg or chicken) is not known to the Shop
class. Instead, the decision of which type of puff to create is delegated to subclasses of the Shop
class. This approach aligns with the Factory Design Pattern by abstracting the object creation process.
The Implementation
Let's walk through the code step by step, based on the provided example.
1. Defining the Puff
Interface
public interface Puff {
void prepare();
}
The Puff
interface declares a prepare
method that each specific type of puff must implement.
2. Implementing Concrete Puff Classes
public class EggPuff implements Puff { @Override
public void prepare() {
// prepare egg puff code
}
}
public class ChickenPuff implements Puff {
@Override
public void prepare() {
// prepare chicken puff code
}
}
We have two concrete classes, EggPuff
and ChickenPuff
, both implementing the Puff
interface and providing specific implementations for the prepare
method.
3. Creating the Abstract Shop
Class
public abstract class Shop { public Puff orderPuff() {
Puff puff = createPuff();
puff.prepare();
return puff;
}
public abstract Puff createPuff();
}
The Shop
class is abstract and contains a method orderPuff
that orders a puff. The actual creation of the puff is deferred to the createPuff
method, which is abstract and must be implemented by subclasses.
4. Implementing Concrete Shop Classes
public class EggPuffShop extends Shop { @Override
public Puff createPuff() {
return new EggPuff();
}
}
public class ChickenPuffShop extends Shop {
@Override
public Puff createPuff() {
return new ChickenPuff();
}
}
We then have two subclasses of Shop
: EggPuffShop
and ChickenPuffShop
. Each subclass implements the createPuff
method to return the specific type of puff it creates.
How It Works
When a client orders a puff from a Shop
, they interact with the orderPuff
method. This method delegates the creation of the puff to the createPuff
method, which is defined in the subclasses. As a result, the client does not need to know the specifics of which type of puff is being created.
For example:
public static void main(String[] args) { Shop eggPuffShop = new EggPuffShop();
Puff eggPuff = eggPuffShop.orderPuff();
Shop chickenPuffShop = new ChickenPuffShop();
Puff chickenPuff = chickenPuffShop.orderPuff();
}
In this example, eggPuffShop
will create and prepare an EggPuff
, while chickenPuffShop
will create and prepare a ChickenPuff
.
Structure of Factory Design Pattern
Benefits of the Factory Design Pattern
- Encapsulation: The creation logic is encapsulated in subclasses, keeping the client code clean and focused on the higher-level logic.
- Flexibility: Adding new types of puffs (e.g.,
VegPuff
) only requires creating new subclasses ofShop
without modifying existing code. - Separation of Concerns: The pattern separates the responsibility of creating objects from the main business logic, making the system easier to manage and extend.
Conclusion
The Factory Design Pattern is a powerful tool for managing object creation in a flexible and maintainable way. By using this pattern, you can delegate the responsibility of object creation to subclasses, allowing for a clean separation of concerns and easy extension of functionality. The puff shop example demonstrates how this pattern can be applied in a real-world scenario, ensuring that your code remains adaptable and scalable.
Comments
Post a Comment