Download Factory Patterns: Factory Method and Abstract Factory and more Study notes Design in PDF only on Docsity!
Design Patterns In Java Bob Tarr
Factory Patterns:
Factory Method
and
Abstract Factory
Design Patterns In Java Factory Patterns 22 Bob Tarr
Factory Patterns Factory Patterns
l Factory patterns are examples of creational patterns
l Creational patterns abstract the object instantiation process.
They hide how objects are created and help make the overall
system independent of how its objects are created and composed.
l Class creational patterns focus on the use of inheritance to decide
the object to be instantiated
È Factory Method
l Object creational patterns focus on the delegation of the
instantiation to another object
È Abstract Factory
Design Patterns In Java Factory Patterns 33 Bob Tarr
Factory Patterns Factory Patterns
l All OO languages have an idiom for object creation. In Java this
idiom is the new operator. Creational patterns allow us to write
methods that create new objects without explicitly using the new
operator. This allows us to write methods that can instantiate
different objects and that can be extended to instantiate other
newly-developed objects, all without modifying the method's
code! (Quick! Name the principle involved here!)
Design Patterns In Java Factory Patterns 44 Bob Tarr
The Factory Method PatternThe Factory Method Pattern
l Intent
È Define an interface for creating an object, but let subclasses decide which
class to instantiate. Factory Method lets a class defer instantiation to
subclasses.
l Motivation
È Consider the following framework:
È The createDocument() method is a factory method.
Design Patterns In Java Factory Patterns 77 Bob Tarr
The Factory Method PatternThe Factory Method Pattern
l So what exactly does it mean when we say that "the Factory
Method Pattern lets subclasses decide which class to instantiate?"
È It means that Creator class is written without knowing what actual
ConcreteProduct class will be instantiated. The ConcreteProduct class
which is instantiated is determined solely by which ConcreteCreator
subclass is instantiated and used by the application.
È It does not mean that somehow the subclass decides at runtime which
ConreteProduct class to create
Design Patterns In Java Factory Patterns 88 Bob Tarr
Factory Method Example 1 Factory Method Example 1
l Clients can also use factory methods:
l The factory method in this case is createManipulator()
Design Patterns In Java Factory Patterns 99 Bob Tarr
Factory Method Example 1 (Continued)Factory Method Example 1 (Continued)
l Note that although the Client delegates the creation of a
ConcreteManipulator to a ConcreteFigure object, the focus of the
pattern is still on how a specific subclass of Figure creates one
particular type of Manipulator. So this is still the Factory Method
Pattern (a class creational pattern).
Design Patterns In Java Factory Patterns 1010 Bob Tarr
Factory Method Example 2 Factory Method Example 2
l Consider this maze game:
Design Patterns In Java Factory Patterns 1313 Bob Tarr
Factory Method Example 2 (Continued)Factory Method Example 2 (Continued)
l The problem with this createMaze() method is its inflexibility.
l What if we wanted to have enchanted mazes with
EnchantedRooms and EnchantedDoors? Or a secret agent maze
with DoorWithLock and WallWithHiddenDoor?
l What would we have to do with the createMaze() method? As it
stands now, we would have to make significant changes to it
because of the explicit instantiations using the new operator of the
objects that make up the maze. How can we redesign things to
make it easier for createMaze() to be able to create mazes with
new types of objects?
Design Patterns In Java Factory Patterns 1414 Bob Tarr
Factory Method Example 2 (Continued)Factory Method Example 2 (Continued)
l Let's add factory methods to the MazeGame class:
- MazeGame with a factory methods. */ public class MazeGame {
public Maze makeMaze() {return new Maze();}
public Room makeRoom(int n) {return new Room(n);}
public Wall makeWall() {return new Wall();}
public Door makeDoor(Room r1, Room r2) {return new Door(r1, r2);}
Design Patterns In Java Factory Patterns 1515 Bob Tarr
Factory Method Example 2 (Continued)Factory Method Example 2 (Continued)
public Maze createMaze() { Maze maze = makeMaze(); Room r1 = makeRoom(1); Room r2 = makeRoom(2); Door door = makeDoor(r1, r2); maze.addRoom(r1); maze.addRoom(r2); r1.setSide(MazeGame.North, makeWall()); r1.setSide(MazeGame.East, door); r1.setSide(MazeGame.South, makeWall()); r1.setSide(MazeGame.West, makeWall()); r2.setSide(MazeGame.North, makeWall()); r2.setSide(MazeGame.East, makeWall()); r2.setSide(MazeGame.South, makeWall()); r2.setSide(MazeGame.West, door); return maze; } }
Design Patterns In Java Factory Patterns 1616 Bob Tarr
Factory Method Example 2 (Continued)Factory Method Example 2 (Continued)
l We made createMaze() just slightly more complex, but a lot more
flexible!
l Consider this EnchantedMazeGame class:
public class EnchantedMazeGame extends MazeGame { public Room makeRoom(int n) {return new EnchantedRoom(n);} public Wall makeWall() {return new EnchantedWall();} public Door makeDoor(Room r1, Room r2) {return new EnchantedDoor(r1, r2);} }
l The createMaze() method of MazeGame is inherited by
EnchantedMazeGame and can be used to create regular mazes or
enchanted mazes without modification!
Design Patterns In Java Factory Patterns 1919 Bob Tarr
The Abstract Factory Pattern The Abstract Factory Pattern
l Intent
È Provide an interface for creating families of related or dependent objects
without specifying their concrete classes.
È The Abstract Factory pattern is very similar to the Factory Method pattern.
One difference between the two is that with the Abstract Factory pattern, a
class delegates the responsibility of object instantiation to another object
via composition whereas the Factory Method pattern uses inheritance and
relies on a subclass to handle the desired object instantiation.
È Actually, the delegated object frequently uses factory methods to perform
the instantiation!
Design Patterns In Java Factory Patterns 2020 Bob Tarr
The Abstract Factory Pattern The Abstract Factory Pattern
l Motivation
È A GUI toolkit that supports multiple look-and-feels:
Design Patterns In Java Factory Patterns 2121 Bob Tarr
The Abstract Factory Pattern The Abstract Factory Pattern
l Applicability
Use the Abstract Factory pattern in any of the following situations:
È A system should be independent of how its products are created,
composed, and represented
È A class can't anticipate the class of objects it must create
È A system must use just one of a set of families of products
È A family of related product objects is designed to be used together, and you
need to enforce this constraint
Design Patterns In Java Factory Patterns 2222 Bob Tarr
The Abstract Factory Pattern The Abstract Factory Pattern
l Structure
Design Patterns In Java Factory Patterns 2525 Bob Tarr
Abstract Factory Example 1 Abstract Factory Example 1
l Let's see how an Abstract Factory can be applied to the
MazeGame
l First, we'll write a MazeFactory class as follows:
// MazeFactory. public class MazeFactory { public Maze makeMaze() {return new Maze();} public Room makeRoom(int n) {return new Room(n);} public Wall makeWall() {return new Wall();} public Door makeDoor(Room r1, Room r2) { return new Door(r1, r2);} }
l Note that the MazeFactory class is just a collection of factory
methods!
l Also, note that MazeFactory acts as both an AbstractFactory and
a ConcreteFactory.
Design Patterns In Java Factory Patterns 2626 Bob Tarr
Abstract Factory Example 1 (Continued)Abstract Factory Example 1 (Continued)
l Now the createMaze() method of the MazeGame class takes a
MazeFactory reference as a parameter:
public class MazeGame {
public Maze createMaze(MazeFactory factory) { Maze maze = factory.makeMaze(); Room r1 = factory.makeRoom(1); Room r2 = factory.makeRoom(2); Door door = factory.makeDoor(r1, r2); maze.addRoom(r1); maze.addRoom(r2); r1.setSide(MazeGame.North, factory.makeWall()); r1.setSide(MazeGame.East, door);
Design Patterns In Java Factory Patterns 2727 Bob Tarr
Abstract Factory Example 1 (Continued)Abstract Factory Example 1 (Continued)
r1.setSide(MazeGame.South, factory.makeWall()); r1.setSide(MazeGame.West, factory.makeWall()); r2.setSide(MazeGame.North, factory.makeWall()); r2.setSide(MazeGame.East, factory.makeWall()); r2.setSide(MazeGame.South, factory.makeWall()); r2.setSide(MazeGame.West, door); return maze; }
}
l Note how createMaze() delegates the responsibility for creating
maze objects to the MazeFactory object
Design Patterns In Java Factory Patterns 2828 Bob Tarr
Abstract Factory Example 1 (Continued)Abstract Factory Example 1 (Continued)
l We can easily extend MazeFactory to create other factories:
public class EnchantedMazeFactory extends MazeFactory { public Room makeRoom(int n) {return new EnchantedRoom(n);} public Wall makeWall() {return new EnchantedWall();} public Door makeDoor(Room r1, Room r2) {return new EnchantedDoor(r1, r2);} }
l In this example, the correlations are:
È AbstractFactory => MazeFactory
È ConcreteFactory => EnchantedMazeFactory (MazeFactory is also a
ConcreteFactory)
È AbstractProduct => MapSite
È ConcreteProduct => Wall, Room, Door, EnchantedWall,
EnchantedRoom, EnchantedDoor
È Client => MazeGame
Design Patterns In Java Factory Patterns 3131 Bob Tarr
Abstract Factory Example 2 (Continued)Abstract Factory Example 2 (Continued)
l And here's the getDefaultToolkit() method in Toolkit:
public static synchronized Toolkit getDefaultToolkit() { if (toolkit == null) String nm = System.getProperty("awt.toolkit", "sun.awt.motif.MToolkit"); toolkit = (Toolkit)Class.forName(nm).newInstance(); } return toolkit; }
Design Patterns In Java Factory Patterns 3232 Bob Tarr
Abstract Factory Example 3 Abstract Factory Example 3
l Sockets are a very useful abstraction for communication over a
network
l The socket abstraction was originally developed at UC Berkeley
and is now in widespread use
l Java provides some very nice implementations of Berkeley
sockets in the Socket and ServerSocket classes in the java.net
package
l The Socket class actually delegates all the real socket
functionality to a contained SocketImpl object
l And the SocketImpl object is created by a SocketImplFactory
object contained in the Socket class
l Sounds like Abstract Factory with just one createProduct()
method
Design Patterns In Java Factory Patterns 3333 Bob Tarr
Abstract Factory Example 3 (Continued)Abstract Factory Example 3 (Continued)
l Here’s some code from the Socket class:
- A socket is an endpoint for communication between two
- machines. The actual work of the socket is performed by an
- instance of the SocketImpl class. An application, by changing
- the socket factory that creates the socket implementation,
- can configure itself to create sockets appropriate to the
- local firewall. */ public class Socket {
// The implementation of this Socket. SocketImpl impl;
// The factory for all client sockets. private static SocketImplFactory factory;
Design Patterns In Java Factory Patterns 3434 Bob Tarr
Abstract Factory Example 3 (Continued)Abstract Factory Example 3 (Continued)
- Sets the client socket implementation factory for the
- application. The factory can be specified only once.
- When an application creates a new client socket, the
- socket implementation factory's createSocketImpl method
- is called to create the actual socket implementation. */ public static synchronized void setSocketImplFactory(SocketImplFactory fac) throws IOException { if (factory != null) { throw new SocketException("factory already defined"); } factory = fac; }
Design Patterns In Java Factory Patterns 3737 Bob Tarr
The Abstract Factory Pattern The Abstract Factory Pattern
l Consequences
È Benefits
› Isolates clients from concrete implementation classes
› Makes exchanging product families easy, since a particular concrete factory
can support a complete family of products
› Enforces the use of products only from one family
È Liabilities
› Supporting new kinds of products requires changing the AbstractFactory
interface
l Implementation Issues
È How many instances of a particular concrete factory should there be?
› An application typically only needs a single instance of a particular concrete
factory
› Use the Singleton pattern for this purpose
Design Patterns In Java Factory Patterns 3838 Bob Tarr
The Abstract Factory Pattern The Abstract Factory Pattern
l Implementation Issues
È How can the factories create the products?
› Factory Methods
› Factories
È How can new products be added to the AbstractFactory interface?
› AbstractFactory defines a different method for the creation of each product it
can produce
› We could change the interface to support only a make(String kindOfProduct)
method
Design Patterns In Java Factory Patterns 3939 Bob Tarr
How Do Factories Create Products? How Do Factories Create Products?
l Method 1: Use Factory Methods
- WidgetFactory.
- This WidgetFactory is an abstract class.
- Concrete Products are created using the factory methods
- implemented by sublcasses. */ public abstract class WidgetFactory { public abstract Window createWindow(); public abstract Menu createScrollBar(); public abstract Button createButton(); }
Design Patterns In Java Factory Patterns 4040 Bob Tarr
How Do Factories Create Products? (Continued)How Do Factories Create Products? (Continued)
- MotifWidgetFactory.
- Implements the factory methods of its abstract superclass. */ public class MotifWidgetFactory extends WidgetFactory {
public Window createWindow() {return new MotifWindow();} public ScrollBar createScrollBar() { return new MotifScrollBar();} public Button createButton() {return new MotifButton();}
}