[go: up one dir, main page]

0% found this document useful (0 votes)
49 views51 pages

Lecture 3 Creational Patterns Complete

The document discusses several creational design patterns including Abstract Factory, Builder, Factory Method, Prototype and Singleton. It provides descriptions of what each pattern is used for, including Abstract Factory being used to create families of related objects without specifying their concrete classes, and Builder being used to separate object construction from representation. Examples are given of how each pattern could be applied.

Uploaded by

Umair Athar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
49 views51 pages

Lecture 3 Creational Patterns Complete

The document discusses several creational design patterns including Abstract Factory, Builder, Factory Method, Prototype and Singleton. It provides descriptions of what each pattern is used for, including Abstract Factory being used to create families of related objects without specifying their concrete classes, and Builder being used to separate object construction from representation. Examples are given of how each pattern could be applied.

Uploaded by

Umair Athar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 51

Creational Patterns

Abstract Factory and Builder


Factory, Prototype and Singleton
Purpose
• Creational design patterns are design patterns
that deal with object creation mechanisms,
trying to create objects in a manner suitable to
the situation.
• The basic form of object creation could result in
design problems or added complexity to the
design. Creational design patterns solve this
problem by somehow controlling this
object creation.
Creational Patterns
• Abstract Factory
Creates an instance of several families of classes
• Builder
Separates object construction from
its representation
• Factory Method
Creates an instance of several derived classes
• Prototype
A fully initialized instance to be copied or cloned
• Singleton
A class of which only a single instance can exist
Intent (Abstract Factory)
• Provide an interface for creating families of
related or dependent objects without specifying
their concrete classes.
• A hierarchy that encapsulates: many possible
“platforms”, and the construction of a suite
of “products”.
• The new operator considered harmful.
Problem
• If an application is to be portable, it needs to
encapsulate platform dependencies. These
“platforms” might include: windowing system,
operating system, database, etc. Too often, this
encapsulatation is not engineered in advance,
and lots of #ifdef case statements with options
for all currently supported platforms begin to
procreate like rabbits throughout the code.
Discussion
• Provide a level of indirection that abstracts the
creation of families of related or dependent objects
without directly specifying their concrete classes.
• The “factory” object has the responsibility for
providing creation services for the entire platform
family. Clients never create platform objects directly,
they ask the factory to do that for them.
• This mechanism makes exchanging product families
easy because the specific class of the factory object
appears only once in the application - where it is
instantiated. The application can wholesale replace
the entire family of products simply by instantiating
a different concrete instance of the abstract factory.
Structure
• The Abstract Factory defines a Factory Method
per product. Each Factory Method encapsulates
the new operator and the concrete, platform-
specific, product classes. Each “platform” is
then modeled with a Factory derived class.
Explanation
• In a scenario where we have UI creational activities for textboxes and
buttons through their own centralized factory classes
• ‘ClsFactoryButton’
• ‘ClsFactoryText’.

• Both these classes inherit from common interface ‘InterfaceRender’.


• Both the factories ‘ClsFactoryButton’ and ‘ClsFactoryText’ inherits
from the common factory ‘ClsAbstractFactory’.

• For object creation it uses the abstract factory ( ClsAbstractFactory )


and for calling the concrete class implementation it calls the methods
via the interface ‘InterfaceRender’. So the ‘ClsAbstractFactory’ class
provides a common interface for both factories ‘ClsFactoryButton’
and ‘ClsFactoryText’.
Example
• The purpose of the Abstract Factory is to provide an interface
for creating families of related objects, without specifying
concrete classes.

• This pattern is found in the sheet metal stamping equipment


used in the manufacture of Japanese automobiles. The
stamping equipment is an Abstract Factory which creates auto
body parts.

• The same machinery is used to stamp right hand doors, left


