0% found this document useful (0 votes)
2 views54 pages

My Design Pattern Notes

The document discusses several design patterns in software development, including the Value Object Design Pattern, Aggregate Root Pattern, Iterator Pattern, Adapter Pattern, Bridge Pattern, and Template Pattern. It explains the principles and implementations of each pattern, emphasizing how they help in structuring code, ensuring data integrity, and decoupling components. Key takeaways include the importance of value-based equality in value objects, centralized management in aggregate roots, and the flexibility offered by design patterns in handling different data structures and behaviors.

Uploaded by

vivek.sheth07
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)
2 views54 pages

My Design Pattern Notes

The document discusses several design patterns in software development, including the Value Object Design Pattern, Aggregate Root Pattern, Iterator Pattern, Adapter Pattern, Bridge Pattern, and Template Pattern. It explains the principles and implementations of each pattern, emphasizing how they help in structuring code, ensuring data integrity, and decoupling components. Key takeaways include the importance of value-based equality in value objects, centralized management in aggregate roots, and the flexibility offered by design patterns in handling different data structures and behaviors.

Uploaded by

vivek.sheth07
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

Value Object Design Pattern

Definition: “Value object is an object whose equality is based on the value rather than identity. “

Let us understand the above statement with more clarity. When you create two objects
and even if their values are the same, they represent different entities. For example, in
the below code, we have created two person objects with the same name “Shiv”.

Person PersonfromIndia = new Person();


[Link] = "Shiv";
[Link] = 20;

Person PersonfromNepal = new Person();


[Link] = "Shiv";
[Link] = 20;

But the first person stays in “India” and the other stays in “Nepal”. So in other words
“PersonFromIndia” object is different from “PersonFromNepal” object even if
the person’s name and age is the same. In other words, they have DIFFERENT
IDENTITIES.

If you try to compare the above C# object, it will return false and this is completely in
line with our expectations. You can use the “Equal” method, or you can use “==”.

