Sunday, June 27, 2010

Abstarct Factory Method

In this edition of my blog, the usage of related objects to form a single component using Abstract Factory method is shared. For instance, take a CAR as example. There are different types of cars available in the market. If a particular customer wants to check the price details and the features in a specific car model, then we could come up with two component (1) Pricing component – which provides the price based on type of customer like corporate ,VIP and type of payment Loan,Cash etc.
(2) Features component – describes the features of the given model of the car.
Now the above 2 are independent component which could be related to provide the details of a car by a dealer.

Intent
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
Applicability
Use the Abstract Factory pattern when
• a system should be independent of how its products are created, composed, and represented.
• a system should be configured with one of multiple families of products.
• a family of related product objects is designed to be used together, and you need to enforce this constraint.
• you want to provide a class library of products, and you want to reveal just their interfaces, not their implementations

The below is an example which is written in a simple manner for beginners to understand, the example accepts the name of the car like “Tyota”, “HondaCity” and type of payment like “Loan” , “Cash” to provide the features and price of a car. The readers can extend the example according to their preference to provide more details.

abstract class VehicleFactory
{
public static Vehicle getVehicle(String name){ // static factory method.

try{
Class vehicleobj=Class.forName(name);
return (Vehicle)vehicleobj.newInstance();
}catch(Exception exp){
exp.printStackTrace();
}
return null;
}
}
/*
Factory interface which returns multiple products like Cost,Features are product interfaces
*/
interface Vehicle {
public Cost getCostSpecification();
public Features getFeatures();
}
interface Cost // product interface
{
public void checkPaymentType(String type);
public void print();
}
interface Features // product interface
{
// could check for type of car like with gear or without gear or subtype or model like innova,corolla

public void print();
}

class TyotaCar implements Vehicle{
public Cost getCostSpecification(){
return new TyotaCost();
}
public Features getFeatures(){

return new TyotaFeatures();
}
}

class TyotaFeatures implements Features{
public void print(){

System.out.println("Tyota Car Features");
}
}
class TyotaCost implements Cost
{
int amount=800000;
public void checkPaymentType(String type){

if(type.equalsIgnoreCase("Loan")){
amount+=amount*0.2;
}else{
amount-=amount*0.1;
}
}
public void print(){

System.out.println("Tyota Car:"+amount);
}

}
class HondaCityCar implements Vehicle{
public Cost getCostSpecification(){
return new HondaCost();
}
public Features getFeatures(){

return new HondaFeatures();
}
}

class HondaFeatures implements Features{
public void print(){

System.out.println("Honda City Car Features");
}
}
class HondaCost implements Cost
{
int amount=100000;
public void checkPaymentType(String type){

if(type.equalsIgnoreCase("Loan")){
amount+=amount*0.3;
}else{
amount-=amount*0.1;
}
}
public void print(){

System.out.println("HondayCity Car:"+amount);
}

}
class Client
{
public static void main(String args[]){

Vehicle car= VehicleFactory.getVehicle("TyotaCar");
Features carview=car.getFeatures();
carview.print();
Cost cost=car.getCostSpecification();
cost.checkPaymentType("Cash");
cost.print();


car= VehicleFactory.getVehicle("HondaCityCar");
carview=car.getFeatures();
carview.print();
cost=car.getCostSpecification();
cost.checkPaymentType("Loan");
cost.print();

}
}

Abstract Factory implementation could be seen in JDBC,JMS implementations. As in JDBC we change only the driver name and the internal implementation to execute the query according to database and retrieval of data is not exposed to the users of the API.

To Practice
1. Create a Customer, Account and Credit card class. When the customerid is given as input a single view of information related that customer should be displayed.
• Customer details like address, name, date of birth etc.
• Account information like accountno, opening balance, current balance, type of account
• Card information like cardno, available balance, date of last payment, expiry date should be printed.

2. Re-model the above implementation to provide the features for any four wheelers.

Thursday, June 17, 2010

Factory Method - 2nd Approach

Now we know that Factory method pattern is used for a creating object and lets its subclass to decide about which class to instantiate. This edition of blog will explain another mechanism or way of implementing the same pattern using Java 5 .

In last article we saw a shelf was able to accomodate any type of object by using parameterized Factory method and now we will take a Vehicle as an example in order to implement template type of Factory method.

Vechicle could be a Car,Plane,Bike,Bus etc , which ever the type of class instance the client needs should be available for it.

class Client
{
public static void main(String args[]){
ConcreteFactory cf=new ConcreteFactory();
Car c=cf.Create(Car.class);
System.out.println("Vechicle is :"+c.getName());
}
}

public interface Vehicle {
String getName();
}

public class Plane implements Vehicle {
String name="Boeing 777";
public String getName() {
return name;
}
}

public class Car implements Vehicle {
String name="Benz";
public String getName() {
return name;
}
}

public interface IFactory{
public <T extends Vehicle> T Create(Class<T> type);
}

