Title: Chapter 5 Creational Patterns: Factory Patterns
1Chapter 5 -Creational Patterns Factory Patterns
CIS 476/566 Software Architecture and Design
Patterns
- Dr. Brahim Medjahed
- brahim_at_umich.edu
2Outline
- Abstract Factory Pattern
- Factory Method Pattern
3Design Patterns in GoF The Big Picture
4What Are Creational Patterns?
- Creational Patterns
- Abstract the instantiation process
- Hide how objects are created
- Two categories
- Object creational patterns
- Focus on the delegation of the instantiation to
another object (e.g., Abstract Factory) - Class creational patterns
- Focus on the use of inheritance to decide the
object to be instantiated (e.g., Factory Method)
5Abstract Factory Pattern
6Abstract Factory Pattern - Intent
- Provide an Interface for creating families of
related or dependent objects without specifying
their concrete classes - Objects instantiated in a coordinated fashion
- The pattern ensures that the system always gets
the correct set of objects for the situation
7Families of objects
- Families may be defined according to any number
of reasons - Different operating systems (cross-platform
applications) - Different performance guidelines
- Different versions of applications
8Motivating Example
- Select device drivers (display and print)
according to the machine capacity
9Define Families based on a Unifying Concept
- Two Families
- Low-resolution family put low demands on the
system - LRDD and LRPD
- High-resolution family put high demands on the
system - HRDD and HRPD
- Families are not always exclusive
- Mid-resolution family for mid-range machines
- LRDD and HRDP
10Applicability
- A system should be independent of how its objects
(or product objects) are created, composed, and
represented - A system should be configured with one of
multiple families of objects - A family of related objects is designed to be
used together - You want to provide a class library of objects,
and you want to reveal just their interfaces, not
their implementations
11Solution 1 A Switch to Control Which Driver to
Use
Class ApControl public doDraw()
switch (Resolution) case LOW
// use LRDD case HIGH // use HRDD
public doPrint() switch (Resolution)
case LOW // use LRPD case
HIGH // use HRPD
12Solution 1 - Cons
- Unclear code
- Code for determining the driver to use are
intermixed with the code for using the driver - Tight coupling
- Adding a MIDDLE value requires changing the code
in two places (otherwise not related) - Weak cohesion
- Each method (doDraw and doPrint) has two
unrelated assignment select driver and create
shape
13Solution 2 Use Inheritance
- Use one abstract class Apcontrol
- Have two different concrete classes
LowResApControl and HighResApControl - LowResApControl and HighResApControl are derived
from Apcontrol - LowResApControl uses low-resolution drivers
- HighResApcontrol uses high-resolution drivers
14Solution 2 The Class Diagram
15Solution 2 - Cons
- Combinatorial explosion new concrete class for
each new family - New concrete class for (LRDP,HRDD)
- New concrete class for (HRDP, LRDD)
- Unclear meaning we specialized each class to a
particular special case
16Solution 3 Replace Switches With Abstraction
- Opportunity for abstraction
- LRDD and HRDD are both display drivers
- LRPD and HRPD are both print drivers
- Abstractions
- Display Drivers
- Print Drivers
17Drivers and their Abstractions
18ApControl Using Display and Print Drivers
- Code is simpler to understand ApControl uses a
DisplayDriver object or a PrintDriver object
without concerning itself about the drivers
resolution
19Code Fragment
Class ApControl public doDraw()
myDisplayDriver.draw() public doPrint()
myPrintDriver.print()
Question How do we create the appropriate objects?
20Creating Appropriate Objects
- Option 1 Have ApControl do it
- Maintenance problem new set of objects
- Unclear code intermixing creation code with
other - Option 2 delegate the creation of the
appropriate family of objects to another object - Call it the factory object (ResFactory in our
example)
21The Factory Object
- Decomposition by responsibility
- ResFactory has the responsibility for deciding
which objects are appropriate - ApControl has the responsibility for knowing how
to work with the appropriate objects - ApControl does not need to worry about whether a
low or high resolution driver is returned because
it uses both in the same way
22Sequence Diagram
23The ResFactory Abstract Class
- Define each factory for the same family of
objects as a concrete class - LowResFact and HighResFact are derived from the
ResFactory abstract class - The ResFactory abstract class has two methods
- Give me the display driver I should use
- Give me the print driver I should use
24The ResFactory Abstract Class (contd)
25Implementation of ResFactory- Code Fragments
- abstract class ResFactory
- abstract public DisplayDriver getDispDriver()
- abstract public PrintDriver getPrtDriver()
-
- class LowResFact extends ResFactory
- public DisplayDriver getDispDriver()
- return new LRDD()
-
- public PrintDriver getPrtDriver()
- return new LRPD()
-
-
26Implementation of ResFactory- Code Fragments
(contd)
- class HighResFact extends ResFactory
- public DisplayDriver getDispDriver()
- return new HRDD()
-
- public PrintDriver getPrtDriver()
- return new HRPD()
-
-
27Putting Things Together
28The Abstract Factory Structure
29Participants
- AbstractFactory
- Declares an interface for operations that create
abstract product objects - ConcreteFactory
- Implements the operations to create concrete
product objects - AbstractProduct
- Declares an interface for a type of product
object - ConcreteProduct
- Defines a product object to be created by the
corresponding concrete factory - Implements the AbstractProduct interface
- Client
- Uses only interfaces declared by AbstractFactory
and AbstractProduct classes
30Collaborations
- Normally a single instance of a ConcreteFactory
class is created at runtime. - This is an example where the Singleton Pattern
should be used - This concrete factory creates product objects
having a particular implementation. - To create different product objects, clients
should use a different concrete factory. - AbstractFactory defers creation of product
objects to its ConcreteFactory
31Consequences
- 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
32Exercise 1
- Suppose you have the task of building a user
interface framework that works on top of
MS-Windows, Mac OS. and Motif. It must work on
each platform with the platform's native look and
feel. You organize it by creating an abstract
class for each type of widget. We consider the
following three types text field, push button,
and list box. You need to write a concrete
subclass of each of those types for each
supported platform. To make this robust, you need
to ensure that the widget objects created are all
for the desired platform. - Question Give the UML class diagram for the
aforementioned situation
33Exercise 1 Class Diagram
34Exercise 2
- Suppose you have the task of building a user
interface framework that works on top of
MS-Windows and Mac OS. The only widget we
consider is Button. Clients should be able to
create an interface that contains a button. The
interface should diplay I am a Win Button and
I am a Mac Button in the case of MS-Windows and
Mac OS platforms respectively - Question 1 Give the UML class diagram
- Question 2 Implement the class diagram
- For simplicity, the type of OS is passed as a
parameter to the factory
35Exercise 2 Class diagram
36Exercise 2 - Implementation
- Public abstract class Button
-
- Public abstract void display()
-
- Public WinButton extends Button
-
- Public void display()
-
- System.out.println(Im a Win Button)
-
-
- Public MacButton extends Button
-
- Public void display()
-
- System.out.println(Im a Mac Button)
-
-
37Exercise 2 Implementation (contd)
- Public abstract class GUIFact
-
- Public abstract Button CreateButton()
-
-
- Public static GUIFact GetFactory(int OSType)
- // 1Windows 2 Mac
- If (OSType1) return( new WinFact())
- Else return (new MacFact())
-
-
38Exercise 2 Implementation (contd)
- Public WinFact extends GUIFact
-
- Public Button createButton()
-
- Return (New winButton())
-
-
- Public MacFact extends GUIFact
-
- Public Button createButton()
-
- Return (New MacButton())
-
-
39Exercise 2 Implementation (contd)
- Public class client
- Public static void main (string args)
- System.in.readln(OSType)
- GUIFact myfactory GUIFact.getFactory(OSType)
- Button myButton myfactory.createButton()
- myButton.display()
40The Factory Method Pattern
41Factory Method Pattern - Intent
- Defines an interface for creating an object, but
let subclasses decide which class to instantiate.
- Factory Method lets a class defer instantiation
to subclasses.
42Motivation
- Document and Application are abstract classes
- Clients subclass them to realize their
application-specific implementation
43Motivation (contd)
- The particular document subclass to
instantiateis application-specific
44Motivation (contd)
- Problem The client must instantiate classes but
it only knows about abstract classes, which it
cannot instantiate
- Solution The factory method
- CreateDocument() is a factory method
45The CreateDocument Factory Method
- Responsible for manufacturing objects
- Redefines an abstract CreateDocument() method in
the abstract class Application - Once an Application subclass is instantiated, it
can then instantiate application-specific
documents
46Applicability
- A class cannot anticipate the class of objects it
must create - A class wants its subclasses to specify the
objects it creates
47The Factory Method Structure
48Participants
- Product
- Defines the interface for the type of objects the
factory method creates - ConcreteProduct
- Implements the Product interface
- Creator
- Declares the factory method, which returns an
object of type Product - ConcreteCreator
- Overrides the factory method to return an
instance of a ConcreteProduct
49Collaborations
- Creator relies on its subclasses to implement the
factory method so that it returns an instance of
the appropriate ConcreteProduct - 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.
50Example
- Create two types of Documents Resume and Report
(the concrete creators) - Each Document consists of Pages (Page is the
Product) - Factory Method CreatePages()
- A Resume has the following pages (concrete
products) - SkillsPage
- EducationPage
- ExperiencePage
- A Report has the following pages (concrete
products) - SummaryPage
- IntroductionPage
- ResultsPage
- ConclusionPage
51Example Class Diagram
52Example - Implementation
-   // MainApp test application   class
MainApp      static void Main()          //
Note constructors call Factory Method
      Document documents new
