Abstract FactoryAbstract Factory · 8/12/2013  · • Using factory method allows abstract class...

Preview:

Citation preview

Abstract FactoryAbstract Factory

IntentIntent• 'To provide an interface for creatingTo provide an interface for creating

families of related or dependent objects without specifying their concrete classes'without specifying their concrete classes

Examples of Factories in the Real World:• The Bank

G h b k k d i• Go to the bank to make a deposit to your account, – you don't walk up to a vault, – pull out a drawer with your name on it, – drop in your moneydrop in your money, – shut the drawer and leave.

• Think about how you originally established, or opened, the account.– 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. y y• The Account Manager is an example of a factory.

– The person or Automated Teller Machine (ATM) that acts as account manager controls the creation of and/or access to individual accounts.

StructureStructure

Example - Write a Cross Platform Window Toolkit • Write a toolkit to allow applications withWrite a toolkit to allow applications with

GUI interfaces to run on multiple platforms– (Mac, PC, OS/2, Unix motif ) using the look ( , , , ) g

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 theThis 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?• How to create the widget?

Use Abstract FactoryUse Abstract Factoryabstract class WidgetFactory {

bli Wi d t Wi d ()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 }

bli B tt t B tt () {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() {public Menu createMenu() {

code to create a Win95 Menu } public Button createButton() { p () {

code to create a Win95 button }

}

Etc.

• Now to get code that works for all platforms we g pget:

public void installDisneyMenu(WidgetFactory myFactory) { Menu disney = myFactory.createMenu(); di ddI ( "Di W ld" )disney.addItem( "Disney World" ); disney.addItem( "Donald Duck" ); disney.addItem( "Mickey Mouse" ); disney.addGrayBar( );disney.addGrayBar( ); disney.addItem( "Minnie Mouse" ); disney.addItem( "Pluto" ); etc.

}}

• 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 {

bli Wi d t Wi d ()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() }

bli B tt t B tt () {public Button createButton() { return new MacButton()

} } }

How Do Factories create Widgets? Method 2) Their Factory Method abstract class WidgetFactory {

private Window windowFactory; private Menu menuFactory; private Button buttonFactory; public Window createWindow() {public Window createWindow() {

return windowFactory.createWindow() } public Menu createMenu(); {public Menu createMenu(); {

return menuFactory.createWindow() } public Button createButton() { p () {

return buttonFactory.createWindow() }

}

How Do Factories create Widgets? Method 2) Their Factory Method class MacWidgetFactory extends WidgetFactory {

public MacWidgetFactory() { windowFactory = new MacWindow(); menuFactory = new MacMenu(); buttonFactory = new MacButton();

} }

class MacWindow extends Window { public Window createWindow() {

//blah } etc.

How Do Factories create Widgets? Method 2) Their Factory Method• When does this make Sense?• There might be more than one way to create a widgetabstract class WidgetFactory {

private Window windowFactory; i t M F tprivate Menu menuFactory;

private Button buttonFactory; public Window createWindow() {

return windowFactory.createWindow() y ()} public Window createWindow( Rectangle size) {

return windowFactory.createWindow( size ) }} public Window createWindow( Rectangle size, String title) {

return windowFactory.createWindow( size, title) }

public Window createFancyWindow() { t i d F t t F Wi d ()return windowFactory.createFancyWindow()

}public Window createPlainWindow() {

return windowFactory.createPlainWindow() }

• Using factory method allows abstract class to do all the different ways to create a windowall the different ways to create a window.

• Subclasses just provide the objects windowFactory, menuFactory, buttonFactory, y y yetc.

How Do Factories create Widgets? 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)return windowFactory.createWindow( size, title) } public Window createFancyWindow() {

return windowFactory createFancyWindow()return windowFactory.createFancyWindow() }etc.

• There is no need for subclasses of• There is no need for subclasses of WidgetFactory.

ApplicabilityApplicability • A system should be independent of how its y p

products are created, composed and represented

• A system should be configured with one ofA system should be configured with one of multiple families of products

• A family of related product objects is designed to b d t th d d t f thibe used together, and you need to enforce this constraint

• You want to provide a class library of products, ou a t to p o de a c ass b a y o p oducts,and you want to reveal just their interfaces, not their implementation

ConsequencesConsequences• It isolates concrete classesIt isolates concrete classes • It makes exchanging product families easy

It t i t d t• It promotes consistency among products • Supporting new kinds of products is

difficult

ImplementationImplementation• Factories as singletonsFactories as singletons • Defining extensible factories

Applying the Factory Pattern to RMI• A factory implementation is useful whenA factory implementation is useful when

you need one object to control the creation of and/or access to other objectsof and/or access to other objects.

• By using a factory in RMI, you can reduce the number of objects that you need tothe number of objects that you need to register with the RMI registry.

How Does a Factory Work in RMI?• Just like any other RMI program, there are a fewJust 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– a client • accesses a name server (the rmiregistry ) • to get a reference to one of the remote objects

– the rmiregistry• which facilitates the client's initial contact with the server

How Does a Factory Work in RMI?• There are two remote interfaces that theThere are two remote interfaces that the

client understands, Factory and Product– Factory and Product

• The FactoryImpl implements the Factory interfaceinterface

• The ProductImpl implements the Product finterface

Example : Widgets in a GUI Environment• In previous example we saw how an AbstractIn 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 javaWidgetFactory.java• This class represents the RMI serverThis class represents the RMI server

interface for creating GUI widgets. • The actual RMI server that implementsThe actual RMI server that implements

this interface determines which type of Widget objects are returned to the clients.g j

public interface WidgetFactory extends java.rmi.Remote {public ScrollBar createScrollBar() throws java.rmi.RemoteException;public Window createWindow() throws java.rmi.RemoteException;p () j p ;

}

ScrollBar javaScrollBar.java • This interface represents an abstractThis interface represents an abstract

ScrollBar that would be returned from a WidgetFactory serverWidgetFactory server.

public interface ScrollBar extends java.io.Serializable{public String toString();

}}

