GOF Design
Patterns in Java - Factory Method Pattern
For this Design pattern, I will discuss all below sections
Case Study Requirements – Case study Requirement to demonstrate GOF
design Patter
Naive Implementation
Proposal – Naïve Implementation for above case study
without GOF design Pattern
Naïve Code Example – Code example with above proposal
Limitations in above
approach –Limitations with above approach
Definition – definition as of Gang of Four
Overview – Brief about the design pattern with
suitable realtime example
Structure – class/flow diagram as per GOF
Code Example – code example by applying Patter
Code Example – code example by applying Patter
Benefits and Liabilities – Advantages and disadvantages with this
pattern
Points to Remember – Points to remember
When to use – where and when this pattern will be applicable
When to use – where and when this pattern will be applicable
Example from Java API – Known example from java api
Case Study Requirements
I have electronic show room
I sell Samsung machines and Refrigerators.
I need an application that
can show details of all my Samsung machines whenever I want.
Naive Implementation Proposal
Naive Code Example
public class ProductDetails {
public RefrigeratorDetails
getSamsungRefrigeratorDetails() {
RefrigeratorDetails
samsungFrige = new RefrigeratorDetails() ;
samsungFrige.setColor("White
Blue");
samsungFrige.setModelNo("Samsung
Refreegerator WB001");
samsungFrige.setCpacity("6 Leter");
samsungFrige.setPrice("15000");
return samsungFrige ;
}
public
WashingMachineDetails getSamsungWashingMachineDetails() {
WashingMachineDetails
samsungWS = new
WashingMachineDetails() ;
samsungWS.setColor("White
Blue");
samsungWS.setModelNo("Samsung
washing machine model BW001");
samsungWS.setCapacity("6 kg");
samsungWS.setPrice("20000");
return samsungWS ;
}
}
public class RefrigeratorDetails
{
String
modelNo , cpacity , price, color ;
//setter getter
}
public class
WashingMachineDetails {
String modelNo , capacity , price, color ;
//setter getter
}
public class Client {
public static void main(String[] args)
{
ProductDetails productDetails = new ProductDetails();
WashingMachineDetails washingMachine =
productDetails.getSamsungWashingMachineDetails();
System.out.println(washingMachine.getCapacity());
System.out.println(washingMachine.getModelNo());
System.out.println(washingMachine.getColor());
System.out.println(washingMachine.getPrice());
}
}
Limitations in above approach
- If washing Machine, refrigerator Details are provided by third party In future, then this application will not work.
- Client is directly dealing with actual implementation that means client is tightly coupled due to that if any product name is changed we need to change the calling method name. In our example we are accessing productDetails.getSamsungWashingMachineDetails() In future if you want to get other product details you need to call some other method like productDetails.getSamsungRefrigeratorDetails which is huge change at client side.
- Different methods returning different types of objects so cannot provide a generic way to handle objects at client side.
- ProductDetails class size will be increased if new product is introduced that effects the readability of the class.
Definition
Factory Pattern defines an
interface for creating an object, but let subclasses decide which class to
instantiate. Factory Method lets a class defer instantiation to subclasses.
Overview
Every Framework supports their services to developers with the help of
set of abstract classes and Interfaces. These abstract classes are being
implemented by the developers. But in beforehand framework designer do not have
idea that how these objects are going to be created by Framework users. Handling
these kinds of objects is really difficult to the Framework designer. This kind
problem can be solved with the help of Factory Method design pattern.
Structure
Code Example
public interface ProductDetails {
public String getModelNo();
public String getPrice();
public String getColor();
public String
getCapacity();
public void setColor(String
color);
public void setModelNo(String
modelNo);
public void setCapacity(String
capacity);
public void setPrice(String
price);
}
public class ProductFactory extends
ProductFactoryCreator {
protected <T extends ProductDetails> T
getProductFactory(Class<T> clazz) {
T
samsungWS = null;
try {
samsungWS
= clazz.newInstance();
samsungWS.setModelNo("Samsung
washing machine model WWBW001");
samsungWS.setCapacity("6 kg");
samsungWS.setPrice("20000");
}
catch
(InstantiationException e) {
e.printStackTrace();
}
catch
(IllegalAccessException e) {
e.printStackTrace();
}
return samsungWS;
}
}
public abstract class
ProductFactoryCreator {
protected abstract <T extends ProductDetails> T
getProductFactory (Class<T> clazz);
}
public class RefrigeratorDetails implements ProductDetails {
String
modelNo , capacity , price, color ;
//setter getter
}
}
public class
WashingMachineDetails implements ProductDetails {
String modelNo , capacity , price, color ;
//setter getter
}Benefits and Liabilities
- Client is not directly dealing with actual implementations so it is loosely coupled with actual implementation. Since all products are expected to be implemented ProductDeatils, if product is changed no huge change will be at client side.
- Since all products are implementing all products will have same so developer can provide a generic way to handle objects at client side.
- Adding new product is easy. Just implementing the interface ProductDeatils is enough.
- Factory method provides the facility to subclass to implement how they want.
Points to Remember
Java Static Factory Methods are different to GOF Factory Method design pattern.
You can also apply generics for bounded parameters. But it has its own limitations. If your application is “Ok” with those you can use as shown below
You can also apply generics for bounded parameters. But it has its own limitations. If your application is “Ok” with those you can use as shown below
protected <T extends ProductDetails> T getProductFactory(Class<T>
clazz) {
T samsungWS = null;
try {
samsungWS
= clazz.newInstance();
samsungWS.setModelNo("Samsung
washing machine model WWBW001");
samsungWS.setPrice("20000");
} catch (InstantiationException
e) {
e.printStackTrace();
} catch
(IllegalAccessException e) {
e.printStackTrace();
}
return samsungWS;
}
When to use
- When the implementation details are not known at development time i.e., Concrete implementation is being provided by others who will use our class in future.
- When a super class wants specify the object that are going to be created by subclass
No comments:
Post a Comment