Abstract Factory | slide # 2 |
...How Do Factories create Widgets | slide # 6 |
......Method 1) My Factory Method | slide # 6 |
......Method 2) Their Factory Method | slide # 7 |
......Method 3) Prototype | slide # 9 |
...Applicability | slide # 10 |
...Consequences | slide # 10 |
Bridge Pattern | slide # 12 |
...Applicability | slide # 14 |
...Consequences | slide # 14 |
We will look at widgets: Windows, Menu's and Buttons
Create an interface( or abstract class) for each widget and an concrete class for each platform:
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?
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 } }Etc.
public void installDisneyMenu(WidgetFactory myFactory) { Menu disney = myFactory.createMenu(); disney.addItem( "Disnsey World" ); disney.addItem( "Donald Duck" ); disney.addItem( "Mickey Mouse" ); disney.addGrayBar( ); disney.addItem( "Minnie Mouse" ); disney.addItem( "Pluto" ); etc. }
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() } }
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 } etc.
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() }Using factory method allows abstract class to do all the different ways to create a window.
Subclasses just provide the objects windowFactory,
menuFactory, buttonFactory, etc.
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() }
public void installDisneyMenu(WidgetFactory myFactory) { // We ship next week, I can't get the stupid generic Menu to // do the fancy Mac menu stuff // Windows version won't ship for 6 months // Will fix this later MacMenu disney = (MacMenu) myFactory.createMenu(); disney.addItem( "Disney World" ); disney.addItem( "Donald Duck" ); disney.addItem( "Mickey Mouse" ); disney.addMacGrayBar( ); disney.addItem( "Minnie Mouse" ); disney.addItem( "Pluto" ); etc. }
class Window { private WindowImp realWindow; public void hide() { realWindow.hide(); } public void show() { realWindow.show();}
public void drawRectangle(int upperLeftX, int upperLeftY, int lowerRightX, int lowerRightY) { realWindow.drawLine( upperLeftX, upperLeftY, lowerRightX, upperLeftY); realWindow.drawLine( lowerRightX, upperLeftY, lowerRightX, lowerRightY); realWindow.drawLine( lowerRightX, lowerRightY, upperLeftX, lowerRightY); realWindow.drawLine( upperLeftX, lowerRightY, upperLeftX, upperLeftY); } }Application Code can't Cheat
Window object can't be cast to another type!
public void setColor( Color newColor ) { peer.setColor( newColor ); }