Window javaWindow.java • This interface represents another GUIThis interface represents another GUI

component that can be returned from a WidgetFactoryWidgetFactory.

public interface Window extends java.io.Serializable {public String toString();

}}

Client javaClient.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 wasWindow 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){catch(Exception e){

System.err.println("Failure creating widgets: " + e.getMessage());}

}}}

MotifWidgetFactory javaMotifWidgetFactory.java • This class is an implementation of the WidgetFactory that will return

MotifWidgetsMotifWidgets. import java.rmi.*;import java.rmi.server.*;

public class MotifWidgetFactory extends UnicastRemoteObjectpublic class MotifWidgetFactory extends UnicastRemoteObjectimplements WidgetFactory {

public MotifWidgetFactory() throws RemoteException {super();p ();try {

Naming.rebind("rmi:///WidgetFactory",this);System.out.println("Server ready");

} catch (Exception e){System err println("Failure setting up WidgetFactory: "System.err.println( Failure setting up WidgetFactory:

+ e.getMessage());}

}

public static void main(String[] args){try {try {

new MotifWidgetFactory();} catch(Exception e){

System.err.println("Failure creating WidgetFactory: "+ e getMessage());+ e.getMessage());

}}

//Remote methods//Remote methodspublic Window createWindow(){

return new MotifWindow();}

public ScrollBar createScrollBar(){return new MotifScrollBar();

}}}

MotifScrollBar javaMotifScrollBar.java • This class is a Motif representation of aThis class is a Motif representation of a

ScrollBar that will be returned by the MotifWidgetFactoryMotifWidgetFactory. public class MotifScrollBar implements ScrollBar {

public String toString(){return "MotifScrollBar";return MotifScrollBar ;

}}

MotifWindow javaMotifWindow.java • This class is a Motif representation of aThis class is a Motif representation of a

Window that will be returned by the MotifWidgetFactoryMotifWidgetFactory. public class MotifWindow implements Window {

public String toString(){return "MotifWindow";return MotifWindow ;

}}

AWTWidgetFactory javaAWTWidgetFactory.java • This is a second implementation of a WidgetFactory that

t AWT id treturns AWT widgets.import java.rmi.*;import java.rmi.server.*;

public class AWTWidgetFactory extends UnicastRemoteObjectimplements WidgetFactory {

public AWTWidgetFactory() throws RemoteException{super();try {try {

Naming.rebind("rmi:///WidgetFactory",this);System.out.println("Server ready");

} catch(Exception e){System.err.println("Failure setting up WidgetFactory: "y p ( g p g y

+ e.getMessage());}

}

public static void main(String[] args){try {try {

new AWTWidgetFactory();} catch(Exception e){

System.err.println("Failure creating WidgetFactory: "+ e.getMessage());e ge essage());

}}

//Remote methodspublic Window createWindow(){public Window createWindow(){

return new AWTWindow();}

public ScrollBar createScrollBar(){public ScrollBar createScrollBar(){return new AWTScrollBar();

}}

AWTScrollBar javaAWTScrollBar.java public class AWTScrollBar implements ScrollBar {

public String toString(){return "AWTScrollBar";

}

}

AWTWindow javaAWTWindow.javapublic class AWTWindow implements Window {public class AWTWindow implements Window {

public String toString(){return "AWTWindow";

}}}

Recommended