if ([Link](PersonfromNepal))
{

But now consider the below scenario of a money example. We are creating two money
objects of 1 rupee value but one is using a paper material and the other is made of steel
material.
But in this case “OneRupeeCoin” value is equal to “OneRupeeNote” value. So even if the
objects are of different instances, they are equal by money value. So, if the money and
currency type match, both the objects are equal.

Money OneRupeeCoin = new Money();


[Link] = 1;
[Link] = "INR";
[Link] = "INR";
[Link] = "A3123JJK332";

Money OneRupeeNote = new Money();


[Link] = 1;
[Link] = "INR";
[Link] = "INR";
[Link] = "Paper";
[Link] = "Z2232V4455";

In other words, value objects when compared are the same when the values of the
properties are the same.

Implementing Value object pattern in C# is a two step process, so in the further article,
let us run through those steps.
Making Value Object Pattern Work Logically in C#
Now for the above “Money” value object to function properly, the below comparison
should work both for “Equals” and “==”. But technically, C# does object reference
comparison and not value.

if (OneRupeeCoin==OneRupeeNote)
{
[Link]("They are equal");
}
if ([Link](OneRupeeNote))
{
[Link]("They are equal");
}

So, to achieve the same, we need to override the “equals” methods and overload “==”
operator as shown in the code below. You can see now the equality is compared on the
base of “Value” and “CurrencyType”. If the “CurrencyType” and “Value” is the same, that
means the objects are the same.

class Money
{
public override bool Equals(object obj)
{
var item = obj as Money;
if (([Link] == Value)&&([Link] == CurrencyType))
{
return true;
}
return false;
}

public static bool operator !=(Money money1, Money money2)


{
if (([Link] != [Link]) &&
([Link] != [Link]))
{
return true;
}
return false;
}
public static bool operator ==(Money money1, Money money2)
{
if (([Link] == [Link])&&
([Link] == [Link]))
{
return true;
}
return false;
}
}

Once the above methods are incorporated, the equality will work on the values and not the
reference. This is in synch with the Value object pattern behavior we discussed in the
introduction.

Making it work with HashTable

There is one more scenario where we expect Value object to work properly i.e. with
Hastable collections. Let us say we add Money object to Hastable collection as shown
below.

Money m1 = new Money(1, "INR", "Coin");


Hashtable coll = new Hashtable();
[Link](m1, m1);

Now I should be able to retrieve the same object by creating other Money object of the
same value type because they are of the same value. In other words, the below code should
retrieve the “m1” money object without any issues.

Money m2 = new Money(1, "INR", "Paper");

Money m3 = (Money)coll[m2];

Now Hashtable uses the value from “GetHashCode” to get an object from the collection.
So, in order to ensure that hash code calculation is same for the combination of value and
currency type we need to override the “GetHashCode” function as shown in the below
code.
By doing so our money object would work properly with the hashtable collection

class Money
{
// Code removed for clarity
public override int GetHashCode()
{
return (_Value +_CurrencyType).GetHashCode();
}
}

Struct as Value Types

Lot of developers use Struct for implementing Value object design pattern and probably
due to the technical nature of struct it looks logical as well. But below are some practical
issues I personally faced with struct implementation: -

 Mapping with Entity framework.


 Loosing OOP benefits like inheritance.

Conclusion About Value Object Pattern


 Value objects equality is based on value rather than identity.
 Value objects should be IMMUTABLE to avoid confusion.
 In C# to ensure proper behavior of value object, we need to override “Equals”
method and “==” operator.

Immutable means once the object is filled with data, that data cannot be changed.
Aggregate Root Pattern

Aggregate root is cluster / group of objects that are treated as a single unit of data.

I am sure lots of developers are already using this pattern unknowingly, via this short note I
would like to inform you formally what you are doing.

Let us try to understand the above definition with an example. Consider the below
“Customer” class which has the capability to add multiple “Address” objects to it. In order
to achieve the same, we have exposed an address collection from the customer class to
represent the 1 to many relationships.

class Customer
{
public string CustomerName { get; set; }
public DateTime DateofBirth { get; set; }

public List<Address> Addresses { get; set; }

class Address
{
public string Address1 { get; set; }
public string Type { get; set; }
}

The above class structure works perfectly well. You can create object of customer and add
multiple addresses object to it.
Customer cust = new Customer();
[Link] = "Shiv koirala";
[Link] = [Link]("12/03/1977");

Address Address1 = new Address();


Address1.Address1 = "India";
[Link] = "Home";
[Link](Address1);

Address Address2 = new Address();


Address2.Address1 = "Nepal";
[Link] = "Home";
[Link](Address2);

Now let's say we want to implement the following validations:

“Customer can only have one address of Home type”.

At this moment, the address collection is a NAKED LIST COLLECTION which is exposed
directly to the client. In other words, there are no validations and restrictions on the “Add”
method of the list. So, you can add whatever and how much ever address objects as you
wish.

[Link](Address2);

So how to address this problem in a clean and logical way. If you think logically, “Customer”
is composed of Addressescollection, so Customer is like a main root. So rather than allowing
DIRECT NAKED ACCESS to Addresses list, how about accessing the address list from
the customer class. In other words, centralizing access to address objects from
the customer class.

So below are three steps which I have implemented to put a centralize address validation.

Step 1: I have made the address list private. So, no direct access to the collection is possible.

Step 2: Created a “Add” method in the “Customer” class for adding the “Address” object. In
this add method, we have put the validation that only one “Home” type address can be
added.
Step 3: Clients who want to enumerate through the address collection for them we have
exposed “IEnumerable” interface.

class Customer
{
// Code removed for clarity
private List<Address> _Addresses; // Step 1 :- Make list private

public void Add(Address obj) // Step 2 :- Address objects added via customer
{
int Count=0;
foreach (Address t in _Addresses)
{
if ([Link] == "Home")
{
Count++;
if (Count > 1)
{
throw new Exception("Only one home address is allowed");
}
}
}
_Addresses.Add(obj);
}

public IEnumerable<Address> Addresses // Step 3 :- To browse use enumerator


{
get { return _Addresses; }
}

If you analyze the above solution closely, the customer is now the root and
the address object is manipulated and retrieved via the customer class.

Why did we do this? Because “Customer” and “Address” object is one logical data unit. To
maintain integrity of address validation, we need to go via the “Customer” class. In the
same way loading of data, updation, deletion, etc. should all happen via the “Customer”
class so that we have proper data integrity maintained.

So, when we say load customer from database, all the respective address objects should
also get loaded.

So, when a group of objects which form one logical unit should have centralized root via
which the manipulation of the contained object should happen. This kind of arrangement is
terms as “Aggregate Root”.
Iterator Pattern

Iterator design pattern is one of the behavioral design patterns. It is applicable to the
situation when a collection of objects has to be iterated without exposing its internal
structure. The whole intent is that it is of less importance how collection has been
internally stored from user point of view. The user is only concerned how he/she can
access a collection. Using the word “access” is a little ambiguous in this context
therefore it needs more clarity.

When accessing a collection, a user can iterate over a collection in a forward or


backward manner or randomly. In forward manner, starting from Zero (0) user can
access collection till end and in backward manner, it’s vice versa. User can also attempt
to access the items of a collection randomly. That means accessing a collection has got
different meanings.

Problem Description
An online shop sells clothes. The shop does not own clothes. However, it sells clothes
from various stores and it charges a brokerage on the number of clothes sold e.g. ebay.
Brokerage is not important for us in this example. Therefore, we shall not talk about it in
detail. Every store has got a different meaning of providing their collection of clothes to
online shop interface.

Let’s say we have two stores, EspiritStore and ZaraStore. EspiritStore stores its clothes
in a List collection whereas ZaraStore in an Array. Both stores implement an interface
and returns an IEnumerable collection of type Clothes. Problem at the client end is that
it needs two functions to iterate over the collection separately. For EspiritStore, it
iterates over a List whereas for ZaraStore over an Array.

Well, at the outset, it is not important for stores to expose how their elements are
internally stored. Online Shop should only be concerned to iterate over a collection
without having to know their internal structure e.g. Array, List or Dictionary etc.
Solution

From online shop point of view, it is only concerned about if a collection has items and if
that’s the case, it should be able to access them. In principle, every store should provide
an iterator that should implement an interface with the following two methods:

1. public interface ITerator{


2. bool hasNext();
3. object Next();
4. }

Advantage of following this approach is that stores instead of returning access to their
internal data structure can return Iterators and encapsulate whole accessing of their
data structures in their respective iterators.

An example of the approach has been shown below:

hasNext() method should check if element has got items in the collection based on a
incrementing position number.

Please refer this article for detailed code :


[Link]

So as to summarize, Iterators are widely used in Object Oriented Programming. Almost


all collection classes offer iterators in one or other form.
Adapter pattern

Many times, two classes are incompatible because of incompatible interfaces. Adapter
helps us to wrap a class around the existing class and make the classes compatible with
each other. Consider the below figure “Incompatible interfaces” both are collections to
hold string values. Both have a method which helps us to add string in to the collection.
One of the methods is named as ‘Add’ and the other as ‘Push’. One of them uses the
collection object and the other the stack. We want to make the stack object compatible
with the collection object.

There are two way of implementing adapter pattern one is by using aggregation (this is
termed as the object adapter pattern) and the other inheritance (this is termed as the
class adapter pattern). First let’s try to cover object adapter pattern.

Figure ‘Object Adapter pattern’ shows a broader view of how we can achieve the same.
We have a introduced a new wrapper class ‘clsCollectionAdapter’ which wraps on the
top of the ‘clsStack’ class and aggregates the ‘push’ method inside a new ‘Add’ method,
thus making both the classes compatible.
Figure: Object Adapter pattern

The other way to implement the adapter pattern is by using inheritance also termed as
class adapter pattern. Figure ‘Class adapter pattern’ shows how we have inherited the
‘clsStack’ class in the ‘clsCollectionAdapter’ and made it compatible with the
‘clsCollection’ class.

Figure: Class adapter pattern


Bridge Pattern

Bridge pattern helps to decouple abstraction from implementation. With this if the
implementation changes it does not affect abstraction and vice versa. Consider the
figure ‘Abstraction and Implementation’. The switch is the abstraction and the
electronic equipments are the implementations. The switch can be applied to any
electronic equipment, so the switch is an abstract thinking while the equipments are
implementations.

Figure: - Abstraction and Implementation

Let’s try to code the same switch and equipment example. First thing is we segregate
the implementation and abstraction in to two different classes. Figure ‘Implementation’
shows how we have made an interface ‘IEquipment’ with ‘Start()’ and ‘Stop()’ methods.
We have implemented two equipments one is the refrigerator and the other is the bulb.
Figure :- Implementation

The second part is the abstraction. Switch is the abstraction in our example. It has a
‘SetEquipment’ method which sets the object. The ‘On’ method calls the ‘Start’ method
of the equipment and the ‘off’ calls the ‘stop’.

Figure: - Abstraction
Finally, we see the client code. You can see we have created the implementation objects
and the abstraction objects separately. We can use them in an isolated manner.

Figure: - Client code using bridge


Template pattern

Template pattern is a behavioral pattern. Template pattern defines a main process


template and this main process template has sub processes and the sequence in which
the sub processes can be called. Later the sub processes of the main process can be
altered to generate a different behavior.

Punch: - Template pattern is used in scenarios where we want to create extendable


behaviors in generalization and specialization relationship.

For example, below is a simple process to format data and load the same in to oracle.
The data can come from various sources like files, SQL server etc. Irrespective from
where the data comes, the overall general process is to load the data from the source,
parse the data and then dump the same in to oracle.

Figure: - General Process

Now we can alter the general process to create a CSV file load process or SQL server
load process by overriding ‘Load’ and ‘Parse’ sub process implementation.
Figure: - Template thought Process

You can see from the above figure how we have altered ‘Load’ and ‘Parse’ sub process
to generate CSV file and SQL Server load process. The ‘Dump’ function and the sequence
of how the sub processes are called are not altered in the child processes.

In order to implement template pattern, we need to follow 4 important steps: -

1. Create the template or the main process by creating a parent abstract class.

2. Create the sub processes by defining abstract methods and functions.

3. Create one method which defines the sequence of how the sub process

methods will be called. This method should be defined as a normal method

so that we child methods cannot override the same.


4. Finally create the child classes who can go and alter the abstract methods

or sub process to define new implementation.


public abstract class GeneralParser
{
protected abstract void Load();

protected abstract void Parse();


protected virtual void Dump()
{
[Link]("Dump data in to oracle");
}
public void Process()
{
Load();
Parse();
Dump();
}
}

The ‘SqlServerParser’ inherits from ‘GeneralParser’ and overrides the ‘Load’ and ‘Parse’
with SQL server implementation.

public class SqlServerParser : GeneralParser


{
protected override void Load()
{
[Link]("Connect to SQL Server");
}
protected override void Parse()
{
[Link]("Loop through the dataset");
}

The ‘FileParser’ inherits from General parser and overrides the ‘Load’ and ‘Parse’
methods with file specific implementation.

public class FileParser : GeneralParser


{
protected override void Load()
{
[Link]("Load the data from the file");
}
protected override void Parse()
{
[Link]("Parse the file data");
}

}
From the client you can now call both the parsers.

FileParser ObjFileParser = new FileParser();


[Link]();

[Link]("-----------------------");

SqlServerParser ObjSqlParser = new SqlServerParser();


[Link]();

[Link]();

The outputs of both the parsers are shown below.

Load the data from the file


Parse the file data
Dump data in to oracle
-----------------------
Connect to SQL Server
Loop through the dataset
Dump data in to oracle
Composite Pattern

GOF definition: - A tree structure of simple and composite objects

Many times, objects are organized in tree structure and developers must understand the
difference between leaf and branch objects. This makes the code more complex and can
lead to errors.

Compose objects into tree structures to represent part-whole hierarchies. Composite lets
clients treat individual objects and compositions of objects uniformly.

Challenge

You are working on a distributed application containing Head Office and Branch Offices.
Each office will be having 2 Clock Controls which needed to be updated globally during
Daylight Saving times.

The above diagram shows the current structure. There will be only 1 Head Office and
multiple branches under it. The head office and each branch will be having 2 clock controls.
The time changing process starts from the head office and in the current approach, the
head office must remember all branches and all clocks inside each branch. This is very
tedious and will break when there is consolidation of branches under one branch group.
Implementation

We can use the Composite Design Pattern in the above scenario. Once our solution is
implemented the Head Office needs to think about only the Branches. The Branches will
think about their respective Clocks.

There are 2 classes in our solution: Office and Clock. The Office class can represent Head
Office and Branches. The Clock class manages the clock control for changing time.

We need to introduce one interface which will be implemented by the Office and Clock
classes.

interface IComponent
{
void Add(IComponent notifier);
void SetTime(DateTime time);
}

The Add() method ensures adding a component of type IComponent. It can be used to add
an Office or Clock instance.

The SetTime() method can be used to change the current time.

Class Implementations

Following are the implementations of the Office and Clock classes:

class Office : IComponent


{
private IList<IComponent> _list = new List<IComponent>();

public void Add(IComponent notifier)


{
_list.Add(notifier);
}
public void SetTime(DateTime time)
{
foreach (IComponent n in _list)
[Link](time);
}
}

class Clock : IComponent


{
public ClockControl ClockControl;

public void Add(IComponent notifier)


{
throw new ApplicationException("You cannot add IClock!");
}

public void SetTime(DateTime time)


{
[Link] = time;
}
}

Please note that the SetTime() implementation of the Office class takes care of informing all
the added IComponent instances. Thus, the Head Office can notify all the branches. The
branches will notify all the clock instances.

Creating Instances
// Create Composite Classes and assign Clock Control instances
_headOffice = new Office();
_headOffice.Add(new Clock() { ClockControl = hForm.clock1 });
_headOffice.Add(new Clock() { ClockControl = hForm.clock2 });

Office branch1 = new Office();


[Link](new Clock() { ClockControl = b1Form.clock1 });
[Link](new Clock() { ClockControl = b1Form.clock2 });
_headOffice.Add(branch1);

Office branch2 = new Office();


[Link](new Clock() { ClockControl = b2Form.clock1 });
[Link](new Clock() { ClockControl = b2Form.clock2 });
_headOffice.Add(branch2);

Please note that the branch instances are added to the head office.
Running the Application

On clicking the Set Time button you can see all the clocks are reset to 10:00 AM.

Here the Head Office does not need to think about all the clock instances of branches. Here
the individual objects (clocks) and composite objects (branches) are treated uniformly
satisfying the pattern definition.

On Button Click:

private void SetTimeButton_Click(object sender, EventArgs e)


{
_headOffice.SetTime(
new DateTime(
[Link],
[Link],
[Link],
10, 0, 0));
}
Prototype pattern

Prototype pattern falls in the section of creational pattern. It gives us a way to create new
objects from the existing instance of the object. In one sentence we clone the existing
object with its data. By cloning any changes to the cloned object does not affect the
original object value.

If you are thinking by just setting objects, we can get a clone then you have mistaken it. By
setting one object to other object we set the reference of object BYREF. So, changing the
new object also changed the original object. To understand the BYREF fundamental more
clearly consider the figure ‘BYREF’ below. Following is the sequence of the below code:

 In the first step we have created the first object i.e. obj1 from class1.
 In the second step we have created the second object i.e. obj2 from class1.
 In the third step we set the values of the old object i.e. obj1 to ‘old value’.
 In the fourth step we set the obj1 to obj2.
 In the fifth step we change the obj2 value.
 Now we display both the values and we have found that both the objects have the
new value.

Figure :- BYREf

The conclusion of the above example is that objects when set to other objects are set
BYREF. So, changing new object values also changes the old object value.
There are many instances when we want the new copy object changes should not affect
the old object. The answer to this is prototype patterns.

Let’s look how we can achieve the same using C#. In the below figure ‘Prototype in action’
we have the customer class ‘ClsCustomer’ which needs to be cloned. This can be achieved
in C# my using the ‘MemberWiseClone’ method. In JAVA we have the ‘Clone’ method to
achieve the same. In the same code we have also shown the client code. We have created
two objects of the customer class ‘obj1’ and ‘obj2’. Any changes to ‘obj2’ will not affect
‘obj1’ as it’s a complete cloned copy.
Can you explain shallow copy and deep copy in prototype patterns?

There are two types of cloning for prototype patterns. One is the shallow cloning which you
have just read in the first question.

In shallow copy only that object is cloned, any objects containing in that object is not
cloned.

For instance, consider the figure ‘Deep cloning in action’ we have a customer class and we
have an address class aggregated inside the customer class. ‘MemberWiseClone’ will only
clone the customer class ‘ClsCustomer’ but not the ‘ClsAddress’ class.

So, we added the ‘MemberWiseClone’ function in the address class also. Now when we call
the ‘getClone’ function we call the parent cloning function and also the child cloning
function, which leads to cloning of the complete object.

When the parent objects are cloned with their containing objects it’s called as deep cloning
and when only the parent is cloning its termed as shallow cloning.
Memento Pattern

Memento pattern is the way to capture objects internal state without violating
encapsulation. Memento pattern helps us to store a snapshot which can be reverted at
any moment of time by the object. Let’s understand what it means in practical sense.

Consider figure ‘Memento practical example’, it shows a customer screen. Let’s say if the
user starts editing a customer record and he makes some changes. Later he feels that he
has done something wrong and he wants to revert back to the original data. This is where
memento comes in to play. It will help us store a copy of data and in case the user presses
cancel the object restores to its original state.

Figure: - Memento practical example

Let’s try to complete the same example in C# for the customer UI which we had just gone
through. Below is the customer class ‘clsCustomer’ which has the aggregated memento
class ‘clsCustomerMemento’ which will hold the snapshot of the data.

The memento class ‘clsCustomerMemento’ is the exact replica (excluding methods) of the
customer class ‘clsCustomer’. When the customer class ‘clsCustomer’ gets initialized the
memento class also gets initialized. When the customer class data is changed the memento
class snapshot is not changed. The ‘Revert’ method sets back the memento data to the
main class.
Figure: - Customer class for memento

The client code is pretty simple. We create the customer class. In case we have issues, we
click the cancel button which in turn calls the ‘revert’ method and reverts the changed data
back to the memento snapshot data. Figure ‘Memento client code’ shows the same in a
pictorial format.
Decorator Pattern

Decorator design pattern comes under structural design pattern category of Gang of four
(GoF) design patterns. As the name suggests it is used to decorate (modify/change) an
existing object without changing its original behavior.

The decorator design pattern is used where there is need to add additional functionality to
already existing object without altering its structure. This design pattern provides a
decorator class which acts as the wrapper of the existing class. This wrapper class is
responsible for adding additional functionalities to the existing class.

Problem Statement

Consider you have to write a program that will calculate the on-road price of the bike. The
final on-road price will depend on base price, accessories, road tax and several other things.
In this case, we can write a decorator pattern that can calculate the on-road price of the
bike.

 Bike interface: Component interface


 RoyalEnfield Class: ConcrteComponent Class
 BikeDecorator abstract class: Decorator abstract class
 PromotionalOffer, TransportOfficeCharges and AccessoriesPrice: ConcreteDecorato
r class

Base price of bike will be available in existing/ actual object of RoyalEnfield class. After
adding additional decorator, the final on road price of the bike has been calculated. The
additional decorator is nothing but the functionality that is added to the
existing RoyalEnfield object.

public interface Bike


{
string GetBikeDetails();
int GetPrice();
}
// 'ConcreteComponent' class
public class RoyalEnfield : Bike
{
public string GetBikeDetails()
{
return "Royal Enfield 350 CC classic Model";
}

public int GetPrice()


{
return 150000;
}
}

//'Decorator' abstract class


public abstract class BikeDecorator : Bike
{
public abstract string GetBikeDetails();
public abstract int GetPrice();
}

// 'ConcreteDecorator' class
public class PromotionalOffer : BikeDecorator
{
private Bike _bike;
public int PromotionalDiscount;

public PromotionalOffer(Bike bike)


{
_bike = bike;
}

public override string GetBikeDetails()


{
return "Promotional offer";
}

public override int GetPrice()


{
return _bike.GetPrice() - PromotionalDiscount;
}
}

// 'ConcreteDecorator' class
public class TransportOfficeCharges : BikeDecorator
{
private Bike _bike;
public int TransportOfficeCharge;
public TransportOfficeCharges(Bike bike)
{
_bike = bike;
}

public override string GetBikeDetails()


{
return "Transport Office Charges";
}

public override int GetPrice()


{
return _bike.GetPrice() + TransportOfficeCharge;
}
}

// 'ConcreteDecorator' class
public class AccessoriesPrice : BikeDecorator
{
private Bike _bike;
public int AccessoriesCharge;

public AccessoriesPrice(Bike bike)


{
_bike = bike;
}

public override string GetBikeDetails()


{
return "Accessories Charges";
}

public override int GetPrice()


{
return _bike.GetPrice() + AccessoriesCharge;
}
}

static void Main(string[] args)


{
RoyalEnfield RoyalEnfieldBike = new RoyalEnfield();
[Link]("-------------------" + [Link]() + "--------------------");
[Link]("Royal Enfield Bike Base Price :" + [Link]());
int test = [Link]();
PromotionalOffer promotionalOffer = new PromotionalOffer(RoyalEnfieldBike);
[Link] = 25000;
[Link]("Price After Promotinal Discount (25000) :" + [Link]());
test = [Link]();

TransportOfficeCharges trasportOfficeCharges = new TransportOfficeCharges(promotionalOffer);


[Link] = 20000;
[Link]("Price After Tranport Charges (20000) :" + [Link]());
test = [Link]();

AccessoriesPrice accessoriesPrice = new AccessoriesPrice(trasportOfficeCharges);


[Link] = 15000;
[Link]("Price After adding accessories (15000) :" + [Link]());

[Link]("-----------------------------------------------------------------------------");
[Link]("On road Price :" + [Link]());
test = [Link]();

[Link]();
}
Mediator pattern
Many a times in projects communication between components are complex. Due to this the logic
between the components becomes very complex. Mediator pattern helps the objects to
communicate in a disassociated manner, which leads to minimizing complexity.

Figure: - Mediator sample example

Let’s consider the figure ‘Mediator sample example’ which depicts a true scenario of the
need of mediator pattern. It’s a very user-friendly user interface. It has three typical
scenarios.

Scenario 1: - When a user writes in the text box it should enable the add and the clear
button. In case there is nothing in the text box it should disable the add and the clear
button.

Figure: - Scenario 1
Scenario 2: - When the user clicks on the add button the data should get entered in the list
box. Once the data is entered in the list box it should clear the text box and disable the add
and clear button.

Figure: - Scenario 2

Scenario 3: - If the user clicks the clear button it should clear the name text box and disable
the add and clear button.

Figure: - Scenario 3

Now looking at the above scenarios for the UI we can conclude how complex the
interaction will be in between these UI’s. Below figure ‘Complex interactions between
components’ depicts the logical complexity.
Figure: - Complex interactions between components

Ok now let me give you a nice picture as shown below ‘Simplifying using mediator’. Rather
than components communicating directly with each other if they communicate to
centralized component like mediator and then mediator takes care of sending those
messages to other components, logic will be neat and clean.

Figure: - Simplifying using mediator


The first thing the mediator class does is takes the references of the classes which have the
complex communication. So here we have exposed three overloaded methods by name
‘Register’. ‘Register’ method takes the text box object and the button objects. The
interaction scenarios are centralized in ‘ClickAddButton’,’TextChange’ and
‘ClickClearButton’ methods. These methods will take care of the enable and disable of UI
components according to scenarios.

The client logic is neat and cool now. In the constructor we first register all the components
with complex interactions with the mediator. Now for every scenario we just call the
mediator methods. In short when there is a text change, we can the ‘TextChange’ method
of the mediator, when the user clicks add we call the ‘ClickAddButton’ and for clear click we
call the ‘ClickClearButton’.
Figure: - Mediator client logic
Façade Pattern

Façade pattern sits on the top of group of subsystems and allows them to communicate in
a unified manner.

Figure: - Façade and Subsystem

Figure ‘Order Façade’ shows a practical implementation of the same. In order to place an
order, we need to interact with product, payment and invoice classes. So, order becomes a
façade which unites product, payment and invoice classes.

Figure: - Order Facade

Figure ‘façade in action’ shows how class ‘clsorder’ unifies / uses ‘clsproduct’,’clsproduct’
and ‘clsInvoice’ to implement ‘PlaceOrder’ functionality.
Figure: - Façade in action
Factory Design Pattern

Gang of Four Definition


“Define an interface for creating an object, but let sub-classes decide which class to
instantiate. The Factory method lets a class defer instantiation it uses to sub-classes”

Factory pattern is one of the most used design patterns in real world applications

Factory pattern creates object without exposing the creation logic to the client and refer
to newly created object using a common interface

From the above diagram, client uses factory and creates the product.

Implementation Guidelines : We need to choose Factory Pattern when

 The Object needs to be extended to subclasses


 The Classes doesn’t know what exact sub-classes it has to create.
 The Product implementation tend to change over time and the Client remains
unchanged

Simple Factory Example: Business Requirement

Differentiate employees as permanent and contract and segregate their pay scales as well
as bonus based on their employee types
We can address the above requirement with the below implementations

1. Implement without Factory Pattern


2. Use a Simple Factory
3. Enhance Simple factory to Factory Method Pattern

Solution 1: Implement without Factory Pattern

if ([Link] == 1)
{
[Link] = 8;
[Link] = 10;
}
else if ([Link] == 2)
{
[Link] = 12;
[Link] = 5;
}

For any new employee type addition, we end up modifying the controller code adding extra
over heads in the development and testing process.

Using a simple factory eliminates the above drawbacks.

Solution 2: Implement with Simple Factory

Step 1: Add new Manager folder and add the below interface and classes

[Link]

public interface IEmployeeManager


{
decimal GetBonus();
decimal GetPay();
}
[Link]

public class ContractEmployeeManager : IEmployeeManager


{
public decimal GetBonus()
{
return 5;
}

public decimal GetPay()


{
return 12;
}
}

[Link]

public class PermanentEmployeeManager : IEmployeeManager


{
public decimal GetBonus()
{
return 10;
}

public decimal GetPay()


{
return 8;
}
}

Step 2 : Create Factory folder and add the below Manager class
[Link]

public class EmployeeManagerFactory


{
public IEmployeeManager GetEmployeeManager(int employeeTypeID)
{
IEmployeeManager returnValue = null;
if (employeeTypeID == 1)
{
returnValue = new PermanentEmployeeManager();
}
else if (employeeTypeID == 2)
{
returnValue = new ContractEmployeeManager();
}
return returnValue;
}
}
Step 3: Update the employee’s controller to consume the factory.

EmployeeManagerFactory empFactory = new EmployeeManagerFactory();

IEmployeeManager empManager =
[Link]([Link]);

[Link] = [Link]();

[Link] = [Link]();

Simple factory implementation is illustrated below


SOLID
SOLID is basically 5 principles, which will help to create a good software architecture.
You can see that all design patterns are based on these principles.

Single responsibility principle (SRP)

A class should take one responsibility and there should be one reason to change that
class. Now what does that mean? I want to share one picture to give a clear idea about
this.

Now see this tool is a combination of so many different tools like knife, nail cutter,
screw driver, etc. So will you want to buy this tool? I don’t think so. Because there is a
problem with this tool, if you want to add any other tool to it, then you need to change
the base and that is not good. This is a bad architecture to introduce into any system. It
will be better if nail cutter can only be used to cut the nail or knife can only be used to
cut vegetables.

namespace SRP
{
public class Employee
{
public int Employee_Id { get; set; }
public string Employee_Name { get; set; }

public bool InsertIntoEmployeeTable(Employee em)


{
// Insert into employee table.
return true;
}

public void GenerateReport(Employee em)


{
// Report generation with employee data using crystal report.
}
}
}

‘Employee’ class is taking 2 responsibilities, one is to take responsibility of employee


database operation and another one is to generate employee report. Employee class should
not take the report generation responsibility because suppose some days after your
customer asked you to give a facility to generate the report in Excel or any other reporting
format, then this class will need to be changed and that is not good.

So according to SRP, one class should take one responsibility so we should write one
different class for report generation, so that any change in report generation should not
affect the ‘Employee’ class.

public class ReportGeneration


{
public void GenerateReport(Employee em)
{
// Report reneration with employee data.
}
}

Open closed principle (OCP)

Now take the same ‘ReportGeneration’ class as an example of this principle. Can you guess
what is the problem with the below class!!

public class ReportGeneration


{
public string ReportType { get; set; }

public void GenerateReport(Employee em)


{
if (ReportType == "CRS")
{
// Report generation with employee data in Crystal Report.
}

if (ReportType == "PDF")
{
// Report generation with employee data in PDF.
}
}
}

Brilliant!! Yes you are right, too much ‘If’ clauses are there and if we want to introduce
another new report type like ‘Excel’, then you need to write another ‘if’. This class should
be open for extension but closed for modification. But how to do that!!
public class IReportGeneration
{
public virtual void GenerateReport(Employee em)
{
// From base
}
}

public class CrystalReportGeneraion : IReportGeneration


{
public override void GenerateReport(Employee em)
{
// Generate crystal report.
}
}

public class PDFReportGeneraion : IReportGeneration


{
public override void GenerateReport(Employee em)
{
// Generate PDF report.
}
}

So if you want to introduce a new report type, then just inherit from IReportGeneration.
So IReportGeneration is open for extension but closed for modification.
Liskov substitution principle (LSP)

This principle is simple but very important to understand. Child class should not break
parent class’s type definition and behavior. Now what is the meaning of this!! Ok let me
take the same employee example to make you understand this principle. Check the below
picture. Employee is a parent class and Casual and Contractual employee are the child
classes, inhering from employee class.

public abstract class Employee


{
public virtual string GetProjectDetails(int employeeId)
{
return "Base Project";
}

public virtual string GetEmployeeDetails(int employeeId)


{
return "Base Employee";
}
}

public class CasualEmployee : Employee


{
public override string GetProjectDetails(int employeeId)
{
return "Child Project";
}
// May be for contractual employee we do not need to store the details into
database.

public override string GetEmployeeDetails(int employeeId)


{
return "Child Employee";
}
}

public class ContractualEmployee : Employee


{
public override string GetProjectDetails(int employeeId)
{
return "Child Project";
}

// May be for contractual employee we do not need to store the details into
database.

public override string GetEmployeeDetails(int employeeId)


{
throw new NotImplementedException();
}
}

Up to this is fine right? Now, check the below code and it will violate the LSP principle.

List<Employee> employeeList = new List<Employee>();

[Link](new ContractualEmployee());
[Link](new CasualEmployee());

foreach (Employee e in employeeList)


{
[Link](1245);
}

Now I guess you got the problem. Yes right, for contractual employee, you will get not
implemented exception and that is violating LSP. Then what is the solution? Break the
whole thing in 2 different interfaces,

1. IProject

2. IEmployee

and implement according to employee type.


public interface IEmployee
{
string GetEmployeeDetails(int employeeId);
}

public interface IProject


{
string GetProjectDetails(int employeeId);
}

Now, contractual employee will implement IEmployee not IProject. This will maintain this
principle.

Interface segregation principle (ISP)

This principle states that any client should not be forced to use an interface which is
irrelevant to it. Now what does this mean, suppose there is one database for storing data of
all types of employees (i.e. Permanent, non-permanent), now what will be the best
approach for our interface?

public interface IEmployee


{
bool AddEmployeeDetails();
}

And all types of employee class will inherit this interface for saving data. This is fine right?
Now suppose that company one day told to you that they want to read only data of
permanent employees. What you will do, just add one method to this interface?

public interface IEmployeeDatabase


{
bool AddEmployeeDetails();
bool ShowEmployeeDetails(int employeeId);
}

But now we are breaking something. We are forcing non-permanent employee class to
show their details from database. So, the solution is to give this responsibility to another
interface.
public interface IAddOperation
{
bool AddEmployeeDetails();
}
public interface IGetOperation
{
bool ShowEmployeeDetails(int employeeId);
}

And non-permanent employee will implement only IAddOperation and permanent


employee will implement both the interface.

Dependency inversion principle (DIP)

This principle tells you not to write any tightly coupled code because that is a nightmare to
maintain when the application is growing bigger and bigger. If a class depends on another
class, then we need to change one class if something changes in that dependent class. We
should always try to write loosely coupled class.

Tightly Coupled Example:

public class Business


{
//Now business class has dependency on DataAccess Class.
//If we change dataAccess, we are going to break business class.

public void SignUp(string userName, string password)


{
//Business Validation
var dataAccess = new DataAccess();
[Link](userName,password);
}
}

public class DataAccess


{
//We can modify this class based on DB i.e. MongoDB, Oracle
//which is against OCP

public void Store(string userName, string password)


{
//10 line of code to Write the data to SQL Server database.
}
}
Loosely Coupled Example:

public class Business :IBusiness


{
//Now business class has now dependency on DataAccess Class.
//If we change dataAccess, we are going to break business class.

public void SignUp(string userName, string password)


{
//Business Validation
IDataAccess dataAccess = new DataAccess();
[Link](userName,password);
}
}

public class DataAccess : IDataAccess


{
//We can modify this class based on DB i.e. MongoDB, Oracle
//which is against OCP
public void Store(string userName, string password)
{
//10 line of code to Write the data to SQL Server database.
}
}

public interface IBusiness


{
void SignUp(string userName, string password);
}

public interface IDataAccess


{
void Store(string userName, string password);
}

Constructor level Injection:

public class UserInterface


{
private readonly IBusiness _business;
public UserInterface(IBusiness business)
{
_business = business;
}
public void GetData()
{
[Link]("Enter Your UserName : ");
var userName = [Link]();
[Link]("Enter Your Password : ");
var password = [Link]();

_business.SignUp(userName,password);
}
}

public class Business :IBusiness


{
private readonly IDataAccess _dataAccess;
//this is called injection, because IDataAccess is injected into
Business ctor
//this is also called ctor injection
public Business(IDataAccess dataAccess)
{
_dataAccess = dataAccess;
}
public void SignUp(string userName, string password)
{
//here again Business class still dependent on DataAccess class
//Because it still using new KeyWord.
//To Remove this dependency, Instance needs to be given to
Business [Link] something else

//IDataAccess dataAccess = new DataAccess();

//instead of using new Keyword, we can use _dataAccess


//Now there is no concrete reference to DataAccess class.

_dataAccess.Store(userName,password);
}
}

public class DataAccess : IDataAccess


{
//We can modify this class based on DB i.e. MongoDB, Oracle
//which is against OCP
public void Store(string userName, string password)
{
//10 line of code to Write the data to SQL Server database.
}
}

public interface IBusiness


{
void SignUp(string userName, string password);
}

public interface IDataAccess


{
void Store(string userName, string password);
}

You might also like