Abstract Factory Pattern
The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without
specifying their concrete classes. In normal usage, the client software creates a concrete implementation of the abstract factory and then
uses the generic interface of the factory to create the concrete objects that are part of the theme. The client doesn't know (or care) which
concrete objects it gets from each of these internal factories, since it uses only the generic interfaces of their products. This pattern
separates the details of implementation of a set of objects from their general usage and relies on object composition, as object creation
is implemented in methods exposed in the factory interface.
A factory is the location of a concrete class in the code at which objects are constructed. The intent in employing the pattern
is to insulate the creation of objects from their usage and to create families of related objects without having to depend on their concrete
classes. This allows for new derived types to be introduced with no change to the code that uses the base class.
Take an example, lets create a button factory. This button factory would be common across multiple operating systems and should
create the button depends on underlying operating system. Here is the sample code:
Code for Button Interface:
package com.java2novice.dp.abstractfactory;
public interface Button {
public void paint();
}
|
Windows button implementation class:
package com.java2novice.dp.abstractfactory;
public class WindowsButton implements Button {
@Override
public void paint() {
/** add code to paint windows button **/
System.out.println("painting windows button...");
}
}
|
Mac Button implementation class:
package com.java2novice.dp.abstractfactory;
public class MacButton implements Button {
@Override
public void paint() {
/** add code to paint MAC OS button **/
System.out.println("painting MAC OS button...");
}
}
|
Common Button Factory Interface:
package com.java2novice.dp.abstractfactory;
public interface ButtonFactory {
public Button createButton();
}
|
Windows Factory implementation:
package com.java2novice.dp.abstractfactory;
public class WindowsFactory implements ButtonFactory {
@Override
public Button createButton() {
/**
* this method creates a button for windows
* button
*/
System.out.println("creating windows button...");
return new WindowsButton();
}
}
|
Mac Button Factory implementation class:
package com.java2novice.dp.abstractfactory;
public class MacOsFactory implements ButtonFactory {
@Override
public Button createButton() {
/**
* this method creates a button for MAC OS
* button
*/
System.out.println("creating mac os button...");
return new MacButton();
}
}
|
GUI Factory Class:
package com.java2novice.dp.abstractfactory;
public class GUIFactory {
private GUIFactory(){
//make private constructor..
}
public static Button createButton(){
String os = null;
/**
* this method should work based on the operating system
* it is running on. First we need to decide which operating
* system is it.
*
* for the example purpose, i will hardcode OS as windows.
*/
os = "windows"; //this is hardcoded value. it should be assigned
// with dynamic logic.
if("windows".equalsIgnoreCase(os)){
return new WindowsFactory().createButton();
} else if("mac".equalsIgnoreCase(os)){
return new MacOsFactory().createButton();
}
return null;
}
}
|
Here is the class to test abstract factory pattern:
package com.java2novice.dp.abstractfactory;
public class AbstractFactoryTest {
public static void main(String a[]){
Button btn = GUIFactory.createButton();
btn.paint();
}
}
|
|