Document2Â Â Â Â Â Â documents0 new
Resume()Â Â Â Â Â Â documents1 new
Report()Â Â Â Â Â Â // Display document pages
      foreach (Document document in
documents)Â Â Â Â Â Â Â Â Â Â Â Â Â Â Console.WriteLine("\n"
document.GetDocName() "--")Â Â Â Â Â Â Â Â foreach
(Page page in document.Pages)Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
  Console.WriteLine(" " page.GetPageName()) Â
                 Â
53Example Implementation (contd)
- Â Â // "Product" Â Â
- abstract class Page  Â
- public abstract GetPageName()
- Â Â
54Example Implementation (contd)
- // Concrete Products for resume
- class SkillsPage Page  Â
- public GetPageName()
- Console.WriteLine(SkillsPage)
- class EducationPage Page  Â
- public GetPageName()
- Console.WriteLine(EduationPage)
- class ExperiencePage Page  Â
- public GetPageName()
- Console.WriteLine(ExperiencePage)
   Â
55Example Implementation (contd)
- // Concrete Products for report
- class SummaryPage Page  Â
- public GetPageName()
- Console.WriteLine(SummaryPage)
- class IntroductionPage Page  Â
- public GetPageName()
- Console.WriteLine(IntroductionPage)
- class ResultsPage Page  Â
- public GetPageName()
- Console.WriteLine(ResultsPage)
- class ConclusionPage Page  Â
- public GetPageName()
- Console.WriteLine(ConclusionPage)
       Â
