design patterns sem 2 mca final pdf
design patterns sem 2 mca final pdf
Creational pattern
Abstract Factory
Creational pattern
The goal of the Abstract Factory design pattern is to form a group of classes with
shared functionalities, better known as families, created by a Factory. This pattern
is especially useful when we need to implement certain class families to solve a
problem, however, we may need to add parallel implementations of the same
classes to solve the same problem with a different approach.
The structure of Abstract Factory may look quite convoluted since it has many
components which seem to intertwine with each other. To better explain how this
pattern works, let's review its components one by one:
Client: It represents the actor or event which triggers the execution of the pattern.
AbstractProduct (A, B): Interfaces for defining the object structure of each family.
ConcreteProduct (A, B): Classes that inherit their properties from AbstractProduct for
implementing entire families of concrete objects.
ConcreteFactory: They represent the concrete factories that will create instances of all the
classes of the family. This class must have a method for creating each and every one of
the classes of the family.
AbstractFactory: They define the structure of the families. They must provide a method for
each and every one of the classes of the family.
Singleton
Creational pattern
The Singleton design pattern receives this name because it can only have a single
instance of a specific class for the entire application; this is achieved by preventing
the creation of multiple instances of the same class, as it typically happens with the
new operator, and imposing a private constructor and a static method to get that
instance.
Google Translator is an example of the interpreter design pattern where the input can be in any language and
we get the output in another language.
These are the components included in this pattern:
Real-world example
This is a pretty simple but very useful pattern, which allows us to create a complex
object from simpler ones. It is very common to find ourselves in situations where
we need to manually create complex objects over and over again, which lead us to
assign properties to each and every one of them, and if such objects have to be
built from some other objects, then we need to create those first in order to assign
them to the main one we’re building. It is a long and tedious process, especially
when it needs to be done frequently.
PROTOTYPE
Creational pattern
The Prototype pattern functionality is based on object cloning. New objects are
created from a pool of previously created and stored prototypes. This pattern is
especially useful when we need to create objects from existing ones or for creating
very large structures of objects. This pattern also helps us hide the strategy we
used for cloning objects from the user.
The components included in this pattern are:
Real-world example
By implementing the Prototype design pattern, we are going to clone an entire list
of products in order to create others from it. How many times have we seen
companies working with more than one price list, which must be created from
scratch and then filled up with the same products from the original? Wouldn't it be
better to use a price list as a template for creating new lists with different
discounts?
Object Pool
Creational pattern
This pattern is widely used for working with large numbers of computationally
expensive objects. This pattern is advantageous for those scenarios where our
program needs these kinds of objects for a short time to discard them afterwards.
This pattern allows us to reutilize objects to keep us from having to create them
each time our application requires them, by storing previously created objects in
order to be used later.
The components included in this pattern are:
IObjectPool: Interface which defines the basic structure of an Object Pool, it has the get
and release methods which will be used for getting and releasing objects, respectively.
AbstractObjectPool: Abstract class which defines the default behavior of an Object Pool,
this class can be used as a basis for creating a ConcreteObjectPool more quickly.
ConcreteObjectPool: It is the complete, and ready-to-be-used, implementation of an
Object Pool.
IPoolableObject: Interface which should implement all the objects we want to manage
through ObjectPool. With this interface we can define the basic structure all objects should
have.
ConcretePoolableObject: These are the real objects to be managed by ObjectPool, they
should inherit from IPoolableObject.
IObjectFactory: Interface which will define the structure of the ConcretePoolableObject
factory.
ConcreteObjectFactory: Concrete factory which implements IObjectFactory for the
creation of a ConcretePoolableObject.
1. The client sends a request for an object to ConcreteObjectPool .
2. ConcreteObjectPool checks if the required object is available, otherwise it will send the request for
the creation of a new object to ConcreteObjectFactory.
3. ConcreteObjectFactory creates a new object whose type is ConcretePoolableObject.
4. ConcreteObjectPool returns the object to the client.
5. The client uses the object.
6. The client returns the object to ConcreteObjectPool.
Real-world example
By implementing the Object Pool design pattern, we are going to develop a multi-
threaded application, which has to carry out many tasks simultaneously. The
Object Pool will control how many processes can be executed at the same time, by
setting a maximum limit in order to avoid running out of resources and to maintain
an even performance throughout the execution, keeping the rest of the processes
in a queue to be executed whenever it's allowed.
Adapter
Structural pattern
Real-world example
By implementing the Adapter design pattern, we are going to create an adapter for
interacting homogeneously with two Bank APIs, both of which allow us to approve
personal loans. However, even though these APIs work similarly, they have
different interfaces, which means that we need to set separate implementations in
order to process the loans through each bank. With this pattern, we will create an
adapter for hiding the intricacies of each API implementation, by showing only a
single interface, compatible with both APIs.
Bridge
Structural pattern
The Bridge design pattern is used for decoupling an abstraction from its
implementation, the purpose is that each one can be modified separately without
affecting the other; in other words, an abstraction gets decoupled from its
implementation so they can vary independently.
The Bridge pattern is mostly used when we have two related pieces of software
and there’s a high probability that modifying one of them can lead to have the other
modified too. What Bridge proposes to solve this problem is creating a class
structure based on aggregation, which includes a bridge class for decoupling the
class we want to use from the client, so the latter can’t be aware of the former, in a
way that one can change without affecting the other.
Real-world example
Real-world example
Decorator
Structural pattern
Facade
Structural pattern
The Facade pattern has the particularity of hiding the complexity in interacting with
a group of subsystems by providing a high level interface, which is in charge of
establishing communication with all the subsystems. Using a facade is a good
strategy for interacting with multiple subsystems in order to execute a concrete
action, because we would need a technical and operational knowledge on each of
them to be aware of which subsystem we need to run and in which order, and that
can get too complicated when working with an overgrown system.
In the illustration, we can see the components included in the Facade pattern,
which are explained as follows:
Real-world example
By implementing the Facade design pattern, we are going to develop a system for
processing online payments, which would need to interact with different
subsystems, each of them bringing their own complexities. This can be a difficult
task, especially when we don't have information about the context of each
subsystem. For that reason, we will implement a facade to show high-level
operations that are going to be in charge of interacting with the subsystems,
abstracting us, the programmers, from dealing with the intricacies of these
interactions.
Flyweight
Structural pattern
Real-world example
This pattern is devoted to the mediation between two objects. What I refer as
mediation is the series of actions executed before and after carrying out the task
requested by the user. The main trait of the Proxy pattern is that it keeps the user
unaware of the mediation that is being carried out in the background, because the
client receives an object structured as expected, all by interacting, unknowingly,
with a proxy.
IObject: It represents the common interface between the Object and the Proxy.
Object: It represents the actual object the client wants access to.
Proxy: Class which implements IObject and is the virtual representation of the
Object.
1. The client sends a request for an object to the Factory .
2. The Factory creates a Proxy for encapsulating the Object.
3. The client executes the Proxy which was created by the Factory.
4. The Proxy performs one or more actions before the execution of the Object.
5. The Proxy hands over the execution to the Object.
6. The Proxy performs one or more actions after the execution of the Object.
7. The Proxy returns the result.
Real-world example
This design pattern allows us to go over a data structure without needing to know
its internal construction. It is especially useful when we are working with complex
data structures, because it lets us go over their elements through an iterator. The
iterator is an interface including the necessary methods for reviewing all the
elements of a data structure. The most common methods are:
The cliententers in a loop in order to review all the elements on the structure, the loop ends when there are no elements left for reviewing, which is going
to be signaled by the hasNext method.
The client sends the request for a new element to the iterator using the nextmethod.
If there are elements left to be reviewed, then we return to step 3, something that is going to be repeated until all elements have been reviewed.
Real-world example
ICommand: Interface describing the structure of the commands, which defines the generic execution method for all of them.
Concrete Command: They represent the concrete commands inheriting from ICommand. Each of these classes represents a command that can be
executed independently.
Command Manager: This component lets us manage all the commands available at runtime, from here we're able to request commands or create new
ones.
Observer
Behavioral pattern
This design pattern allows us to observe the changes suffered by an object, that is,
if the observed object suffers any change, a notification will be sent to the
observers; this is known as publish-subscribe. Observer is one of the main design
patterns used in the development of graphical user interfaces (GUI), because it
allows us to decouple the graphical component from the action to be performed.
IObservable: Interface which must be implemented by all objects subject to observation, in it, all the basic implementable methods are defined.
ConcreteObservable: This is the observable class; it implements IObservable along with its methods.
IObserver: Interface which must be implemented by all objects in charge of observing the changes on IObservable.
ConcreteObserver: Concrete class in charge of watching the changes on IObservable, it inherits from IObserver and must implement its methods.
ObserverA registers into the Observable object in order to be notified of any changes.
ObserverB registers into the Observable object in order to be notified of any changes.
Real-world example
The template design pattern focuses on code reutilization for implementing steps
to solve problems. This is achieved by implementing base classes for defining
basic behaviors. Typically, methods are created for each step of the algorithm;
some of these will be implemented while others remain abstract until they are
executed by the subclasses.
Client: It's the component which triggers the execution of the template.
AbstractTemplete: It's an abstract class including a series of operations which define the necessary steps for carrying out the execution of the algorithm.
This class has a templateMethod method for executing step1, step2 and step3 in order.
Implementation: This class represents a concrete template which inherits from AbstractTemplate and implements its methods.
Real-world example
Strategy
Behavioral pattern
The strategy design pattern allows us to set the behavior of a class at runtime.
Strategy bases on polymorphism for implementing a series of behaviors that can
be interchanged during the execution of the program, allowing for a modification of
an object’s behavior by following a strategy that has been set.
IStrategy: Common interface all strategies must implement. In it, all the operations the strategies need to implement are defined.
10. Context takes this result and hands it over to the client.
Real-world example
The Chain of Responsibility pattern stands out from others because of its
versatility, allowing us to solve problems where we’re not sure which object should
process a specific request; this design pattern can easily solve problems
inheritance can’t because of its chain structure, where a series of objects try to
process a request in sequence.
AbstractHandler: Base class used for defining the structure of every ConcreteHandler. This class is an aggregation of itself, which allows it to contain
another AbstractHandler for carrying on with the execution chain.
2. The first Handler tries to process the request but it’s unable to do it, therefore, it relays the request to the next handler .
3. The second Handler tries to process the request but it’s unable to do it, therefore, it relays the request to the next Handler .
4. The third Handler tries to process the request but it’s unable to do it, therefore, it relays the request to the next Handler .
5. The HandlerN (Any handler in the chain) is the one finally succeeding in processing the request, after which it sends a response (optional) so it can be
relayed by all the previous Handlers until it reaches to the Client.
Real-world example
Interpreter
Behavioral pattern
The Interpreter design pattern is used for evaluating a determined language and
return an Expression. This pattern can interpret languages such as Java, C#, SQL,
or even a new one invented by us, and provide a response based on its
evaluation.
This is one of the most complex design patterns, because we need to combine
various object-oriented programming techniques in order to implement it, which
can make it a bit difficult to understand. The main techniques we're going to be
dealing with are Inheritance, Polymorphism and Recursivity.
The components included in the Interpreter pattern are as follows:
Context: Object carrying global information to be used by the interpreter in order to read and store information of all the classes in the pattern. This
object is sent to the interpreter which then relays it to the rest of the structure.
TerminalExpression: It refers to expressions which, after being evaluated or interpreted, end the execution of a branch or subtree.
NonTerminalExpression: These are composite expressions, which contain more expressions subject to evaluation. They are interpreted by using
recursivity until a terminal expression is found.
1. The client creates the context for the execution of the interpreter.
3. The client requests for the evaluation of the expression to the interpreter . To that end, it sends it the context.
7. The Expression is completely evaluated and provides the result of the interpretation of all the Terminal Expressions and Non-terminal Expressions.
Real-world example
Google Translator is an example of the interpreter design pattern where the input can be in any
language and we get the output in another language.
Mediator
Behavioral pattern
The Mediator design pattern handles the manner in which a group of classes
interact with each other. This pattern is especially useful when we have a large
number of classes communicating directly with one another. By implementing this
pattern, we can create a bidirectional communication layer, which can be used by
a class in order to interact with others through a common object acting as a
mediator.
One of the main problems we face when building large projects is that the number
of classes can grow even larger and increase the interactions and relationships
between them. This can bring issues with coupling, especially when we're creating
direct communication channels which can be hard to track and debug.
The components included in the pattern are:
Client:Component for starting the communication with the rest of the components through the mediator.
Components:These are parts of the mediator communication network, that is, diverse objects sharing the same mediator for communicating with each
other.
Mediador:Component for handling the communication between the rest of the components. It directs the incoming messages to the corresponding
receiver.
1. ComponentA wants to communicate with ComponentB and sends a message through the mediator.
2. The mediator may analyze the message for debugging or tracking purposes, or for directing it to the receiver.
3. The message is delivered to the receiver, which in turn sends a response to the mediator.
Real-world example
Memento
Behavioral pattern
This design pattern allows us to record the state of an object on a specific moment
in order to return it to that state at any given time. Memento is useful when we
have many objects changing over time and, for some reason, we need to restore
them to a previous state.
Caretaker: This is the component registering all the changes happening in the Originator. It allows us to travel to any previous state of the Originator.
2. The Originator creates a new Memento which represents its current state.
3. The Client stores the Memento into the Caretaker in order to change between different Originatorstates.
4. After some time, the Client sends a request to the Caretaker for a previous state of the Originator.
5. The Client uses the Memento sent by the Caretaker to restore the state of the Originator .
Real-world example
The Null Object pattern was created due to the need of avoiding the appearance of
null values that can cause runtime errors. What this pattern basically proposes is
using instances for implementing the required interface but with a void body,
instead of returning a null value.
AbstractObject: Common interface between the real object and its null representation.
ConcreteObject: Class representing a real object, which has a concrete implementation; it will be created only when the requested object exists.
NullObject: Object which implements void methods. It will be created only when a requested object does not exist, and it’s going to be returned instead
of a null reference.
1. The client looks for a specific object.
4. On the other hand, if the requested object is located, an instance of ConcreteObjectwill be returned.
5. The client receives any of the two mentioned instances, however, it will never get a null reference if the object were not to be found.
Real-world example
State
Behavioral pattern
The State design pattern characterizes for changing its behavior depending on the
state of the application. To achieve this, it’s necessary to create a series of classes
for representing the different states an application can go through, that is, one
class for each state of the application.
The components included in the State design pattern are as follows:
Context: It represents the component subject to changing states, it has its current state as one of its properties. Going back to the vending machine
example, this would represent the machine.
AbstractState: Base class used for generating different states. This works better as an abstract class, instead of as an interface, because it allows us to
set behaviors by default and alter the operation on every state.
ConcreteState: Each one of these components represent a state the application could go through during its execution, which is why we’re going to have
a ConcreteState for each possible state. This class must inherit from AbstractState.
2. A request operation is executed in the Context, delegating the execution to the current state (StateA).
4. Again, a request operation is executed in the Context delegating the execution to the current state (StateB).
6. A new request operation is executed in the Context delegating the execution to the current state (StateC).
Real-world example
By implementing the State design pattern, we are going to create our own server,
which will be control through a series of states. These states will tell the server
how to behave under different events, because the same event can provide
different results depending on the current state of the server.
Visitor
Behavioral pattern
The Visitor design pattern is used for separating the logic and operations
performed over a complex structure. On occasions, we can find data structures
requiring various operations to be performed and needing new ones to be created
as the application grows.
2. The client creates the instance of the Visitor to be used in the structure.
3. The client executes the accept method of the structure and sends the Visitor.
4. The Element tells the Visitor which method must be used for processing it. The Visitor must have a method for each class type included in the structure.
5. The Visitor analyzes the Element using its visitElement method and repeats the accept method execution process over the Element's children. Again, the
Visitor must have a method for each class type included in the structure.
6. The ConcreteElementA tells the Visitor visitor which method must be used for processing it, that is visitElementA.
7. The Visitor proceeds with the rest of the children of the Element and executes the accept method on ConcreteElementB.
8. The ConcrteElementB tells the Visitor which method must be used for processing it, that is visitElementB.
9. Lastly, the Visitor ends the operation performed over the structure after having traversed all the objects, providing results available for the client by
request using the getResults method (this is optional, because some operations won't produce any results).
Real-world example
By implementing the Visitor design pattern, we are going to review how a plan to
build a Microsoft Project type project is analyzed and evaluated to get the
information we require. To that end, we will develop a work plan which includes
activities and personnel forming a hierarchical structure similar to a tree.