Thursday, February 26, 2015

Abstract Factory Design Pattern

Design Pattern > Creational Design Pattern > Abstract Factory Design Pattern

Abstract factory pattern provide the interface which used to create related or dependent objects without specifying their concrete classes.
The client remains completely unaware (decoupled) on which concrete products it gets from each of these individual factories and the client is only able to access a simplified interface.

Abstract factory pattern is also called factory of factories because return type of factory class methods are a abstract class( factory) which further creates the concrete object.

Key terms in Abstract Factory Design pattern :

AbstractFactory - declares a interface for operations that create abstract products.
ConcreteFactory - implements operations to create concrete products.
AbstractProduct - declares an interface for a type of product objects.
ConcreteProduct - defines a product to be created by the corresponding ConcreteFactory; it implements the AbstractProduct interface.
Client - uses the interfaces declared by the AbstractFactory and AbstractProduct classes.


Let's see a example. Suppose a computer manufacturer company has two factories one is LaptopFactory which manufactures hi-end and low-end laptops models HI_LAP_A, LOW_LAP_Z) and another factory is DesktopFactory which manufactures hi-end and low-end desktops models HI_DESK_A, LOW_DESK_Z .Based on client input either laptop or desktop, system prints the details of PCs i.e. final products.

We will create interface/abstract classes LowEndProductFactory and HiEndProductFactory as AbstractProduct and provide makeProduct() method to be implemented by actual products(laptop and Desktop models classes).

public interface LowEndProductFactory{

void makeProduct();
}

public interface HiEndProductFactory{

void makeProduct();
}

then AbstractComputerFactory would be our AbstractFactory interface which declares methods of return type as LowEndProductFactory and HiEndProductFactory.

public interface AbstractComputerFactory{

LowEndProductFactory creteLowEndPC();
HiEndProductFactory createHiEndPC();
}
this interface will be implemented by ConcreteFactory classes which are LaptopFactory and DesktopFactory.
finally our client class will print these product details based on the the user input as "laptop" or "desktop".

Java Implementation :

/**
 * AbstractProduct
 */
package com.kmingle.abstractfactory;

public interface HiEndProductFactory {

void getProductDetails();
}


/**
 * ConcreteProduct
 */
package com.kmingle.abstractfactory;

public class HI_LAP_A implements HiEndProductFactory {

/* (non-Javadoc)
* @see com.kmingle.abstractfactory.HiEndProductFactory#makeProduct()
*/
@Override
public void getProductDetails() {

System.out.println("Hi-end Laptop");

}

}


/**
 * ConcreteProduct
 */
package com.kmingle.abstractfactory;

public class HI_DESK_A implements HiEndProductFactory {

/* (non-Javadoc)
* @see com.kmingle.abstractfactory.HiEndProductFactory#makeProduct()
*/
@Override
public void getProductDetails() {

System.out.println("Hi-end Desktop");
}

}


/**
 * AbstractProduct
 */
package com.kmingle.abstractfactory;

public interface LowEndProductFactory {

void getProductDetails();
}


/**
 * ConcreteProduct
 */
package com.kmingle.abstractfactory;

public class LOW_LAP_Z implements LowEndProductFactory {

/* (non-Javadoc)
* @see com.kmingle.abstractfactory.LowEndProductFactory#makeProduct()
*/
@Override
public void getProductDetails() {

System.out.println("Low-end Laptop");
}

}


/**
 * ConcreteProduct
 */
package com.kmingle.abstractfactory;

public class LOW_DESK_Z implements LowEndProductFactory {

/* (non-Javadoc)
* @see com.kmingle.abstractfactory.LowEndProductFactory#makeProduct()
*/
@Override
public void getProductDetails() {

System.out.println("Low-end Desktop");
}

}


/**
 * AbstractFactory
 */
package com.kmingle.abstractfactory;

public interface AbstractComputerFactory {

LowEndProductFactory creteLowEndPC();
HiEndProductFactory createHiEndPC();
}


/**
 * ConcreteFactory
 */
package com.kmingle.abstractfactory;

public class LaptopFactory implements AbstractComputerFactory {

/* (non-Javadoc)
* @see com.kmingle.abstractfactory.AbstractComputerFactory#creteLowEndPC()
*/
@Override
public LowEndProductFactory creteLowEndPC() {
return new LOW_LAP_Z();
}

/* (non-Javadoc)
* @see com.kmingle.abstractfactory.AbstractComputerFactory#createHiEndPC()
*/
@Override
public HiEndProductFactory createHiEndPC() {
return new HI_LAP_A();
}

}


/**
 * ConcreteFactory
 */
package com.kmingle.abstractfactory;

public class DesktopFactory implements AbstractComputerFactory {

/* (non-Javadoc)
* @see com.kmingle.abstractfactory.AbstractComputerFactory#creteLowEndPC()
*/
@Override
public LowEndProductFactory creteLowEndPC() {
return new LOW_DESK_Z();
}

/* (non-Javadoc)
* @see com.kmingle.abstractfactory.AbstractComputerFactory#createHiEndPC()
*/
@Override
public HiEndProductFactory createHiEndPC() {
return new HI_DESK_A();
}

}


/**
 * Client Class
 */
package com.kmingle.abstractfactory;

import java.io.InputStream;
import java.util.Scanner;

public class AbstractFactoryClient {

public static void main(String[] args) {

AbstractComputerFactory acf;
while (true) {
System.out.println("enter your choice: ");
Scanner user_input = new Scanner( System.in );
String userChoice = user_input.next();
if ("laptop".equals(userChoice)) {
acf = new LaptopFactory();
printAvailableProducts(acf);
} else if ("desktop".equals(userChoice)) {
acf = new DesktopFactory();
printAvailableProducts(acf);
} else {
System.out.println("no product available");
System.exit(0);
}
}

}

private static void printAvailableProducts(AbstractComputerFactory acf) {

System.out.println("available products in entered choice are : ");
acf.createHiEndPC().getProductDetails();
acf.creteLowEndPC().getProductDetails();
}

}

OutPut :

enter your choice:
desktop
available products in entered choice are :
Hi-end Desktop
Low-end Desktop
enter your choice:
laptop
available products in entered choice are :
Hi-end Laptop
Low-end Laptop
enter your choice:
server
no product available


So, now if you want to add new product say server you need to create 1. server product classes by implementing productfactory interface 2. create serverfactory class by impplementing AbstractComputerFactory 3. add a condition for server in client class

No comments:

Total Pageviews