hand doors, right front fenders, left front fenders, hoods, etc.
for different models of cars. Through the use of rollers to
change the stamping dies, the concrete classes produced by
the machinery can be changed within three minutes.
Checklist
• Decide if “platform independence” and creation
services are the current source of pain.
• Map out a matrix of “platforms” versus “products”.
• Define a factory interface that consists of a factory
method per product.
• Define a factory derived class for each platform that
encapsulates all references to the new operator.
• The client should retire all references to new, and
use the factory methods to create the
product objects.
Example
• If you have :
▫ class Foo implements DoSomething {...}
▫ class Bar implements DoSomething {...}
obj = new Foo();
obj.doSomething();
• Everywhere in your code, once you want to change all instances of Foo to use
instances of Bar, are you really going to do search/replace ?
• If you have :
▫ obj = DoSomethingFactory.create();
▫ obj.doSomething();
Inside the DoSomethingFactory, you can return any object you want that
implements the DoSomething interface.
• By using a Factory, you have the control over all the objects that are created
by it.
• If you decide to change the way the Factory creates objects, the changes take
effect immediately in the code that uses the Factory.
Builder Design Pattern
Intent
• Separate the construction of a complex object
from its representation so that the same
construction process can create
different representations.
• Parse a complex representation, create one of
several targets.
Problem
• An application needs to create the elements of a
complex aggregate. The specification for the
aggregate exists on secondary storage and one
of many representations needs to be built in
primary storage.
Concepts
• Builder Abstract interface for creating objects
(product).
• Concrete Builder Provides implementation for
Builder. It is an object able to construct other
objects. Constructs and assembles parts to build the
objects.
• Director The Director class is responsible for
managing the correct sequence of object creation. It
receives a Concrete Builder as a parameter and
executes the necessary operations on it.
• Product The final object that will be created by the
Director using Builder.
Discussion
• Separate the algorithm for interpreting (i.e. reading and parsing) a
stored persistence mechanism (e.g. RTF files) from the algorithm for
building and representing one of many target products (e.g. ASCII,
TeX, text widget). The focus/distinction is on creating
complex aggregates.

• The “director” invokes “builder” services as it interprets the external


format. The “builder” creates part of the complex object each time it
is called and maintains all intermediate state. When the product is
finished, the client retrieves the result from the “builder”.

• Affords finer control over the construction process. Unlike creational


patterns that construct products in one shot, the Builder pattern
constructs the product step by step under the control of
the “director”.
Structure
• The Reader encapsulates the parsing of the
common input. The Builder hierarchy makes
possible the polymorphic creation of many
peculiar representations or targets
Example
• The Builder pattern separates the construction of a complex object
from its representation so that the same construction process can
create different representations.

• This pattern is used by fast food restaurants to construct children’s


meals. Children’s meals typically consist of a main item, a side item,
a drink, and a toy (e.g., a hamburger, fries, Coke, and toy dinosaur).

• Note that there can be variation in the content of the children’s meal,
but the construction process is the same. Whether a customer orders
a hamburger, cheeseburger, or chicken, the process is the same. The
employee at the counter directs the crew to assemble a main item,
side item, and toy. These items are then placed in a bag. The drink is
placed in a cup and remains outside of the bag. This same process is
used at competing restaurants.
Checklist
• Decide if a common input and many possible
representations (or outputs) is the problem at hand.
• Encapsulate the parsing of the common input in a
Reader class.
• Design a standard protocol for creating all possible
output representations. Capture the steps of this
protocol in a Builder interface.
• Define a Builder derived class for each
target representation.
• The client creates a Reader object and a Builder object,
and registers the latter with the former.
• The client asks the Reader to “construct”.
• The client asks the Builder to return the result.
Factory Pattern
• Factory patterns are examples of creational patterns
▫ 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.
▫ Class creational patterns focus on the use of
inheritance to decide the object to be instantiated
⚫ Factory Method
▫ Object creational patterns focus on the delegation of
the instantiation to another object
⚫ Abstract Factory
Difference
• 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.
Contd..
• If there is only one creator, it specifies an
abstract factory method, allowing its subclasses
to choose the concrete product to instantiate.

However, if there are multiple creators in the


application, which want to create these products,
we may end up duplicating these factory
methods in all of them.
Ways to use Factory Method
• Static Factories

▫ The factory( ) takes an argument that allows it to determine what type of Shape to create;
it happens to be a String in this case but it could be any set of data. The factory( ) is now
the only other code in the system that needs to be changed when a new type of Shape is
added (the initialization data for the objects will presumably come from somewhere outside
the system, and not be a hard-coded array as in the above example).
▫ The static factory( ) method in the previous example forces all the creation operations to
be focused in one spot, so that’s the only place you need to change the code. This is
certainly a reasonable solution, as it throws a box around the process of creating objects.

• Polymorphic factories

