CS 696: Advanced OO
| 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 CheatWindow object can't be cast to another type!
public void setColor( Color newColor )
{
peer.setColor( newColor );
}