Level Up Your Java Skills!
Subscribe to Ram N Java for hands-on programming guides, real-world architecture patterns, and clean code examples!
SUBSCRIBE NOWUnderstanding the Architecture
The Abstract Factory Pattern acts as a "super-factory" or "factory of factories." In this practical implementation, we organize related objects into concrete families based on their environment:
- Land Animal Family: Produces land animals such as
Dog,Cat, andLion. - Sea Animal Family: Produces aquatic animals such as
SharkandOctopus. - Abstract Animal Factory: The super factory that delegates the creation of the correct concrete factory based on input.
Complete Java Code Implementation
Here is the complete source code demonstrating the interfaces, concrete implementations, factory classes, and client execution:
// 1. Common Product Interface
interface Animal {
String speak();
}
// Concrete Products: Land Animals
class Dog implements Animal {
@Override
public String speak() { return "Bark Bark"; }
}
class Cat implements Animal {
@Override
public String speak() { return "Meow Meow"; }
}
class Lion implements Animal {
@Override
public String speak() { return "Roar"; }
}
// Concrete Products: Sea Animals
class Shark implements Animal {
@Override
public String speak() { return "Cannot Speak"; }
}
class Octopus implements Animal {
@Override
public String speak() { return "Squawk"; }
}
// 2. Abstract Factory (Super Factory)
abstract class AnimalFactory {
public abstract Animal getAnimal(String animalType);
public static AnimalFactory getAnimalFactory(String factoryType) {
if ("SEA".equalsIgnoreCase(factoryType)) {
return new SeaAnimalFactory();
} else if ("LAND".equalsIgnoreCase(factoryType)) {
return new LandAnimalFactory();
}
return null;
}
}
// 3. Concrete Factories
class LandAnimalFactory extends AnimalFactory {
@Override
public Animal getAnimal(String animalType) {
if ("DOG".equalsIgnoreCase(animalType)) {
return new Dog();
} else if ("CAT".equalsIgnoreCase(animalType)) {
return new Cat();
} else if ("LION".equalsIgnoreCase(animalType)) {
return new Lion();
}
return null;
}
}
class SeaAnimalFactory extends AnimalFactory {
@Override
public Animal getAnimal(String animalType) {
if ("SHARK".equalsIgnoreCase(animalType)) {
return new Shark();
} else if ("OCTOPUS".equalsIgnoreCase(animalType)) {
return new Octopus();
}
return null;
}
}
// 4. Client / Driver Application
public class AbstractFactoryPatternDemo {
public static void main(String[] args) {
// Fetch Sea Animal Factory
AnimalFactory seaFactory = AnimalFactory.getAnimalFactory("SEA");
Animal shark = seaFactory.getAnimal("SHARK");
System.out.println("Shark says: " + shark.speak());
Animal octopus = seaFactory.getAnimal("OCTOPUS");
System.out.println("Octopus says: " + octopus.speak());
// Fetch Land Animal Factory
AnimalFactory landFactory = AnimalFactory.getAnimalFactory("LAND");
Animal dog = landFactory.getAnimal("DOG");
System.out.println("Dog says: " + dog.speak());
Animal cat = landFactory.getAnimal("CAT");
System.out.println("Cat says: " + cat.speak());
Animal lion = landFactory.getAnimal("LION");
System.out.println("Lion says: " + lion.speak());
}
}
Key Takeaways for Developers
- Encapsulation: The client application never calls the concrete class constructor directly using
new. - Extensibility: To add a new environment (e.g.,
SkyAnimalFactorywithBird), simply create the classes and register them in the super-factory without modifying existing product hierarchies. - Consistency: Ensures that related products stay within their defined family domain.
Watch More Related Design Pattern Tutorials
Click here to watch in Youtube : https://www.youtube.com/watch?v=Bbjh8atQJz0
Click the below Image to Enlarge
| Abstract Factory Design Pattern - Implementation - Class Diagram |
Animal.java
public interface Animal
{
public String speak();
}
Cat.java
public class Cat implements Animal
{
@Override
public String speak()
{
return "Meow Meow Meow";
}
}
Dog.java
public class Dog implements Animal
{
@Override
public String speak()
{
return "Bark Bark Bark";
}
}
Lion.java
public class Lion implements Animal
{
@Override
public String speak()
{
return "Roar";
}
}
Octopus.java
public class Octopus implements Animal
{
@Override
public String speak()
{
return "SQUAWCK";
}
}
Shark.java
public class Shark implements Animal
{
@Override
public String speak()
{
return "Cannot Speak";
}
}
AnimalFactory.java
public abstract class AnimalFactory
{
public abstract Animal getAnimal( String animalType );
public static AnimalFactory getAnimalFacory(String factoryType)
{
AnimalFactory animalFactory = null ;
if("sea".equals(factoryType))
{
animalFactory = new SeaAnimalFactory();
}
else
{
animalFactory = new LandAnimalFactory();
}
return animalFactory;
}
}
LandAnimalFactory.java
public class LandAnimalFactory extends AnimalFactory
{
public Animal getAnimal( String animalType )
{
Animal animal = null;
if( "dog".equals(animalType) )
{
animal = new Dog();
}
else if( "cat".equals(animalType) )
{
animal = new Cat();
}
else if( "lion".equals(animalType) )
{
animal = new Lion();
}
return animal;
}
}
SeaAnimalFactory.java
public class SeaAnimalFactory extends AnimalFactory
{
public Animal getAnimal( String animalType )
{
Animal animal = null;
if( "shark".equals(animalType) )
{
animal = new Shark();
}
else if( "octopus".equals(animalType) )
{
animal = new Octopus();
}
return animal;
}
}
Client.java
public class Client
{
public static void main( String[] args )
{
Animal animal = null;
AnimalFactory animalFactory = null;
String speakSound = null;
// Get Factory object by passing the factory type
animalFactory = AnimalFactory.getAnimalFacory("sea");
System.out.println("Animal Factory type : " + animalFactory.getClass().getName());
System.out.println();
// Get Animal object by passing the animal type
animal = animalFactory.getAnimal("shark");
System.out.println("Animal Type : "+animal.getClass().getName());
speakSound = animal.speak();
System.out.println("shark speak : "+speakSound);
System.out.println();
animal = animalFactory.getAnimal("octopus");
System.out.println("Animal Type : "+animal.getClass().getName());
speakSound = animal.speak();
System.out.println("octopus speak : "+speakSound);
System.out.println("---------------------------------------------------------");
// Get Factory by passing the factory type
animalFactory = AnimalFactory.getAnimalFacory("land");
System.out.println("Animal Factory type : " + animalFactory.getClass().getName());
System.out.println();
// Get Animal object by passing the animal type
animal = animalFactory.getAnimal("dog");
System.out.println("Animal Type : "+animal.getClass().getName());
speakSound = animal.speak();
System.out.println("dog speak : "+speakSound);
System.out.println();
animal = animalFactory.getAnimal("cat");
System.out.println("Animal Type : "+animal.getClass().getName());
speakSound = animal.speak();
System.out.println("cat speak : "+speakSound);
System.out.println();
animal = animalFactory.getAnimal("lion");
System.out.println("Animal Type : "+animal.getClass().getName());
speakSound = animal.speak();
System.out.println("lion speak : "+speakSound);
}
}
Output
Animal Factory type : SeaAnimalFactory
Animal Type : Shark
shark speak : Cannot Speak
Animal Type : Octopus
octopus speak : SQUAWCK
---------------------------------------------------------
Animal Factory type : LandAnimalFactory
Animal Type : Dog
dog speak : Bark Bark Bark
Animal Type : Cat
cat speak : Meow Meow Meow
Animal Type : Lion
lion speak : Roar
No comments:
Post a Comment