Abstract-factory



Creational design patterns abstract the
instantiation process.
make a system independent of how its
objects are created, composed, and
represented.
Main goal is:
Provide an interface for creating families of
related or dependent objects without
specifying their concrete classes.
AbstractFactory (WidgetFactory)
declares an interface for operations that create
abstract product objects.
ConcreteFactory (Motif & PMWidgetFactory)
implements the operations to create concrete
product objects.
AbstractProduct (Window, ScrollBar)
declares an interface for a type of product object.
ConcreteProduct (MotifWindow, MotifScrollBar)
1- defines a product object to be created by the
corresponding concrete factory.
2-implements the AbstractProduct interface.
Client
uses only the interfaces declared by
AbstractFactory and AbstractProduct




a system should be independent of how its
products are created.
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 implementations.

It isolates concrete classes.
◦ It isolates clients from implementation classes. Clients
manipulate instances through their abstract interfaces.

It makes exchanging product families easy.
◦ It can use different product configurations simple by
changing the concrete factory.

It promotes consistency among products
◦ To enforce that an application use objects from only one family at
a time.

Supporting new kinds of products is difficult
 Adding a new product requires extending the abstract interface
which implies that all of its derived concrete classes also must
change.
 Essentially everything must change to support and use the new
product family





abstract factory interface is extended
derived concrete factories must implement the extensions
a new abstract product class is added
a new product implementation is added
client has to be extended to use the new product

Abstract Factory pattern to creating mazes
class MazeFactory
{
public:
MazeFactory();
virtual Maze * MakeMaze() const;
virtual Wall * MakeWall() const;
virtual Room * MakeRoom(int n) const;
virtual Door* MakeDoor(Room *r1, Room* r2) const;
}

CreateMaze taking a MazeFactory as a parameter
Maze *MazeGame::CreateMaze(MazeFactory& factory)
{
Maze * aMaze = factory.MakeMaze();
Room * r1 = factory.MakeRoom(1);
Room *r2 = factory.MakeRoom(2);
…
…
}

EnhantedMazeFactory
class EnchantedMazeFactory: public MazeFactory
{
public:
EnchantedMazeFactory();
virtual Room* MakeRoom(int n) const
{
return new EnchantedRoom(n, CastSpell());
virtual Door* MakeDoor(Room *r1, Room* r2) const
{
return new DoorNeedingSpell(r1,r2);
}
protected: Spell* CastSpell() const;
}
}

BombedMazeFactory
Wall * BombedMazeFactory::MakeWall() const
{
return new BombedWall;
}
Room *BombedMazeFactory::MakeRoom(int n) const
{
return new RoomWithABomb(n);
}

Code using BombedMazeFactory
MazeGame game;
BombedMazeFactory factory;
game.CreateMaze(factory);

CreateMaze can take an instance of
EnchantedMazeFactory just as well to build
enchanted mazes.
interface GUIFactory
{
public Button createButton();
}
class WinFactory implements GUIFactory
{
public Button createButton()
{ return new WinButton(); }
}
class OSXFactory implements GUIFactory
{
public Button createButton() { return new OSXButton(); }
}
interface Button
{
public void paint();
}
class WinButton implements Button
{
public void paint()
{
System.out.println("I'm a WinButton");
}
}
class OSXButton implements Button
{
public void paint()
{
System.out.println("I'm an OSXButton");
}
}
class Application
{
public Application(GUIFactory factory) {
Button button = factory.createButton();
button.paint();
}
}
public class ApplicationRunner
{
public static void main(String[] args) {
new Application(createOsSpecificFactory());
}
}
public static GUIFactory createOsSpecificFactory()
{
int sys = readFromConfigFile("OS_TYPE");
if (sys == 0) {
return new WinFactory(); }
else {
return new OSXFactory(); }
}