Software Design COSC 4353/6353 D R. R A J S I N G H
Creational Design Patterns What are creational design patterns? Types Examples Structure Effects
Creational Patterns Design patterns that deal with object creation mechanisms Create objects suitable to the situation Abstracts instantiation process Makes system independent of how its objects are Created Composed Represented Details hiding
Why Creational Patterns? The basic form of object creation could result in design problems added complexity to the design Creational design patterns solve this problem by controlling the object creation They increase system's flexibility in terms of what, who, how, and when of object creation
Categories Two categories: Object creational patterns deals with object creation defers part of its object creation to another object Class creational patterns deals with class instantiation defers its object creation to subclasses
When to Use? Consider applying creational patterns when: A system should be independent of how its objects are created. A set of related objects is designed to be used together. Hiding the implementations of a class library of product, revealing only their interfaces. Constructing different representation of independent complex objects. A class want its subclass to implement the object it creates. The class instantiations are specified at run-time. There must be a single instance and client can access this instance at all times. Instance should be extensible without being modified.
Structure Diagram shows the structure most CPs should have in common. Different creational patterns require additional and different participated classes. Participants: Creator: Declares object interface. Returns object. ConcreteCreator: Implements object's interface.
Most Commonly Used CPs Abstract factory Factory Builder Prototype Singleton
Abstract Factory Pattern Provides an interface for creating families of related or dependent objects without specifying their concrete classes
Example What happens when I want to create a Computer of Model B with Model B memory, CPU and Modem?
Solution: Using Abstract Factory
Solution: Using Abstract Factory Type of Computer gets created depends on which implementation of ComputerFactory is handling the call.
Structure
Effects of Abstract Factory Isolates concrete classes Makes exchanging product families easy Promotes consistency amongst products Supporting new kinds of products is difficult
Factory Method Define an interface for creating an object Let subclasses decide which class to instantiate Also known as virtual constructor Very common in toolkits and frameworks where library code needs to create objects of types that may be subclassed by applications using the framework
Example We want to develop a framework of a Computer that has memory, CPU, and Modem. The actual memory, CPU, and Modem that is used depends on the actual computer model being used. We want to provide a configure function that will configure any computer with appropriate parts. This function must be written such that it does not depend on the specifics of a computer model or the components.
Example using Factory Method
When to Use? The creation of an object makes reuse impossible without significant duplication of code. The creation of an object requires access to information or resources that should not be contained within the composing class. The lifetime management of the generated objects must be centralized to ensure a consistent behavior within the application.
Structure
Effects of using Factory Method Provides hooks for subclasses Connects parallel class hierarchies Refactoring an existing class to use factories breaks existing clients Pattern heavily relies on using private constructor meaning it cannot be extended unless constructor is visible. Subclass must provide its own re-implementation of all factory methods
Factory Method Vs. Other Patterns Abstract Factory is often implemented with Factory Method Factory Methods are usually called within Template Methods Prototypes don t require subclassing the creator. However, they often require initialization of Product class. Factory method doesn t require such an operation. Increased number of subclasses Intention is to increase polymorphism
Builder Pattern The intention of the builder pattern is to find a solution to the telescoping constructor anti-pattern The telescoping constructor anti-pattern occurs when the increase of object constructor parameter combination leads to an exponential list of constructors. The builder pattern uses another object, a builder, that receives each initialization parameter step by step and then returns the resulting constructed object at once.
Example We have a Car class. The problem is that a car has many options. The combination of each option would lead to a huge list of constructors for this class. So we will create a builder class, CarBuilder. We will send to the CarBuilder each car option step by step and then construct the final car with the right options:
Example class Car is Can have GPS, trip computer and a various number of seats. Can be a city car, a sport car or a cabriolet. class CarBuilder is method getresult() is output: a Car with the right options Construct and return the car. method setseaters(number) is input: the number of seaters the car may have. Tell the builder the number of seaters. method setcitycar() is Make the builder remember that the car is a city car.
Example method setcabriolet() is Make the builder remember that the car is a cabriolet. method setsportcar() is Make the builder remember that the car is a sport car. method settripcomputer() is Make the builder remember that the car has a trip computer. method unsettripcomputer() is Make the builder remember that the car does not have a trip computer. method setgps() is Make the builder remember that the car has a global positioning system. method unsetgps() is Make the builder remember that the car does not have a global positioning system.
Example Construct a CarBuilder called carbuilder carbuilder.setseaters(2) carbuilder.setsportcar() carbuilder.settripcomputer() carbuilder.unsetgps() car := carbuilder.getresult()
Structure
When to Use? Algorithms for creating complex object should be independent of the parts that make up the object and how they are assembled Construction process must allow different representation for the object that is constructed
Effects of Builder Pattern Lets product s internal representation to vary Isolates code for construction and representation Gives finer control over construction process
Builder Vs. Others Builder takes care of complete creating of a complex product step by step Abstract Factory emphasizes on creation of families of products focusing one components at a time Builder builds a composite
Prototype Pattern Specify the kinds of objects to create using a prototypical instance. Create new objects by cloning prototype.
Example We want to write an occurrence browser class for a text. This class lists the occurrences of a word in a text. Such an object is expensive to create as the locations of the occurrences need an expensive process to find. So, to duplicate such an object, we use the prototype pattern:
Example class WordOccurrences is field occurrences is The list of the index of each occurrence of the word in the text. constructor WordOccurrences(text, word) is input: the text in which the occurrences have to be found input: the word that should appear in the text Empty the occurrences list for each textindex in text ismatching := true for each wordindex in word if the current word character does not match the current text character then ismatching := false if ismatching is true then Add the current textindex into the occurrences list
Example method getoneoccurrenceindex(n) is input: a number to point on the nth occurrence. output: the index of the nth occurrence. Return the nth item of the occurrences field if any method clone() is output: a WordOccurrences object containing the same data. Call clone() on the super class. On the returned object, set the occurrences field with the value of the local occurrences field. Return the cloned object.
Example text := A pattern can lead to another pattern by examining the current pattern." word := "pattern" searchengine := new WordOccurrences(text, word) anothersearchengine := searchengine.clone()
Structure
When to Use? System should be independent of how its products are created, composed, and represented Classes to instantiate are specified at runtime You want to avoid creating class hierarchy of factories that parallel the class hierarchy of products.
Effects of Prototype Pattern Adding and removing products at runtime Specifying new objects by varying values and structure Reduced subclassing Configuring application with classes dynamically Each subclass must implement clone operation
Prototype Vs. Others Abstract Factory is competing pattern, however, may work together as well Composite and decorator benefit form Prototype
Singleton Pattern Ensure a class has only one instance and provide a global point to access it The concept is sometimes generalized to systems that operate more efficiently when only one object exists The term comes from the mathematical concept of a singleton
Example The singleton pattern must be carefully constructed in multi-threaded applications. If two threads are to execute the creation method at the same time when a singleton does not yet exist, they both must check for an instance of the singleton and then only one should create the new one
Example public class SingletonDemo { private static volatile SingletonDemo instance = null; private SingletonDemo() { } public static SingletonDemo getinstance() { if (instance == null) { synchronized (SingletonDemo.class){ if (instance == null) { instance = new SingletonDemo (); } } } return instance; } }
Structure
When to Use? There must be exactly one instance of a class, and it must be accessible to clients from a well known access point. When the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying their code.
Effects of Singleton Pattern Controlled access to sole instance Reduced name space Permits refinement of operations and representation Permits a variable number of instances More flexible than class operator
Singleton Vs. Others Several patterns are implemented using Singleton. AbstractFactory needs a singleton pattern for single instance of the factory. Facade Objects are often Singletons because only one Facade object is required. State objects are often Singletons. Singletons are often preferred to global variables because: They do not pollute the global name space with unnecessary variables. They permit lazy allocation and initialization, whereas global variables in many languages will always consume resources.