public class ConcreteFactory implements IFactory {
public <T extends Vehicle> T Create(Class<T> type) {
try {
return type.newInstance();
} catch (InstantiationException e) {
System.out.println("Exception while instantiating..."+e);
return null;
} catch (IllegalAccessException e) {
System.out.println("IllegalAccessException..."+e);
return null;
}
}
}


Thumb Rule

o Often, designs start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Prototype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed.

o Prototype doesn’t require subclassing, but it does require an Initialize operation. Factory Method requires subclassing, but doesn’t require Initialize.

o The advantage of a Factory Method is that it can return the same instance multiple times, or can return a subclass rather than an object of that exact type.

o Some Factory Method advocates recommend that as a matter of language design (or failing that, as a matter of style) absolutely all constructors should be private or protected. But it can create a new object or recycles an old one.

o The new operator considered harmful. There is a difference between requesting an object and creating one. The new operator always creates an object, and fails to encapsulate object creation. A Factory Method enforces that encapsulation, and allows an object to be requested without unresolvable coupling to the act of creation.

Checklist

o If you have an inheritance hierarchy that uses polymorphism,then consider adding a polymorphic creation capability by defining a static factory method in the base class.

o Design the arguments to the factory method. What qualities or characteristics are necessary and sufficient to identify the correct derived class to instantiate?

o Consider designing an internal “object pool” that will allow objects to be reused instead of created from scratch.

o Consider making all constructors private or protected.

o The case when the Creator class is an abstract class and does not provide an implementation for the factory method it declares, requires the subclasses to define an implementation, because there's no reasonable default. It gets around the dilemma of having to instantiate unforeseeable classes.

o The case when the Creator is a concrete class and provides a default implementation for the factory method. It's also possible to have an abstract class that defines a default implementation, but this is less common. the concrete Creator uses the factory method primarily for flexibility. It's following a rule that says, "Create objects in a separate operation so that subclasses can override the way they're created." This rule ensures that designers of subclasses can change the class of objects their parent class instantiates if necessary.

Wednesday, June 16, 2010

Factory Method Pattern

Today I had a discussion with one of my office colleagues about GOF(Gang of Four Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides) patterns and advantages. During the discussion, he claimed a trivial question posed at him during the interview. He explained me the scenario.

A shelf should be able to hold any items like books, laptops etc. How to design such objects?
A shelf is an object which does not know what type of object it will hold. This gave the clue of implementing factory method pattern by GOF.


Applicability
Use the Factory Method pattern when
1. a class can't anticipate the class of objects it must create.
2. a class wants its subclasses to specify the objects it creates.
3. classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate.


Shelf is an object which does not what type of object a book or a laptop is. Hence, based on the applicability of Factory Method as provided by GOF mentioned above, the below sample is illustrated.



import java.util.ArrayList;
class Shelf
{
ArrayList list=null;
ContextFactory factory=null;
public void storeObject(String object){
if(list==null && factory==null){
list=new ArrayList();
factory=new ContextFactory();
}
Item itemobject=factory.createObject(object);
if(itemobject!=null)
list.add(itemobject);
}
public void printObjects(){

System.out.println(list.toString());
}
}
interface Items // Creator interface
{
public Item createObject(String object);
}

class ContextFactory implements Items // Creator class decides which object to be created.
{
public Item createObject(String object){
if(object!=null){

if(object.startsWith("Book")){
return new Book();
}else if(object.startsWith("Laptop")){

return new Laptop();
}

}
return null;
}
}
interface Item
{
// no implementation
}
class Book implements Item // class Book is of type Item
{
public Book(){

System.out.println("Book Object Created...");
}
}
class Laptop implements Item // class Laptop is of type Item
{
public Laptop(){

System.out.println("Latop Object Created...");
}

}

class Client
{
public static void main(String args[]){

Shelf shelfobj=new Shelf();
shelfobj.storeObject("Book");
shelfobj.storeObject("Laptop");
shelfobj.storeObject("Book");
shelfobj.storeObject("Book");
shelfobj.printObjects();
}
}

The above example is provided for beginners to practically copy and use the code for understanding.
Factory method pattern eliminate the need to bind application-specific classes into your code. The code only deals with the Product(Item) interface; therefore it can work with any user-defined ConcreteProduct(any objects could be stored in shelf) classes, as the Client class is not bound to Book,Laptop objects only we can create more type of objects by implementing Item interface and store in shelf.

There are multiple ways of implementing Factory Method which I will be providing samples in the forthcoming days.

To Practice
A customer visits to a shop and purchases the products of his preference for payment the customer might use debit card, credit card,customer card(VIP card with discount).Design a POS(Point of Sale) Reader class which will accept Credit card,Debit Card, Customer Card.

Readers may kindly provide valuable suggestions/comments in order to make the sample simple and easily understandable for beginners.

To have more discussions on Patterns and Object Oriented Design & Architecture, please feel free to mail me at : bala_j@rediffmail.com