300 likes | 324 Views
Algorithm Programming 2 89-211 Creational Design Patterns. Bar-Ilan University 2005-2006 תשס"ו by Moshe Fresko. Creational Design Patterns. Creational DP: Abstracts the instantiation process. Helps make a system independent of how objects are created, composed, represented. Two types
E N D
Algorithm Programming 289-211Creational Design Patterns Bar-Ilan University 2005-2006 תשס"ו by Moshe Fresko
Creational Design Patterns • Creational DP: • Abstracts the instantiation process. • Helps make a system independent of how objects are created, composed, represented. • Two types • Class creationalUses inheritance to vary the class to be instantiated • Object creationalDelegates instantiation to another object
Creational Patterns • Creational Patterns are important as systems depend more on object composition • Creational Patterns • Encapsulate concrete classes system uses • Hide how instances of these classes are created
Maze example interface Site { void enter() ; } class Room implements Site { public Room(int number){ roomNumber = number ; } public Site getSide(int direction) { return sides[direction] ; } public void setSide(int direction, Site m) { sides[direction] = m ; } public void enter() { } private Site[] sides = new Site[4] ; private int roomNumber ; } class Wall implements Site { public Wall() { } public void enter() { } } class Door implements Site { public Door(Room r1, Room r2){ room1 = r1 ; room2 = r2 ; } public void enter() { } private Room room1, room2 ; private boolean isOpen ; }
Maze Example class Maze { public static int NORTH = 0 ; public static int SOUTH = 1 ; public static int EAST = 2 ; public static int WEST = 3 ; public Maze() { } public void addRoom(Room r) { rooms.add(r) ; } public Room roomNo(int idx) { return (Room) rooms.get(idx) ; } List rooms = new ArrayList() ; }
Maze Example class MazeGame { public Maze createMaze() { Maze maze = new Maze() ; Room room1 = new Room(1) ; Room room2 = new Room(2) ; Door door = new Door(room1,room2) ; maze.addRoom(room1) ; maze.addRoom(room2) ; room1.setSide(Maze.NORTH,new Wall()) ; room1.setSide(Maze.EAST ,door) ; room1.setSide(Maze.SOUTH,new Wall()) ; room1.setSide(Maze.WEST ,new Wall()) ; room2.setSide(Maze.NORTH,new Wall()) ; room2.setSide(Maze.EAST ,new Wall()) ; room2.setSide(Maze.SOUTH,new Wall()) ; room2.setSide(Maze.WEST ,door) ; return maze ; } }
Factory Method • Intent: Define an interface for creating an object, but let subclasses decide which cass to instantiate. • Motivation: • Example: Framework of Abstract classes • Abstract classes: Document, Application • Application has Open, New, etc. to create new documents • Application cannot know which concrete document to instant • Concrete classes: DrawingDocument, DrawingApplication
Factory Method Solution • CreateDocument() = Factory Method
Factory Method • Applicability: • Use the Factory Method when • A class can’t anticipate the class of objects it must create • A class wants its subclasses to specify the objects it creates
Factory Method - Participants • Product (Document) • The interface of objects the Factory Method creates • ConcreteProduct (MyDocument) • Implements the product interface • Creator (Application) • Declares the factory method which returns an object of type Product • ConcreteCreator (MyApplication) • Defines the Factory method to returnn an instance of ConcreteProduct
Factory Method Implementation • Abstract Creator Class v.s. Concrete Creator Class • Parameterized Factory Method • Creator can keep the Class Info to instantiate (Can avoid sub classing) • To use naming conventions
Factory Methods in Maze Example public class MazeGame { Maze newMaze() { return new Maze() ; } Room newRoom(int n) { return new Room(n) ; } Wall newWall() { return new Wall() ; } Door newDoor(Room r1, Room r2) { return new Door(r1,r2) ; } public Maze createMaze() { Maze maze = newMaze() ; Room room1 = newRoom(1) ; Room room2 = newRoom(2) ; Door door = newDoor(room1,room2) ; ……… ……… return maze ; } }
Customized Maze Components class BombedWall extends Wall { } class RoomWithABomb extends Room { RoomWithABomb(int n) { super(n) ; } } class BombedMazeGame extends MazeGame { Wall newWall() { return new BombedWall() ; } Room newRoom(int n) { return new RoomWithABomb(n) ; } }
Abstract Factory • Intent: Provides an interface for creating families of related or dependent objects without specifying their concrete classes. • Motivation: • User interface Toolkit supporting multiple look-and- feel standards. (Widgets like Scroll Bars, Windows, Buttons etc.) • Not to hard code these widgets for a particular look-and-feel otherwise hard to change it • We can define a WidgetFactory interface for creating each basic entity
Abstract Factory - Applicability • Use Abstract Factory if • A system must be independent of how its products are created • A system should be configured with one of multiple families of products • A family of related objects must be used together • You want to reveal only interfaces of a family of products and not their implementations
Abstract Factory - Participants • AbstractFactory (WidgetFactory) • Declares an interface of methods to create abstract product objects • ConcreteFactory (MotifWidgetFactory,…) • Implements the methods to create concrete product objects • AbstractProduct (Window, ScrollBar) • Declares an interface for a product type • ConcreteProduct (MotifWindow, MotifScrollBar) • Defines a product object • Implements the AbstractProduct interface • Client • Uses only interfaces declared by AbstractFactory and AbstractProduct
Abstract Factory Implementation • Factory better to be a Singleton • A new Concrete Factory for each Platform.Or alternatively a single Concrete Factory keeping its Classes of Products. • Extending the Factories. (Adding a new Product)
Abstract Factory – Maze Example class MazeFactory { Maze newMaze() { return new Maze() ; } Room newRoom(int n) { return new Room(n) ; } Wall newWall() { return new Wall() ; } Door newDoor(Room r1, Room r2) { return new Door(r1,r2) ; } } public class MazeGame { public Maze createMaze(MazeFactory factory) { Maze maze = factory.newMaze() ; Room room1 = factory.newRoom(1) ; Room room2 = factory.newRoom(2) ; Door door = factory.newDoor(room1,room2) ; ……… ……… return maze ; } }
Customizing Maze Factory class BombedWall extends Wall { } class RoomWithABomb extends Room { RoomWithABomb(int n) { super(n) ; } } class BombedMazeFactory extends MazeFactory { Wall newWall() { return new BombedWall() ; } Room newRoom(int n) { return new RoomWithABomb(n) ; } }
Singleton • Intent: Ensure that a class has only one instance, and provide a global point of access to it. • Use Singleton • There must be exactly one instance of a class, and it must be accessible to clients from a well known access point. • When this instance should be extensible by sub-classing
Singleton • Singleton • Define an Instance operation to access its unique instance. It must be a static method. • Must create its own unique instance.
Singleton - benefits • Controlled access to sole instance • Reduced namespace • May be sub-classed to refine operations • Can Permit a variable number of instances • More flexible than static methods
Singleton – Implementation • Ensure a unique instance class Singleton { private static Singleton inst = null ; public static Singleton getInstance() { if (inst==null) inst = new Singleton() ; return inst ; } protected Singleton() { } } • Subclassing the singleton class • Put instance() method in each subclass
Singleton – Maze example class MazeFactory { protected MazeFactory() { } private static MazeFactory inst = null ; public static MazeFactory getInst() { if (inst==null) inst = new MazeFactory() ; return inst ; } Maze newMaze() { return new Maze() ; } Room newRoom(int n) { return new Room(n) ; } Wall newWall() { return new Wall() ; } Door newDoor(Room r1, Room r2) { return new Door(r1,r2) ; } }
Singleton – Maze example public class MazeGame { public Maze createMaze() { Maze maze = MazeFactory.getInst().newMaze() ; Room room1 = MazeFactory.getInst().newRoom(1) ; Room room2 = MazeFactory.getInst().newRoom(2) ; Door door = MazeFactory.getInst().newDoor(room1,room2) ; maze.addRoom(room1) ; maze.addRoom(room2) ; room1.setSide(Maze.NORTH,new Wall()) ; room1.setSide(Maze.EAST ,door) ; room1.setSide(Maze.SOUTH,new Wall()) ; room1.setSide(Maze.WEST ,new Wall()) ; room2.setSide(Maze.NORTH,new Wall()) ; room2.setSide(Maze.EAST ,new Wall()) ; room2.setSide(Maze.SOUTH,new Wall()) ; room2.setSide(Maze.WEST ,door) ; return maze ; } }
Singleton – Alternative Maze Factory class MazeFactory { protected MazeFactory() { } private static final String name = "BOMBED" ; private static MazeFactory inst = null ; public static MazeFactory getInst() { if (inst==null) { if (name.equals("BOMBED")) inst = new BombedMazeFactory() ; else inst = new MazeFactory() ; } return inst ; } Maze newMaze() { return new Maze() ; } Room newRoom(int n) { return new Room(n) ; } Wall newWall() { return new Wall() ; } Door newDoor(Room r1, Room r2) { return new Door(r1,r2) ; } }