Abstract Factory Design Pattern
Abstract Factory design pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. In normal usage, the client software creates a concrete implementation of the abstract factory and then uses the generic interfaces to create the concrete objects that are part of the theme.
Following example of Bank will illustrate the working of abstract factory pattern.
- You don’t walk up to a vault,
- Pull out a drawer with your name on it,
- Drop in your money,
- Shut the drawer and leave.
- You probably went to the bank,
- Spoke with an Account Manager and signed some papers.
- In return, they gave you some checks, a passbook, or a bank card so you could access your account in the future.
- The person or Automated Teller Machine (ATM) that acts as account manager controls the creation of and/or access to individual accounts.
Applicability
- 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 implementation
Example – Write a Cross Platform Window Toolkit
Write a toolkit to allow applications with GUI interfaces to run on multiple platforms (Mac, PC, OS/2, Unix motif ) using the look and feel of each platform
We will look at widgets: Windows, Menu’s and Buttons
Create an interface( or abstract class) for each widget and a concrete class for each platform

This allows the application to write to the widget interface
public void installDisneyMenu() {
Menu disney = create a menu somehow
disney.addItem( "Disney World" );
disney.addItem( "Donald Duck" );
disney.addItem( "Mickey Mouse" );
disney.addGrayBar( );
disney.addItem( "Minnie Mouse" );
disney.addItem( "Pluto" ); etc.
}
How to create the widget? Use Factory
abstract class WidgetFactory {
public Window createWindow();
public Menu createMenu();
public Button createButton();
}
class MacWidgetFactory extends WidgetFactory {
public Window createWindow() {
code to create a mac window
}
public Menu createMenu() {
code to create a mac Menu
}
public Button createButton() {
code to create a mac button
}
}
class Win95WidgetFactory extends WidgetFactory {
public Window createWindow() {
code to create a Win95 window
}
public Menu createMenu() {
code to create a Win95 Menu
}
public Button createButton() {
code to create a Win95 button
}
}
public void installDisneyMenu(WidgetFactory myFactory) {
Menu disney = myFactory.createMenu();
disney.addItem( "Disney World" );
disney.addItem( "Donald Duck" );
disney.addItem( "Mickey Mouse" );
disney.addGrayBar( );
disney.addItem( "Minnie Mouse" );
disney.addItem( "Pluto" );
...
}
We just need to make sure that the application for each platform creates the proper factory.
How Do Factories create Widgets?
Method 1- My Factory Method
abstract class WidgetFactory {
public Window createWindow();
public Menu createMenu();
public Button createButton();
}
class MacWidgetFactory extends WidgetFactory {
public Window createWindow() {
return new MacWidow()
}
public Menu createMenu() {
return new MacMenu()
}
public Button createButton() {
return new MacButton()
}
}
Method 2- Their Factory Method
abstract class WidgetFactory {
private Window windowFactory;
private Menu menuFactory;
private Button buttonFactory;
public Window createWindow() {
return windowFactory.createWindow()
}
public Menu createMenu(); {
return menuFactory.createWindow()
}
public Button createButton() {
return buttonFactory.createWindow()
}
}
class MacWidgetFactory extends WidgetFactory {
public MacWidgetFactory() {
windowFactory = new MacWindow();
menuFactory = new MacMenu();
buttonFactory = new MacButton();
}
}
class MacWindow extends Window {
public Window createWindow() {
//blah
}
abstract class WidgetFactory {
private Window windowFactory;
private Menu menuFactory;
private Button buttonFactory;
public Window createWindow() {
return windowFactory.createWindow()
}
public Window createWindow( Rectangle size) {
return windowFactory.createWindow( size )
}
public Window createWindow( Rectangle size, String title) {
return windowFactory.createWindow( size, title)
}
public Window createFancyWindow() {
return windowFactory.createFancyWindow()
}
public Window createPlainWindow() {
return windowFactory.createPlainWindow()
}
Method 3- Prototype
class WidgetFactory {
private Window windowPrototype;
private Menu menuPrototype;
private Button buttonPrototype;
public WidgetFactory( Window windowPrototype, Menu menuPrototype,
Button buttonPrototype) {
this.windowPrototype = windowPrototype;
this.menuPrototype = menuPrototype;
this.buttonPrototype = buttonPrototype;
}
public Window createWindow() {
return windowFactory.createWindow()
}
public Window createWindow( Rectangle size) {
return windowFactory.createWindow( size )
}
public Window createWindow( Rectangle size, String title) {
return windowFactory.createWindow( size, title)
}
public Window createFancyWindow() {
return windowFactory.createFancyWindow()
}
There is no need for subclasses of WidgetFactory.
Abstract Factory Implementation using Java
In this example we’ll apply the Factory Pattern to RMI. A factory implementation is useful when you need one object to control the creation of and/or access to other objects. By using a factory in RMI, you can reduce the number of objects that you need to register with the RMI registry.
Just like any other RMI program, there are a few basic players
A server
- produces one or more remote objects,
- each of which implements a remote interface
A client
- accesses a name server (the rmiregistry )
- to get a reference to one of the remote objects
- which facilitates the client’s initial contact with the server
There are two remote interfaces that the client understands,
Factory and Product
The FactoryImpl implements the Factory interface. The ProductImpl implements the Product interface

In previous example we saw how an Abstract Factory can be used to create widgets for a GUI environment. By designing the client to use the Abstract Factory interface, different factories can be created to generate different sets of widgets without requiring changes to the clients.
WidgetFactory.java
public interface WidgetFactory extends java.rmi.Remote {
public ScrollBar createScrollBar() throws java.rmi.RemoteException;
public Window createWindow() throws java.rmi.RemoteException;
}
This class represents the RMI server interface for creating GUI widgets. The actual RMI server that implements this interface determines which type of Widget objects are returned to the clients.
ScrollBar.java
This interface represents an abstract ScrollBar that would be returned from a WidgetFactory server.
public interface ScrollBar extends java.io.Serializable{
public String toString();
}
Window.java
This interface represents another GUI component that can be returned from a WidgetFactory.
public interface Window extends java.io.Serializable {
public String toString();
}
Client.java
This class is a simple client of the WidgetFactory that will grab a Window and ScrollBar and display the actual type of object that was loaded.
import java.rmi.*;
public class Client {public static void main(String[] args)
{
try {
WidgetFactory factory = (WidgetFactory) Naming.lookup("rmi://"+ args[0]+ "/WidgetFactory");
System.out.println("Window: "+factory.createWindow());
System.out.println("ScrollBar: "+factory.createScrollBar());
} catch(Exception e){
System.err.println("Failure creating widgets: " + e.getMessage());
}
}
}
MotifWidgetFactory.java
This class is an implementation of the WidgetFactory that will return MotifWidgets.
import java.rmi.*;import java.rmi.server.*;
public class MotifWidgetFactory extends UnicastRemoteObject implements WidgetFactory {
public MotifWidgetFactory() throws RemoteException {
super();
try {
Naming.rebind("rmi:///WidgetFactory",this);
System.out.println("Server ready");
} catch (Exception e){
System.err.println("Failure setting up WidgetFactory: "+ e.getMessage());
}
}
public static void main(String[] args){
try {
new MotifWidgetFactory();
} catch(Exception e){
System.err.println("Failure creating WidgetFactory:" + e.getMessage());
}
}
//Remote methods
public Window createWindow(){
return new MotifWindow();
}
public ScrollBar createScrollBar(){
return new MotifScrollBar();
}
}
MotifScrollBar.java
This class is a Motif representation of a ScrollBar that will be returned by the MotifWidgetFactory.
public class MotifScrollBar implements ScrollBar {
public String toString(){
return "MotifScrollBar";
}
}
MotifWindow.java
This class is a Motif representation of a Window that will be returned by the MotifWidgetFactory.
public class MotifWindow implements Window {
public String toString(){
return "MotifWindow";
}
}
AWTWidgetFactory.java
This is a second implementation of a WidgetFactory that returns AWT widgets.
import java.rmi.*;
import java.rmi.server.*;
public class AWTWidgetFactory extends UnicastRemoteObject
implements WidgetFactory {
public AWTWidgetFactory() throws RemoteException{
super();
try {
Naming.rebind("rmi:///WidgetFactory",this);
System.out.println("Server ready");
} catch(Exception e){
System.err.println("Failure setting up WidgetFactory: "
+ e.getMessage());
}
}
public static void main(String[] args){
try {
new AWTWidgetFactory();
} catch(Exception e){
System.err.println("Failure creating WidgetFactory: "
+ e.getMessage());
}
}
//Remote methods
public Window createWindow(){
return new AWTWindow();
}
public ScrollBar createScrollBar(){
return new AWTScrollBar();
}
}
AWTScrollBar.java
public class AWTScrollBar implements ScrollBar {
public String toString(){
return "AWTScrollBar";
}
}
AWTWindow.java
public class AWTWindow implements Window {
public String toString(){
return "AWTWindow";
}
}
Consequences
- It isolates concrete classes
- It makes exchanging product families easy
- It promotes consistency among products
- Supporting new kinds of products is difficult
Related Posts
Popular Posts (last 30 days)
- Attendance Management System 1481 view(s)
- Advanced Java Tutorial (For Intermediate) 771 view(s)
- JAVA Graphical User Interface (GUI) 726 view(s)
- Graph Implementation in C++ 531 view(s)
- File Handling using Input-Output Streams in Java 484 view(s)
- Linked lists in C++ 469 view(s)
- Sockets and Network Programming in Java 396 view(s)
- UDP Datagram Sockets in Java 392 view(s)
- Applications of Stack in data structures 391 view(s)
- Circular Linked Lists 345 view(s)