56Example Implementation (contd)
- Â Â // Abstract Creator
- abstract class Document      public ArrayList
Pages new ArrayList() - // Constructor calls abstract Factory method
    public Document()          this.CreatePage
s()    public abstract GetDocName() -    // Factory Method    public abstract void
CreatePages()Â Â
57Example Implementation (contd)
-   // First Concrete Creator   class Resume
Document      - // Factory Method implementation public
override void CreatePages()Â Â Â Â Â Â Â Â Â Â Pages.Add(
new SkillsPage())Â Â Â Â Â Â Pages.Add(new
EducationPage())Â Â Â Â Â Â Pages.Add(new
ExperiencePage())Â Â Â Â -
- public overide void GetDocName()
- Console.WriteLine(Resume)
-
58Example Implementation (contd)
-   // Second Concrete Creator   class Report
Document      - // Factory Method implementation   Â
- Â public override void CreatePages()Â Â Â Â Â Â Â Â Â
 Pages.Add(new SummaryPage()) - Pages.Add(new IntroductionPage())   Â
  Pages.Add(new ResultsPage())      Pages.Add(ne
w ConclusionPage())Â Â Â Â - public overide void GetDocName()
- Console.WriteLine(Report)
- Â Â
59Example - Output
60Exercise 3
- Let us consider Exercise 2 (slide 34) with the
factory method. - Question 1 Give the UML class diagram
- Question 2 Implement the class diagram
61Exercise 3 UML Diagam
62Exercise 3 Implementation
- // Abstract Creator
- abstract class GUIÂ Â Â Â Â Â
- // Constructor calls abstract Factory method
    public GUI()          this.CreateButton()
    -    // Factory Method    public abstract void
CreateButton()Â Â
63Exercise 3 Implementation
- // First Concrete Creator   class WinGUI
GUIÂ Â Â Â Â Â - // Factory Method implementation public
override void CreateButton()Â Â Â Â Â Â Â Â Â Â new
WinButton()Â Â Â Â -
-
64Exercise 3 Implementation
- // First Concrete Creator   class MacGUI
GUIÂ Â Â Â Â Â - // Factory Method implementation public
override void CreateButton()Â Â Â Â Â Â Â Â Â Â new
MacButton()Â Â Â Â -
-
65Exercise 3 Implementation
- // "Product"  abstract class Button  Â
- // ConcreteProduct 1
- class WinButton Button Â
- Public WinButton()
- System.out.println(Im a Win Button)
-
- // ConcreteProduct 2
- class MacButton Button Â
- Public MacButton()
- System.out.println(Im a Mac Button)
-
66- Public class client
- Public static void main (string args)
- System.in.readln(OSType)
- If (OSType1)
- GUI myGUI new WinGUI()
- Else GUI myGUI new MacGUI()
-