▫ However, the reason for the Factory Method pattern is so that different types of factories
can be sub classed from the basic factory (the above design is mentioned as a special case).
Example
• Now the factory method appears in its own class, ShapeFactory, as
the create( ) method. This is a protected method which means it
cannot be called directly, but it can be overridden.
• The subclasses of Shape must each create their own subclasses of
ShapeFactory and override the create( ) method to create an
object of their own type. The actual creation of shapes is performed
by calling ShapeFactory.createShape( ), which is a static method
that uses the Map in ShapeFactory to find the appropriate factory
object based on an identifier that you pass it.
• The factory is immediately used to create the shape object, but you
could imagine a more complex problem where the appropriate
factory object is returned and then used by the caller to create an
object in a more sophisticated way. However, it seems that much of
the time you don’t need the intricacies of the polymorphic factory
method, and a single static method in the base class will work fine.
Abstract Factory
• The Abstract Factory pattern looks like the
factory objects we’ve seen previously, with not
one but several factory methods. Each of the
factory methods creates a different kind of
object.
Prototype Pattern
• The prototype means making a clone. This implies
cloning of an object to avoid creation.
• If the cost of creating a new object is large and
creation is resource intensive, we clone the object.
• We use the interface Cloneable and call its method
clone() to clone the object.
• In Case of a plant cell.
▫ cloning involves making a copy of the original one.
▫ Here, we break the cell in two and make two copies
and the original one does not exist.
▫ Let’s take a class Plant Cell having a method split().
The plant cell will implement the interface Cloneable.
Discussion

• Declare an abstract base class that specifies a pure


virtual “clone” method, and, maintains a dictionary
of all “cloneable” concrete derived classes. Any class
that needs a “polymorphic constructor”
• capability: derives itself from the abstract base class,
registers its prototypical instance, and implements
the clone() operation.
• The client then, instead of writing code that invokes
the “new” operator on a hard-wired class name,
calls a “clone” operation on the abstract base class,
supplying a string or enumerated data type that
designates the particular concrete derived
class desired.
Structure

• The Factory knows how to find the correct


Prototype, and each Product knows how to
spawn new instances of itself.
Role

• The Prototype pattern creates new objects by


cloning one of a few stored prototypes. The
Prototype pattern has two advantages:
▫ it speeds up the instantiation of very large,
dynamically loaded classes (when copying objects
is faster),
▫ and it keeps a record of identifiable parts of a
large data structure that can be copied without
knowing the subclass from which they were
created.
Design
• Objects are usually instantiated from classes
that are part of the program. The Prototype
pattern presents an alternative route by creating
objects from existing prototypes.
Contd…
• The copies, or clones, are objects in their own right, and the
intention of the pattern is that their state can be altered at will
without affecting the prototype. During the run of the program
new prototypes can be added, either from new classes or from
variations on existing prototypes. Although there are other
designs, the most flexible is to keep a prototype manager that
maintains an indexed list of prototypes that can be cloned.
The main players in the pattern are:
▫ IPrototype Defines the interface that says prototypes must be
cloneable
▫ Prototype A class with cloning capabilities
▫ PrototypeManager Maintains a list of clone types and their keys
▫ Client Adds prototypes to the list and requests clones
Benefits
• The classes to instantiate are specified at run
time, for example, by dynamic loading.
• To avoid building a class hierarchy of factories
that parallels the class hierarchy of products.
• When instances of a class can have one of only a
few different combinations of state.
Singleton
• In computer engineering, the singleton pattern is a
design pattern used to implement the mathematical
concept of a singleton, by restricting the
instantiation of a class to one object.
• This is useful when exactly one object is needed to
coordinate actions across the system.
• The concept is sometimes generalized to systems
that operate more efficiently when only one object
exists, or that restrict the instantiation to a certain
number of objects (e.g. five)
Intent
• Intent
• Ensure a class has only one instance, and
provide a global point of access to it.
• Encapsulated “just-in-time initialization” or
“initialization on first use”.
• Problem
• Application needs one, and only one, instance of
an object. Additionally, lazy initialization and
global access are necessary.
Discussion
• Make the class of the single instance object
responsible for creation, initialization, access, and
enforcement. Declare the instance as a private static
data member. Provide a public static member
function that encapsulates all initialization code,
and provides access to the instance.
• The client calls the accessor function (using the
class name and scope resolution operator) whenever
a reference to the single instance is required.
Example
• #include <iostream>
• using namespace std;
• int n = 12; // A global variable
• int main()
• {
• int n = 13; // A local variable
• cout << ::n << endl; // Print the global variable:
12
• cout << n << endl; // Print the local variable: 13
Structure
• Make the class of the single instance responsible
for access and “initialization on first use”. The
single instance is a private static attribute. The
accessor function is a public static method.
Example
• The office of the President of the United States is a
Singleton. The United States Constitution specifies
the means by which a president is elected, limits the
term of office, and defines the order of succession.
As a result, there can be at most one active
president at any given time. Regardless of the
personal identity of the active president, the title,
“The President of the United States” is a global
point of access that identifies the person in
the office.

Check list

• Define a private static attribute in the “single


instance” class.
• Define a public static accessor function in
the class.
• Do “lazy initialization” (creation on first use) in
the accessor function.
• Define all constructors to be protected or
private.
• Clients may only use the accessor function to
manipulate the Singleton.

You might also like