You are on page 1of 57

সফটওয় ার

আিকেটকচার

Table of Contents
ভূিমকা 0
িডজাইন প াটান 1
ােটিজ প াটান 1.1
ােটাটাইপ প াটান 1.2
এডা ার প াটান 1.3
Iterator িডজাইন প াটান 1.4
চইন অফ র পি িবিলিট 1.5
অবজারভার প াটান 1.6
িসে লটন প াটান 1.7
কে ািজট িডজাইন প াটান 1.8
ট াইেভন ডেভলপেম 2

1
সফটওয় ার আিকেটকচার

howtocode.com.bd

কাস এর মুল পাতা | HowToCode মুল সাইট | সবার জন া ািমং গ | িপিডএফ ডাউনেলাড

সফটওয় ার আিকেটকচার - বাংলা

এস এম ফরহাদ আলী

সংে প
ইউজার ই ারেফস-এ েপিরএ , কাড ল, িরফ া িরং থেক কের িবিভ িডজাইন প াটান, ট াইেভন
ডেভলপেম ও ডাটােবজ িডজাইন ইত ািদ স েক িব ািরত ...

ওেপন সাস
এই বইিট মূলত া েম লখা এবং বইিট স ূন ওেপন সাস । এখােন তাই আপিনও অবদান রাখেত পােরন
লখক িহেসেব । আপনার কি িবউশান গৃ হীত হেল অবদানকারীেদর তািলকায় আপনার নাম যাগ কের দওয়া হেব ।

এিট মূলত একিট িগটহাব িরেপািজেটাির যখােন এই বইেয়র আিটেকল েলা মাকডাউন ফরম ােট লখা হে ।
িরেপাজটিরিট ফক কের পুল িরকুেয় পাঠােনার মাধ েম আপনারাও অবদান রাখেত পােরন ।

Like 18 Share

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives


4.0 International License.

ভূিমকা 2
সফটওয় ার আিকেটকচার

িডজাইন প াটান ভূিমকা


সফটওয় ার ডেভলপেম এ ব ল আেলািচত একিট BuzzWord হে িডজাইন প াটান । সফটওয় ার
ডেভলপাররা সাধারণত অেনক জিটল জিটল সমস ার সমাধান কের থােকন। যিদ দখা যায় এই সমস া েলা বার
বার ডেভলপারেদর সমাধান করেত হে , তাহেল তারা এই সমস া েলার সবেচেয় ভােলা একিট সমাধান বর কের
ফেলন যােত কের ভিবষ েত এরকম সমস া দখা িদেল সহেজই এর সমাধান কের ফলা যায় ।

সফটওয় ার িডজাইন করেত গেল িডজাইন প াটান অেনক কােজ লােগ। কননা িডজাইন প াটান হে একটা
সমস ার পরীি ত এবং মািণত সমাধান। সহজ কথায় বলেত গেল িডজাইন প াটান হে কানও িনিদ সমস ার
সমাধােনর টমে ট।

িডজাইনপ াটান কানও ল া ুেয়েজর উপর ডীেপ কের না তাই আপনারা য ল া ুেয়েজই কাজ কেরন না কেনা,
িডজাইন প াটান শখা এবং সটা এ াই কের ভােলা সফটওয় ার িডজাইন করা কিঠন িকছু না ।

িডজাইন প াটান 3
সফটওয় ার আিকেটকচার

ােটিজ প াটান
ােটিজ প াটান বশ মজার এবং সহজ একিট িডজাইন প াটান । রানটাইেম কানও এলগিরদম অথবা কানও
অবেজে র কমন িবেহিভওর চ করেত এই প াটােনর জুিড় নই ।

মেন ক ন একিট একশন গেমর কথা যখােন একজন যা ােক অেনক অেনক িভেলেনর সােথ যু করেত হয় ।
গেমর েত যা ার পাওয়ার / হলথ থােক ১০০% এবং েতই যা া মার মার কাট কাট মুেড থােক মােন
এে িসভ মুেড থােক । আে আে যা ার হলথ কমেত থােক এবং স িডেফি ভ মুেড চেল যায় । তখন স
খাবােরর খাঁজ করেত থােক, খাবার পেল তার হলথ আবার ১০০% হেয় যায় এবং স আবার এে িসভ মুেড চেল
যায় ।

এ রকম গেমর জন যিদ আমরা কাড িলিখ তাহেল েতই একটা Fighter class বানােবা িনেচর মত কেরঃ

public class Fighter


{
public int Health { get; set; }
public void ChangeMood(String mood)
{
switch (mood)
{
case "Angry":
SetAnggsiveBehavior();
break;
case "Defensive":
SetDefensiveBehavior();
break;
}
}
private void SetDefensiveBehavior()
{
Console.WriteLine("Defensive Mood");
}
private void SetAnggsiveBehavior()
{
Console.WriteLine("Angry Mood");
}
}

এখােন Health নােম একিট পািট রাখা হেয়েছ Fighter এর াে র জন । একিট ChangeMood() নােম মথড
রাখা হেয়েছ এবং এর প ারািমটার িহেসেব ফাইটােরর মুড নােম একিট ি ং রাখা হেয়েছ এবং একিট Switch ক রাখা
হেয়েছ । Switch েকর িভতর চক করা হেয়েছ যিদ ফাইটােরর মুড Angry হয় তাহেল SetAnggsiveBehavior()
কল করা হেয়েছ । আবার যিদ ফাইটােরর মুড Defensive হয় তাহেল SetDefensiveBehavior() কল করা হেয়েছ
। দুইটা মথেডর মেধ ই ফাইটােরর বতমান মুেডর জন িকছু একটা ি কের দয়া হেয়েছ কনেসােল । এরপর
CllientCode আমােদর Fighter class এ ইউজ করেব এইভােবঃ

ােটিজ প াটান 4
সফটওয় ার আিকেটকচার

class Program
{
static void Main(string[] args)
{
var fighter = new Fighter();
var random = new Random();

fighter.Health = random.Next(1, 100);

if (fighter.Health <= 50)


{
fighter.ChangeMood("Defensive");
}
else if (fighter.Health > 50)
{
fighter.ChangeMood("Angry");
}

Console.ReadKey();
}
}

এখােন ফাইটােরর া ৫০ এর উপের হেল আমরা ফাইটারেক এে িসভ মুেড িনেয় িগেয়িছ এবং ৫০ এর িনেচ হেলই
আমরা তােক িডেফি ভ মুেড িনেয় িগেয়িছ ।

ব স আমােদর গেমর জন কাড িলখা শষ । িক এই কােডর class library যিদ আিম অন কাউেক দই এবং স
ফাইটােরর জন নতুন কানও Mood বানােত চায় তাহেল স পারেবনা । তােক আমােদর ফাইটার ােসর পুেরা সাস
কাড িদেয় িদেত হেব । তাহেল আমােদর অবেজ ওিরেয়ে ড া ািমং এর OCP (Open Close Principle )
এর ভােয়ােলশন হেব । OCP মােন হে একিট class/entity ধুমা এ েট করার জন ওেপন থাকেব িক
মািডিফেকশন করার জন াজড থাকেব ।

িক বতমান Fighter class এ নতুন মুড ঢাকােত চাইেল আমােদর switch েক নতুন case যাগ করেত হেব এবং
নতুন একিট মথড কল করেত হেব । তাই এিট OCP এর ভােয়ােলশন ।

আবার এই িডজাইেনর আেরাও সমস া হে এিট Principle of Least Knowledge েলরও ভােয়ােলশন ।
কননা Fighter class ক সব সময় জানেত হে তার কান কান মুড থাকেত পাের অথাৎ এে িসভ, িডেফি ভ
া া া এসব মুড স েক তােক জানেত হে । িক আমােদর ফাইটার এর এসব স েক নেলজ না থাকেলও চেল
। আমরা তােক রানটাইেম বেল িদেত পাির তুিম এখন এই মুেড ফাইট কর ।

সবেশেষ এই িডজাইন এর আেরকিট সমস া হে SRP (Single Responsibility Principle) এর ভােয়ােলশন ।


কননা একটা ফাইটােরর িবিভ মুেডর জন আমরা িবিভ মথড কল কেরিছ । িক বা েব এই মুড েলার কাড
অেনক বড় হেয় যেত পাের । আমরা এখােন ধু মা কনেসােল িকছু মেসজ ি কেরিছ ।

তাই িডেফি ভ মুড অথবা এে িসভ মুড মথেড না িনেয় আমরা এ েলা আলাদা class এ িনেয় যেত পাির ।

তাহেল আসুন আমরা কােডর িডজাইন চ কের ফিল।

ােটিজ প াটান 5
সফটওয় ার আিকেটকচার

যেহতু সব ফাইটােরর কমন একিট বিশ হে ফাইট করা সেহতু আমরা একিট কমন ই ারেফস IFighter বানােত
পাির যার মেধ একিট মথড থাকেব Fight() নােমঃ

public interface IFighter


{
void Fight();
}

এখন আমরা আমােদর ফাইটােরর এে িসভ এবং িডেফি ভ মুেডর জন দুইটা আলাদা আলদা class বানােত পাির
যারা উভেয়ই IFighter এ ইমি েম করেব ।

এে িসভ এর জন ঃ

public class Aggresive : IFighter


{
public void Fight()
{
Console.WriteLine("Fighter is now in aggresive mood");
}
}

িডেফি ভ এর জন ঃ

public class Defensive : IFighter


{
public void Fight()
{
Console.WriteLine("Fighter is now in defensie mood");
}
}

এভােব আমােদর িডজাইেনর SRP এর ে ম স ভ হেয় গেলা।

এখন Principle of Least Knowledge এবং OCP এর ে ম স ভ করার জন আমােদর Fighter class িটেক
মািডিফেকশন করেত হেব এভােবঃ

ােটিজ প াটান 6
সফটওয় ার আিকেটকচার

public class Fighter


{
public int Health { get; set; }
private IFighter _fighter;
public void ChangeMood(IFighter fighter)
{
_fighter = fighter;
_fighter.Fight();
}

এখন আমােদর ClientCode দখেত হেব এরকমঃ

class Program
{
static void Main(string[] args)
{
var fighter = new Fighter();
var random = new Random();

fighter.Health = random.Next(1, 100);

if (fighter.Health <= 50)


{
fighter.ChangeMood(new Defensive());
}
else if (fighter.Health > 50)
{
fighter.ChangeMood(new Aggresive());
}

Console.ReadKey();
}
}

এই িডজাইেন আমােদর সুিবধা িক তাহেল ।

আমরা যিদ এই িডজাইেনর class library অন কাউেক িদেয় দই এবং স যিদ ফাইটােরর জন নতুন কানও মুড
বানােত চায় তাহেল তােক কখনই Fighter class এ হাত িদেত হেব না ।

তােক নতুন মুেডর জন class বানােত হেব যিট IFighter ক ইমি েম করেব , এবং Fight() মথেডর মেধ নতুন
মুেডর জন কাড িলখেব সবেশেষ ােয় কােড এর Fighter এর ChangeMood() এর ভতর িদেয় নতুন
অবেজ িদেয় িদেলই আমােদর নতুন মুড এ ফাইট করা করেব ফাইটার ।

ােটিজ প াটােনর সবেচেয় বড় সুিবধা হে রানটাইেম কানও কমন অবেজে র কমন বিশ / এলগিরদম( যমন
Sorting) চ করা এবং switch ক অথবা if else এর শকল থেক কাডেক মুি দয়া ।

গফ এর ভাষ অনুযায়ী ােটিজ প াটােনর সং া এরকমঃ

ােটিজ প াটান 7
সফটওয় ার আিকেটকচার

Define a family of algorithms, encapsulate each one, and make them interchangeable.
Strategy lets the algorithm vary independently from clients that use it.

ােটিজ প াটান 8
সফটওয় ার আিকেটকচার

ােটাটাইপ প াটান
একটা ব াপার আমরা সবাই জািন য, আমরা যখন new ইউজ কের অবেজ বানাই তখন সােথ সােথ অবেজ িট
মমরীেত জায়গা দখল কের বেস ।

সা হভী ওেয়ট এি েকশেন অেনক অেনক অবেজে র এর দরকার হয় আমােদর । যত বশী অবেজ তত বশী
মমরী খরচ । তেব বতমান সমেয়র িপিস লার পারফরেম এত ভােলা য অেনেকই এই িজিনস েলা এিড়েয় যায়
অথবা অেনেকর এি েকশেনর মমরী কমিজউম করার ব পার েলা মুখ িবষয় হেয় দাঁড়ায় না ।

তেব িচ া ক ন মাবাইল গম অথবা য কানও গেমর কথা । মমরী কম িক এই মমরী ইউজ কেরই গম বানােত
হেব । তখন এই ােটাটাইপ িডজাইন প াটান আমােদর অেনক সাহায কের ।

মািটেভশনাল উদাহরনঃ

মেন ক ন আমােদর একিট Person class আেছ এরকমঃ

public class Person


{
public String Name { get; set; }
public String Email { get; set; }
}

এখন আমােদর ClientCode এ আমরা এর অবেজ বানাই এভােবঃ

public static void Main(string[] args)


{
var person = new Person();
person.Name = "Person1";
person.Email = "xyz@mail.com";
Console.WriteLine("Name:{0} and Email:{1}", person.Name, person.Email);

এখন এই অবেজ যিদ আমােদর এি েকশেনর ১০০০ জায়গায় আবার েয়াজন হয় তেব আবার একই ভােব আমােদর
অবেজ বানােত হেব ১০০০ বার । অথাৎ ১০০০ বার আমােদর new কের অবেজ বানােত হেব । ১০০০ িট অবেজ
আমােদর মমরীেত অেনক অেনক জায়গা িনেয় চুপ কের বেস থাকেব । যিট খুব ভােলা কথা না ।

সমাধানঃ এই বার বার অেবজ বানােনার হাত থেক রহাই পেত আমরা যা করেত পাির তা হে একিট অবেজে র
ান বািনেয় রেখ িদেত পাির । যখনই ঐ অবেজে র দরকার হেব িঠক তখনই আমরা এর ান ইউজ করেত পারেবা
। আমােদর নতুন কের আর অবেজ বানােনার দরকার হেব না ।

তাহেল চলুন আমরা Person class এর চহারার মানিচ একটু চ কের ফিল :P । তার আেগ আমােদর একিট
ই ারেফস এর দরকার হেব । আমােদর ই ারেফসটা িস ল এবং এরকমঃ

ােটাটাইপ প াটান 9
সফটওয় ার আিকেটকচার

public interface IClone


{
Object Clone();
}

ািনং এর উপায় ন র ১:

এর আেগ আমরা একটা class বািনেয়িছলাম যা িছল খুবই িস ল । এর মা দুেটা ম ার ভিরেয়বল িছেলা ।

এখন আমােদর যা করেত হেব তা হে Person class িট IClone ই ারেফস ক ইমি েম করেব এবং ই ারেফস
এর Clone মথেডর মেধ Person এর নতুন অবেজ বািনেয় এই অবেজে র একটা একটা কের াপািট ধের ধের
আমােদর Person class এর াপািট েলা এসাইন করেত হেব । িনেচর উদাহরণ দখেলই ব পারটা ি য়ার হেয়
যােবঃ

public class Person : IClone


{
public String Name { get; set; }
public String Email { get; set; }
public Object Clone()
{
var person = new Person
{
Name = Name,
Email = Email
};

return person;
}
}

এখন আমােদর ােয় কাড দেখ িনইঃ

public class Program


{
public static void Main(string[] args)
{
Person person = new Person();
person.Name = "Person";
person.Email = "xyz@mail.com";

Console.WriteLine("Before Cloning.......");
Console.WriteLine("Name:{0} and Email:{1}", person.Name, person.Email);

Person person1 = person.Clone() as Person;


Console.WriteLine("After Cloning..............");
Console.WriteLine("Name:{0} and Email:{1}", person1.Name, person1.Email);
}
}

ােটাটাইপ প াটান 10
সফটওয় ার আিকেটকচার

া ামিট রান করেল আমরা দখেত পাব য ধুমা একবার অবেজ বািনেয় এর ান কের আমরা বু আেরকিট
অবেজ পেয় গিছ ।

ািনং এর উপায় ন র ২:

আমােদর Person class এ মা দুিট াপািট িছেলা । এবং Clone মথেড আমরা এর অবেজ বািনেয় এই দুিট
াপািট এসাইন কেরিছলাম । এখন যিদ এমন হয় য এই class এ অেনক েলা াপািট থাকেব । তাহেল আমােদর
ধের ধের এই অসংখ াপািট েলা এসাইন করেত হেব যা অেনকটা ক সাধ কাজ।

.NET আমােদর একটা সুিবধা িদেয়েছ MemberwiseClone() ান করার সুিবধা । এই মথড হে অবেজে র
আিদিপতা Object class এর একিট Protected মথড । এিট যা কের তা হে এিট অবেজে র সব েলা ম ার
এর ান কের রেখ দয় ।

এিট ব বহার করেত হয় এভােবঃ

public class Person : IClone


{
public String Name { get; set; }
public String Email { get; set; }
public Object Clone()
{
return MemberwiseClone();
}
}

এবং আমােদর ােয় কাড আেগর মতই থাকেবঃ

public class Program


{
public static void Main(string[] args)
{
Person person = new Person();
person.Name = "Person";
person.Email = "xyz@mail.com";

Console.WriteLine("Before Cloning.......");
Console.WriteLine("Name:{0} and Email:{1}", person.Name, person.Email);

Person person1 = person.Clone() as Person;


Console.WriteLine("After Cloning..............");
Console.WriteLine("Name:{0} and Email:{1}", person1.Name, person1.Email);
}
}

এরপর আমােদর দুেটা িজিনস িনেয় একটু আেলাচনা করা দরকার । একিট হে ShallowCopy আর অন িট হে
DeepCopy.

তা ShallowCopy টা িক ?? আসুন জেন িনইঃ-

ােটাটাইপ প াটান 11
সফটওয় ার আিকেটকচার

ShallowCopy আর িকছু ই না, একটা অবেজ এর ত েকটা াপািট ক অন অবেজ এর াপািটেত এসাইন
কের দয়াই হে ShallowCopy । িক যখন আমরা একটা অবেজ এর মেধ অন একিট অবেজ এর রফাের
রাখব তখন এই ShallowCopy অন রকম িবেহভ কের । চলুন উদাহরন দেখই ব পার টা ি য়ার কের িনই।

আমরা নতুন একিট class বানাই Address নােম যার একিট মা াপািট থাকেব Street নােমঃ

public class Address


{
public String Street { get; set; }
}

এবং আমােদর আেগর Person class িট চ কের িনেচর মত কিরঃ

public class Person : IClone


{
public String Name { get; set; }
public String Email { get; set; }
public Address Address { get; set; }
public Person()
{
Address = new Address();
}
public Object Clone()
{
return MemberwiseClone();
}
}

তাহেল আমােদর Person class এর মেধ Address class এর একিট রফাের থাকেলা ।

এখন আমরা আমােদর ােয় কােড অবেজ ািনং এর আেগ Person এর Address এসাইন কির এবং ািনং
এর পর আবার আমরা ানড অবেজ এর Address এসাইন কির ।

সবেশেষ, ািনং এর আেগর অবেজ এর Address কনেসােল ি করেল দখেত পাব য আমরা পের য ানড
অবেজ এর Address এর ভ ালু এসাইন কেরিছলাম সটা দখাে ।

ােটাটাইপ প াটান 12
সফটওয় ার আিকেটকচার

public class Program


{
public static void Main(string[] args)
{
Person person = new Person();

person.Name = "Person";
person.Email = "xyz@mail.com";
person.Address.Street = "221B";

Person person1 = person.Clone() as Person;


person1.Address.Street = "221B Baker Street";

Console.WriteLine("After Cloning..............");
/*showing person1's Address in person object*/
Console.WriteLine("Street:{0}",person.Address.Street);
}
}

তারমােন আমােদর ানড অবেজ এর রফাের অবেজ Address এবং একচুয়াল অবেজ এর রফাের
অবেজ Address একই অবেজ ক মােন Address ক পেয় করেছ । যিট একিট সমস া ।

আেরকিট িবষয় ল নীয় এখােন বািক ভ ািরেয়বল েলা িক িঠকই ান হে িক রফাের ান হে না । এর


সমাধান পেত পাির আমরা DeepCloning কের।

DeepCloning:

DeepCloning হে MemberwiseClone() এর সােথ বাড়িত িকছু যাগ করা । সটা হে অবেজ এর


রফাের টাও কিপ কের অবেজ িরটান করা

িঠক এভােবঃ

ােটাটাইপ প াটান 13
সফটওয় ার আিকেটকচার

public class Person : IClone


{
public String Name { get; set; }
public String Email { get; set; }
public Address Address { get; set; }
public Person()
{
Address = new Address();
}
public Object Clone()
{
//cloning member variable
Person person = this.MemberwiseClone() as Person;

//cloning reference object


person.Address = new Address();
person.Address.Street = this.Address.Street;
return person;
}
}

এখন আমােদর ােয় কাড দেখ আিসঃ

public class Program


{
public static void Main(string[] args)
{
Person person = new Person();

person.Name = "Person";
person.Email = "xyz@mail.com";
person.Address.Street = "221B";

Person person1 = person.Clone() as Person;


person1.Name = "Person";
person1.Email = "xyz@mail.com";
person1.Address.Street = "221B Baker Street";

Console.WriteLine("Before Cloning.......");
Console.WriteLine("Name:{0} and Email:{1}, Street:{2}", person.Name, person.Email, person

Console.WriteLine("After Cloning.......");
Console.WriteLine("Name:{0} and Email:{1}, Street:{2}", person1.Name, person1.Email, pers
}
}

এটা রান করেল ShallowCopy এর ঝােমলা আর থাকেব না অথাৎ ান করেল একই অবেজ এর আেরকিট
আইেডি কাল অবেজ পাব (দুিট িভ িভ অবেজ পাব)।

ােটাটাইপ প াটান 14
সফটওয় ার আিকেটকচার

আমরা আেরক উপােয় DeepCopy করেত পাির । তার আেগ আমােদর সব েলা class এর উপর
[Serializable] এি িবউট িলেখ রেখ আসেত হেব এবং Person class এর clone() মথেড একটু অন ভােব
কাড িলখেত হেব।

চলুন দেখ আিস । আমােদর [Serializable] এি িবউট যাগ করার পর Address class টা এরকম দখায়ঃ

[Serializable]
public class Address
{
public String Street { get; set; }
}

এরপর মািডিফেকশন এবং [Serializable] এি িবউট যাগ করার পর Person class টা এরকম দখায়ঃ

[Serializable]
public class Person : IClone
{
public String Name { get; set; }
public String Email { get; set; }
public Address Address { get; set; }
public Person()
{
Address = new Address();
}
public Object Clone()
{
using (Stream stream = new MemoryStream())
{
var binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(stream, new Person());
stream.Seek(0, SeekOrigin.Begin);
return (Person)binaryFormatter.Deserialize(stream);
}
}
}

তাহেল আমােদর ােয় কাড আেগর মতই থাকেব, রজা ও আেগর মত দখােব । আমরা ধুমা DeepCopy
করার কৗশলটা চ কেরিছ মা ।

ােয় কাডঃ

ােটাটাইপ প াটান 15
সফটওয় ার আিকেটকচার

public class Program


{
public static void Main(string[] args)
{
Person person = new Person();

person.Name = "Person";
person.Email = "xyz@mail.com";
person.Address.Street = "221B";

Person person1 = person.Clone() as Person;


person1.Name = "Person";
person1.Email = "xyz@mail.com";
person1.Address.Street = "221B Baker Street";

Console.WriteLine("Before Cloning.......");
Console.WriteLine("Name:{0} and Email:{1}, Street:{2}", person.Name, person.Email, person

Console.WriteLine("After Cloning.......");
Console.WriteLine("Name:{0} and Email:{1}, Street:{2}", person1.Name, person1.Email, pers
}
}

এই িছেলা আমােদর Prototype Design Pattern ।

সমা :)

ােটাটাইপ প াটান 16
সফটওয় ার আিকেটকচার

এডা ার প াটান
এডা ার িডজাইন প াটান খুবই সহজ একিট িডজাইন প াটান ।

বা ব জীবেনও আমরা িবিভ ধরেনর এডা ার ব বহার কির । যমন য কানও রকেমর চাজার , মাবাইল, ক ােমরার
মমরী কােডর এডা র ইত ািদ ।

তাহেল সফটওয় ার িডজাইেন এডা ার প াটান িক?

চলুন আমরা উদাহরণ এর মাধ েমই এর উ র খুেজ িনই।

মেন ক ন সই াৈগিতহািসক যুেগ যখন ডাইেনাসররা ঘুের বড়াত তখন এক আিদমানব পেটর দােয় একিট
সফটওয় ার ফােম কামলা খাটত । সই আমেল তা আর এত এত লাইে রী/ মওয়াক িছেলা না । তা সই আিদ
মানব সই ফােম C# ল া ুেয়েজ একিট class িলেখিছেলা যটা ধুমা একিট কাজ করেত পারত । সটা হে এই
class এর একটা মথড িদেয় স একটা ইি জার এর অ ােরর ইি জার েলার যাগফল বর কের িদত।

Class টা হে িঠক এ রকমঃ

public class Calculator


{
public int GetSum(int[] numbers)
{
int sum = numbers.Sum();
return sum;
}
}

এরপর সই আিদ মানব তাহার ClientCode এ এই Calculator class িটেক আনে র সিহত িঠক এভােব ব বহার
করেত লািগেলা

public class Program


{
static void Main(string[] args)
{
var calculator = new Calculator();
int[] numbers = { 1, 2, 3, 4, 5 };
var sum = calculator.GetSum(numbers);
Console.WriteLine(sum);
}
}

এরপর ল ল বছর পর র যুেগর গােছর চামড়া পরা ইয়া ল া ল া দাঁিড় ওয়ালা া ামার একিট হার ভতের
সই আিদ মানেবর ভা াচুরা একিট পন াইভ খুেজ পেলা।

এডা ার প াটান 17
সফটওয় ার আিকেটকচার

স তার ল াপটেপ পন াইভিট ঢু িকেয় একিট DLL ফাইল খুেজ পেলা। স ঘেটঘুেট দখেলা য এই DLL এ সই
আিদ মানেবর বানােনা class টী রেয়েগেছ।

স এই class ক তার একিট এি েকশেন ইউজ করার িস া িনেলা।

ইউজ করেত িগেয় দখেলা য আিদ মানবিট তার class এ Array ব বহার কেরেছ। িক তার এি েকশেন কাথাও
Array এর ব বহার নই। কারন এতিদেন এই র যুেগ Collection Framework চেল এেসেছ।
List,Dictionary,HashTable এ েলার ব বহার হেয়েছ। এই া ামার িস া িনল যভােবই হাক আিদ
মানেবর কাড তােক তার এি েকশেন ব বহার করেত হেবই । যভােবই হাক।

ঐিতহ ধের রাখার জন মিরয়া এই গােছর বাকল পড়া া ামার ।

এখন এই া ামার অেনক িচ া ভাবনা কের একিট বুি বর করেলা। স একটা class িলখেলা যটা তার আিদ
মানেবর class টােক ব বহার করেব। িঠক এভােবঃ

public class CalculatorAdapter


{
private readonly Calculator _calculator;
public CalculatorAdapter()
{
_calculator =new Calculator();
}

public int GetTotalSum(List<int> numbers)


{
int sum = _calculator.GetSum(numbers.ToArray());
return sum;
}
}

এখােন আমরা আসেল িক কেরিছ?? আমরা এখােন আিদ মানেবর বানােনা Calculator class টােক ইউজ কেরিছ।
এর GetSum() মথডিটেক GetTotalSum() মথড এর মধ ব বহার কেরিছ। আর একিট কাজ এখােন করা
হেয়েছ সটা হে কনভাসন । এখােন ল নীয় ব পার হে GetSum() িক আ েম িহেসেব একিট ইি জােরর
Array নয় আবার অন িদেক GetTotalSum() মথড আ েম িহেসেব একিট ইি জােরর িল নয়।

যেহতু আিদ মানেবর কাড ইি জােরর Array এর ইিলেমে র যাগফল বর কের সেহতু এখােন ইি জােরর িল েক
Array ত কনভাট করা হেয়েছ ।

তাহেল র যুেগর া ামার এখন তার ClientCode এ নতুন কাড ইউজ করেব এইভােবঃ

এডা ার প াটান 18
সফটওয় ার আিকেটকচার

class Program
{
static void Main(string[] args)
{
CalculatorAdapter calculator = new CalculatorAdapter();
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
var sum = calculator.GetTotalSum(numbers);
Console.WriteLine(sum);
}
}

র যুেগর া ামার এত ণ যা করেলা সটা হে স CalculatorAdapter নােম একটা Adapter িলেখেছ


Calculator class এর জন যােত কের Calculator class এর কানও িকছু চ না কের স এটােক ব বহার
করেত পাের।

এখােন দখা যাে া ামারিট একিট িল পাঠাে এর যাগফল বর করার জন িক ভতের স আেগর Array
ব বহার কেরই যাগফল বর করেছ যটা ClientCode থেক বাঝা যাে না।

এত ণ য আপনােদর বা ব এবং ক নীয় একটা গ শানালাম এটাই হে এডা র িডজাইন প াটান। গফ এর


সং া দখেলই ব পারটা ি য়ার হেয় যােব আশাকির ;)

Convert the interface of a class into another interface clients expect. Adapter lets
classes work together that couldn’t otherwise because of incompatible interfaces.

এডা ার প াটান 19
সফটওয় ার আিকেটকচার

Iterator িডজাইন প াটান


মেন ক ন একিট সফটওয় ার ফাম ফসবুক এবং টুইটােরর যত েলা ইউজার আেছ তােদর স ূণ তথ েলা একিট
কমন ডটােবইজ এ রাখেত চায় । (যিদও বা েব ফসবুক এবং টুইটার কখনও তােদর ইউজােরর তথ বাইেরর
কাউেক িদেব না )

সফটওয় ার ফামিট দুইজন ডেভলপার ক এই কােজর দািয় িদল । একজন ডেভলপার ফসবুেকর ইউজােরর তথ
িনেয় কাজ করেব অন জন টুইটােরর ইউজােরর তথ িনেয় কাজ করেব ।

থম ডেভলপার ফসবুেকর ইউজারেদর একিট List এ রেখ কাজিট কের ফলেলা এইভােবঃ

public class Facebook


{
private List userList;
public Facebook()
{
userList = new List();
userList.Add("Logical Forhad");
userList.Add("Rayhanur Rahman");
userList.Add("Maruf Khan");
userList.Add("Arif Raian");
userList.Add("Mahedi Mahfuj");
userList.Add("Atish Dipankar");
}
public List GetUserList()
{
return userList;
}
}

অন জন টুইটার ইউজার দর তথ েলা একিট Array ত রেখ কাজিট কের ফলেলা এইভােবঃ

Iterator িডজাইন প াটান 20


সফটওয় ার আিকেটকচার

public class Twitter


{
private String[] userList;
private const int MAX_USER = 6;
public Twitter()
{
userList = new string[MAX_USER];
userList[0] = "_iLogical";
userList[1] = "Amit Seal Ami";
userList[2] = "Crackbrained Sakkhor";
userList[3] = "Bazlur Rahman Rokon";
userList[4] = "Sachine Tendulkar";
userList[5] = "Shane Watson";
}

public String[] GetUserList()


{
return userList;
}
}

এরপর যখন তারা ফসবুক এবং টুইটােরর ইউজারেদর তথ েলা ােয় কােড দখেত চাইেলা তখন তারা িনেচর
কােডর মত কের দেখ িনেলাঃ

Iterator িডজাইন প াটান 21


সফটওয় ার আিকেটকচার

public class Program


{
static void Main(string[] args)
{
Facebook facebook = new Facebook();//concrete implementation
List<string> fbuserList = facebook.GetUserList();

Console.WriteLine("Facebook users........n");

for (int i = 0; i < fbuserList.Count; i++)


{
Console.WriteLine(fbuserList[i]);
}
Console.WriteLine("n");

Twitter twitter = new Twitter();//concrete implementation


String[] twitterUserList = twitter.GetUserList();
Console.WriteLine("Twitter users........n");

for (int i = 0; i < twitterUserList.Length; i++)


{
Console.WriteLine(twitterUserList[i]);
}

Console.ReadKey();
}
}

এখন দুইজন ডেভলপারই আলাদা আলাদা ডটা াকচার ব বহার কেরেছ ফসবুক এবং টুইটার এর ইউজারেদর তথ
রাখেত ।

অন িদেক তারা তােদর কাড এর ডটা াকচার চ করেত িব ু মা আ হী না। িক তারা য িডজাইন কেরেছ এই
িডজাইেন িকছু সমস া আেছঃ

আমরা টুইটার এবং ফসবুেকর কংি ট ইমি েমে শন করিছ, িক করার কথা ই ারেফস কািডং , কননা OOP
বেল Code to interface not to implementation. আমরা ােয় কােড অেনক েলা বয়লারে ট কাড িলেখ
ফেলিছ । ফসবুেকর জন একবার এর ইউজারেদর নাম লুপ চািলেয় ি কেরিছ আর একবার টুইটােরর জন
ইউজারেদর িল লুপ চািলেয় ি কেরিছ । মা া কথা একই কাজ দুই বার কেরিছ। গল ােসর ইউজারেদর তথ
ি করেত চাইেল আমােদর আেরকটা লুপ যাগ করেত হেব । ােয় কােডর জানেত হে তােক কত কার
ডটা াকচাের লুপ ঘুিরেয় ইউজারেদর তথ ি করেত হেব। ( যমন গল াস এর ইউজারেদর তথ ি করেত
চাইেল ােয় কাড ক ফসবুক+টুইটার+ গল াস = ৩ কার ডটা াকচার স েক জানেত হেব ) যটা OOP
এর Encapsulation ল এর ভােয়ােলশন । সমাধানঃ তাহেল আমরা এখন িক করেত পাির? চলুন একটু িচ া কির
। আ া এরকম হেল কমন হয় বলুন তা , একিট অবেজ যিদ য কানও কার ডটা াকচােরর উপর কাজ কের
সই ডটা াকচােরর ডটা েলা ি কের িদেত পাের তাহেলই তা আমােদর কাজ হেয় গেলা । তাহেল থম
ডেভলপার এবং ি তীয় ডেভলপার অথবা অন য কানও ডেভলপার য ডটা াকচার িনেয়ই কাজ ক ক না
কেনা আমােদর ঐ একিট মা অবেজ সব ডটা াকচােরর উপর ছিড় ঘুিড়েয় আমােদর ডটা েলা ি কের
িদেত পাের । হ া আমরা এখন এমনই একিট অবেজ বানােবা ।

Iterator িডজাইন প াটান 22


সফটওয় ার আিকেটকচার

যেহতু এিট সবার উপর কাজ করেব তাই এিটেক আমরা একিট ই ারেফস িহেসেবই রািখঃ

public interface ISocialNetworking


{
bool HasNext();
Object Next();
}

এখন আমরা দুিট class বানােবা যারা আমােদর সদ নতুন বানােনা ই ারেফসেক ইমি েম করেব ।

ফসবুেকর জন ঃ

public class FacebookIterator : ISocialNetworking


{
private List<String> userList;
private int _postion = 0;
public FacebookIterator()
{
userList = new List<string>();
userList.Add("Logical Forhad");
userList.Add("Rayhanur Rahman");
userList.Add("Maruf Khan");
userList.Add("Arif Raian");
userList.Add("Mahedi Mahfuj");
userList.Add("Atish Dipankar");
}
public bool HasNext()
{
return userList.Count() > _postion;
}

public object Next()


{
String element = userList.ElementAt(_postion++);

return element;
}
}

টুইটােরর জন ঃ

Iterator িডজাইন প াটান 23


সফটওয় ার আিকেটকচার

public class TwitterIterator : ISocialNetworking


{
private String[] userList;
private const int MAX_USER = 6;
private int position = 0;
public TwitterIterator()
{
userList = new string[MAX_USER];
userList[0] = "_iLogical";
userList[1] = "Amit Seal Ami";
userList[2] = "Crackbrained Sakkhor";
userList[3] = "Bazlur Rahman Rokon";
userList[4] = "Sachine Tendulkar";
userList[5] = "Shane Watson";
}

public bool HasNext()


{
return userList.Length > position;
}

public object Next()


{
String element = userList[position++];
return element;
}
}

এখন আমােদর ােয় কােড আমরা ই ারেফসিটেক এভােব ইউজ করেত পািরঃ

Iterator িডজাইন প াটান 24


সফটওয় ার আিকেটকচার

public class Program


{
static void Main(string[] args)
{

Console.WriteLine("Facebook users........n");
ISocialNetworking iterator = new FacebookIterator();
while (iterator.HasNext())
{
Console.WriteLine(iterator.Next());
}
Console.WriteLine("n");

iterator = new TwitterIterator();


Console.WriteLine("Twitter users........n");
while (iterator.HasNext())
{
Console.WriteLine(iterator.Next());
}
Console.ReadKey();
}
}

দাঁড়ান এখােনই শষ না আমরা আমােদর িডজাইনিটেক আরও ভােলা করেত পাির । আমােদর Twitter class টীেক
আমরা এভােব মািডফাই করেত পাির যখােন আমরা একিট নতুন মথড যাগ কেরিছ যার কাজ হে আমােদর
ই ারেফসিটেক(ISocialNetworking) িরটান করা ।

সা মািডফাইড Twitter class িট এরকমঃ

public class Twitter


{
private String[] userList;
private const int MAX_USER = 6;
public Twitter()
{
userList = new string[MAX_USER];
userList[0] = "_iLogical";
userList[1] = "Amit Seal Ami";
userList[2] = "Crackbrained Sakkhor";
userList[3] = "Bazlur Rahman Rokon";
userList[4] = "Sachine Tendulkar";
userList[5] = "Shane Watson";
}

public ISocialNetworking GetIterator()


{
return new TwitterIterator();
}
}

Iterator িডজাইন প াটান 25


সফটওয় ার আিকেটকচার

এবং মািডফাইড Facebook class িট হে এরকমঃ

public class Facebook


{
private List<String> userList;
public Facebook()
{
userList = new List<string>();
userList.Add("Logical Forhad");
userList.Add("Rayhanur Rahman");
userList.Add("Maruf Khan");
userList.Add("Arif Raian");
userList.Add("Mahedi Mahfuj");
userList.Add("Atish Dipankar");
}

public ISocialNetworking GetIterator()


{
return new FacebookIterator();
}
}

এখন সবেশেষ আমােদর ােয় কাড চ হেয় দাঁড়ােব এরকমঃ

Iterator িডজাইন প াটান 26


সফটওয় ার আিকেটকচার

public class Program


{
static void Main(string[] args)
{
ISocialNetworking iterator;

Facebook facebook = new Facebook();


Twitter twitter = new Twitter();

iterator = facebook.GetIterator();

Console.WriteLine("Facebook users........n");
while (iterator.HasNext())
{
Console.WriteLine(iterator.Next());
}
Console.WriteLine("n");

iterator = twitter.GetIterator();

Console.WriteLine("Twitter users........n");
while (iterator.HasNext())
{
Console.WriteLine(iterator.Next());
}
Console.ReadKey();
}
}

ব স হেয় গেলা আমােদর Iterator িডজাইন প াটান । িক আমরা এই ছা িডজাইন প াটান িশখেত িগেয় িনেজ
িনেজই আমােদর Iterator বািনেয় িনেয়িছ যটা ায় সব ল া ুেয়েজই আেগ থেকই বািনেয় রাখা আেছ। .NET এ এই
ই ারেফসিটর নাম হে IEnumerator। ডটা াকচার য রকমই হাক না কেনা ,এটা সব Collection এর উপর
কাজ করেত পাের।

এিট ব বহার করেল আমােদর FacebookIterator ,TwitterIterator এবং ISocialNetworking এ েলা আর


লাগেব না িক Facebook এবং Twitter class এ িকছু টা চ করেত হেব ।

মািডফাইড ফসবুকঃ

Iterator িডজাইন প াটান 27


সফটওয় ার আিকেটকচার

public class Facebook


{
private List<String> userList;
public Facebook()
{
userList = new List<string>();
userList.Add("Logical Forhad");
userList.Add("Rayhanur Rahman");
userList.Add("Maruf Khan");
userList.Add("Arif Raian");
userList.Add("Mahedi Mahfuj");
userList.Add("Atish Dipankar");
}

public IEnumerator GetIterator()//introducing IEnumurator


{
return userList.GetEnumerator();
}
}

মািডফাইড টুইটারঃ

public class Twitter


{
private String[] userList;
private const int MAX_USER = 6;
public Twitter()
{
userList = new string[MAX_USER];
userList[0] = "_iLogical";
userList[1] = "Amit Seal Ami";
userList[2] = "Crackbrained Sakkhor";
userList[3] = "Bazlur Rahman Rokon";
userList[4] = "Sachine Tendulkar";
userList[5] = "Shane Watson";
}

public IEnumerator GetIterator()//introducing IEnumurator


{
return userList.GetEnumerator();
}
}

এবং সবেশেষ আমােদর ােয় কাড সামান একটু মািডফাইড হেয় এরকম হেবঃ

Iterator িডজাইন প াটান 28


সফটওয় ার আিকেটকচার

public class Program


{
static void Main(string[] args)
{
IEnumerator iterator;//changed

Facebook facebook = new Facebook();


Twitter twitter = new Twitter();

iterator = facebook.GetIterator();

Console.WriteLine("Facebook users........n");
while (iterator.MoveNext())
{
Console.WriteLine(iterator.Current);
}
Console.WriteLine("n");

iterator = twitter.GetIterator();

Console.WriteLine("Twitter users........n");
while (iterator.MoveNext())
{
Console.WriteLine(iterator.Current);
}
Console.ReadKey();
}
}

তাহেল এই িছেলা আমােদর Iterator িডজাইন প াটান । খুবই সহজ এবং ছাট একিট িডজাইন প াটান যিট য
কানও Collection এর উপর কুমদারী করেত পাের :)

হ ািপ কািডং :)

Iterator িডজাইন প াটান 29


সফটওয় ার আিকেটকচার

চইন অফ র পি িবিলিট
েত কটা িডজাইন প াটােনরই উ ব হেয়েছ মূলত এক একিট সমস ার সমাধান সবেচেয় ভালভােব সমাধান করার
জন ।

সফটওয় ার ইি িনয়ািরং এ CodeReuse বলেত যটা বাঝায় সটা িডজাইন প াটানই সবেচেয় ভালভােব স
কের । আমােদর দনি ন জীবেন নানা ভােব ছিড়েয় িছিটেয় আেছ িডজাইন প াটান । একটু ভালভােব খয়াল কের
িচ াকরেলই ধরাযায় প াটান েলা ।

এই যমন কেয়ক িদন আেগই আমার অিফেসর সবাই টু ের ভুটান ঘুের এল । আিম য ােজে িছলাম সিটও
কমি ট হেয় িগেয়িছল । ভাবলাম এই ফােক ােম িগেয় ঘুের আসেল ম হয় না । আমার েজ ম ােনজােরর কােছ
৫ িদেনর ছু িটর জন দরখা িনেয় গলাম । আমােদর িত উইেক ওয়ািকং ড হে ৫ িদন । অিফেসর িনয়ম হে
এক স াহ ছু িটর জন ১ মাস আেগ থেক বেল রাখেত হয় । আমার েজ ম ােনজার দরখাে ৫ িদন দেখ বলেলন
৩ িদন হেল আিম এখনই তামােক ছু িট িদেয় িদতাম । যেহতু তুিম ৫ িদন ছু িট চা সেহতু তামােক িরেসাস
ম ােনজােরর কাছ থেক ছু িট িনেত হেব । ৩ িদেনর বিশ ছু িট দয়া আমােদর এখিতয়াের নই।

আবার একজন বড় ভাই বলেলন য ১ িদেনর ছু িট হেল তুিম তামার িটম িলডােরর কাছ থেকই িনেত পারেত ।

এরপর আিম িরেসাস ম ােনজােরর কাছ থক দরখা িনেয় গলাম , উিন খুিশ মেন আনে র সিহত ছু িট এ ভ
করেলন । আিমও খুিশেত ডগমগ হেয় ােম চেল গলাম ।

তা ব াপারটা িক দাঁড়াল । আমার যিদ ১ িদেনর ছু িটর দরকার হত আিম আমার িটম িলডােরর কাছ থেকই িনেত
পারতাম । আবার ৩ িদেনর ছু িটর দরকার হেল েজ ম ােনজােরর কাছ থেকই িনেত পারতাম । এর চেয় বিশ ছু িট
হেল হয়ত এডিমন অথবা অন কানও ঊ তন কমকতার কােছ থেকই িনেত হত ।

চলুন আমরা কােড িজিনস েলা িলেখ ফিল । সবার থেম আমােদর দরকার হেব একিট Response নােম enum
এর । enum হে জা একটা টাইপ । য আমার িরেকােয় এ ভড না িডনােয়ড ।

public enum Response


{
Approved,
Denied
}

এখন আেরকিট ব াপার দখা যাে য আমার িটম িলডার / ােজ ম ােনজার অথবা িরেসাস ম ােনজার সবারই
একিট মতা হে ছু িট Approve করা এবং রজা দয়া য ছু িট ম ুর না নাম ুর । তাহেল যেহতু সবারই একটা
কমন বিশ হে ছু িট Approve করা তাহেল আমরা একিট interface বানাই যার একিট মথড থাকেব Approve
নােম এবং এই মথড একিট Response নােম enum িরটান করেব এবং প ারািমটার িহেসেব যােক এ ভ করেব
তার একটা রফাের থাকেব । এে ে Employee আমরা interface িটর নাম দই IApprover :

চইন অফ র পি িবিলিট 30
সফটওয় ার আিকেটকচার

public interface IApprover


{
Response Approve(Employee employee);
}

আ া আিম য দরখা িট িনেয় িগেয়িছলাম তার মেধ িক িছেলা ??ধের িনলাম এর মেধ িছেলা আমার নাম আর
কয়িদন ছু িট দরকার সটা । আিম তা আর আমার নােম class িলখেত পাির না । এ জন class এর নাম িদলাম
Employee .যার দুিট পািট একিট হে Name অন িট Days. Employee class িট িঠক এরকমঃ

public class Employee


{
public String Name { get; set; }
public int Days { get; set; }
public Employee(String name, int days)
{
Name = name;
Days = days;
}
}

এখন আমরা এর আেগ য interface টা বািনেয় িছলাম সই interface টা implement করেব আমার
TeamLeader এবং ProjectManager এবং তােদর কােছ Employee এর একটা রফাের থাকেব কননা আিম
য দরখা িনেয় িগেয়িছলাম সিট আসেল আমােকই িরে েজ কের ।

সা একদেম আমরা দেখ ফিল IApprover implement করার পর TeamLeader এবং ProjectManager
class দুেটা কমন দখায় । TeamLeader class িট এরকমঃ

public class TeamLeader : IApprover


{
public Response Approve(Employee employee)
{
if (employee.Days == 1)
return Response.Approved;
return Response.Denied;
}
}

ProjectManager class িট এরকমঃ

চইন অফ র পি িবিলিট 31
সফটওয় ার আিকেটকচার

public class ProjectManager : IApprover


{
public Response Approve(Employee employee)
{
if (employee.Days <= 3 && employee.Days >= 1)
return Response.Approved;
return Response.Denied;
}
}

TeamLeader এবং ProjectManager উভেয়র Approve মথেডর মধ Employee এর কত িদন ছু িট দরকার


তা চক কেরিছ । যিদ ছু িটর িদন TeamLeader এর এখিতয়ার এর বাইের হয় তাহেল তাহেল স Denied িরটান
করেব আর এখিতয়াের থাকেল Approved িরটান করেব । এরকম ভােব ProjectManager এর ে ও েযাজ

এখন আমােদর ClientCode দখা যাক ।

public class Program


{
public static void Main(string[] args)
{
Employee employee = new Employee("Forhad", 4);

IApprover approver = new TeamLeader();

Response responses = approver.Approve(employee);

if (Response.Approved != responses)
{
approver = new ProjectManager();
responses = approver.Approve(employee);
if (Response.Approved == responses)
{
Console.WriteLine("Request Granted Have A nice journey Mr:{0}", employee.Name);
}
else
{
Console.WriteLine("Sorry Your Request was not granted Mr:{0}", employee.Name);
}
}
else
{
Console.WriteLine("Request Granted Have A nice journey Mr:{0}", employee.Name);
}

}
}

চইন অফ র পি িবিলিট 32
সফটওয় ার আিকেটকচার

ClientCode এ আমরা আসেল িক কেরিছ??

আমরা Employee এর একটা অে বািনেয়িছ । OOP এর Inheritance ব বহার কের আমরা IApprover মেধ
TeamLeader এর অবেজ বািনেয় রেখিছ । এর পর আমরা IApprover এর Approve() মথড এর মেধ িদেয়
আেগ Employee এর বানােনা অবেজ িট রফাের িহেসেব Pass কের কল কেরিছ । আমরা জািন Approve
মথড Response নামক enum িরটান কের । আমরা Response টা enum এ রেখিছ ।

এর পর চক কেরিছ যিদ Response টা Approved হয় তাহেল আমরা ছু িট া Emplyee ক Greetings


কেরিছ । আর Response টা Denied হেল আমরা ProjectManager এর কােছ িগেয়িছ তার পর একই
প িতেত আমরা চক কেরিছ িতিন ছু িট এ ভ কেরেছন না কেরনিন । এ ভ করেল আবারও আমরা Employee
ক Greetings জািনেয়িছ অন িদেক Approve না হেল দুঃখ কাশ কেরিছ ।

এখােন ল ণীয় িবষয় হে ClientCode ক সব সময় জানেত হে Employee ক থেম কার কােছ ছু িটর জন
যেত হেব , স ছু িট িদেত না পারেল তারপর কার কােছ যেত হেব স না পারেল তারপর কার কােছ যেত হেব ।

এই য এত ণ আমরা কাড করলাম এই িডজাইন টা হে বােজ একটা িডজাইন । আমােদর নতুন কারও কােছ
যাওয়া লাগেল আমােদর ClientCode এ চ করেত হেব । আরও বশ কেয়কটা মহা শ ক আমদািন করেত হেব
(মােন if else) J । মেন ক ন এমন একটা কা ািনেত ছু িট চাইেত গেলন অথবা অন কানও িরেকােয় এর জন
গেলন যখােন এই রকম ১০০ জন ঊ তন কমকতার কােছ দৗড়ােদৗিড় করেত হেত পাের । ঐ কা ািনর জন এই
রকম একটা এি েকশন বানােত গেল আপনােক ঐ ১০০ জন কমকতার অবেজ বানােত হেব িতবারই যখনই
আপনার দরকার হেব তােদর কাছ থেক কানও রজা জানার জন হেত পাের সটা ছু িট / লান / বােজট ইত ািদ
ইত ািদ ।

এটা খুবই বােজ একটা ব াপার হেব ।

তাহেল আসুন আমরা আমােদর িডজাইনটােক একটু চ কির ।

আমরা IAppover ই ারেফসটােক একটু চ কির । আমরা এখােন ই ারেফসটার িনেজরই মত একটা রফাের
রেখ িদেত পাির যােত কের য এটােক ইমি েম করেব স যিদ িরেকােয় া করেত না পাের (এে ে ছু িট দয়ার
ব পারটা) স অন একজনেক HandOver কের িদেব য ন বাবা আিম পারলাম না , দখ ছেলটােক তুই যিদ ছু িট
িদেত পািরস ।

এভােব একজন না পারেল আেরকজন ক িদেয় িদেব এভােব চলেত থাকেব । মােন Responsibility এর Chaining
হে ।

তাহেল আমােদর IApprover ই ারেফসটা এরকমঃ

public interface IApprover


{
Response Approve(Employee employee);
IApprover NextApprover { get; set; }
}

এখন তাহেল আমােদর

TeamLeader class এর ইমি েমনেটশন িগেয় দাঁড়ােব এরকমঃ

চইন অফ র পি িবিলিট 33
সফটওয় ার আিকেটকচার

public class TeamLeader : IApprover


{
public Response Approve(Employee employee)
{
if (employee.Days == 1)
return Response.Approved;
return NextApprover.Approve(employee);
}

public IApprover NextApprover { get; set; }


}

এখােন আমরা ধু মা TeamLeader যিদ ছু িট এ ভ করেত না পাের তাহেল স NextApprover এর কােছ


দািয় চািপেয় িদেয়েছ NextApprover.Approve(employee);

এই লাইনটা িদেয় ।

একই ভােব ProjectManager এর ইমি েমে শন িগেয় দাঁড়ােব এরকমঃ

public class ProjectManager : IApprover


{
public Response Approve(Employee employee)
{
if (employee.Days <= 3 && employee.Days >= 1)
return Response.Approved;
return NextApprover.Approve(employee);
}
public IApprover NextApprover { get; set; }
}

একই ভােব আমরা আেরকিট ResourceManager নােম class বািনেয় ফিল আমােদর উদাহরণ দয়ার সুিবধার
জন । এইভােবঃ

public class ResourceManager : IApprover


{
public Response Approve(Employee employee)
{
if (employee.Days >= 7)

return Response.Approved;

return NextApprover.Approve(employee);
}
public IApprover NextApprover { get; set; }
}

চইন অফ র পি িবিলিট 34
সফটওয় ার আিকেটকচার

এখন মেন ক ন আমােদর অিফেস এমন একজন ক িঠক করা হেলা য িকনা সবার িরেকােয় হন করেব / হ াে ল
করেব । আমােদর আর TeamLeader,ProjectManager,ResourceManager এর কােছ যাওয়ার েয়াজন নই
। RequestHandler class এ আমােদর সব কের িদেব । আমরা ধু তার কােছ িগেয় আমেদর েয়াজেনর কথা
বলব। স কাথা থেক / কার কাছ থেক আমােদর িরেকােয় এ ভ করােয় আনেব তা আমােদর দখার িবষয় না ।

আমােদর RequestHandler class টা এরকমঃ

public class RequestHandler : IApprover


{
public Response Approve(Employee employee)
{
return NextApprover.Approve(employee);
}
public IApprover NextApprover { get; set; }
}

এখােন ল নীয় ব পার হে RequestHandler িক কানও চিকং না কেরই ন ট এ ভার এর কােছ এ ভ


করার জন িরেকােয় Redirect করেছ ।

করেছ এখন আমােদর চইন িঠক কের দয়ার পালা । এখােন আমােদর যটা করেত হেব সটা হে একজন িরেকােয়
না এ ভ করেত পারেল স কার কােছ িরেকােয় টা পাঠােব , আবার যার কােছ পাঠােলা স না পারেল কার কােছ
পাঠােব এভােব চইিনং চলেত থাকেব ।

আমরা একটা মথড বানাই য ধুমা চইন তির কের িদেবঃ

private static IApprover CreateChain()


{
IApprover handler = new RequestHandler();
IApprover approver1 = new TeamLeader();
IApprover approver2 = new ProjectManager();
IApprover approver3 = new ResourceManager();
handler.NextApprover = approver1;
approver1.NextApprover = approver2;
approver2.NextApprover = approver3;
return handler;
}

এখােন আমরা থেম RequestHandler এর অবেজ বািনেয়িছ যার কােছ আমরা িরেকােয় করব ছু িটর জন ।
এর পর পরপর আমরা TeamLeader,ProjectManager,ResourceManager এর অবেজ বািনেয়িছ । এর
পর চইিনং এর পালা ।

Handler তার NextApprover সট করেব (মােন িরেকােয় Redirect করেব )TeamLeader এর অবেজ
(approver1) এর কােছ , TeamLeader এ ভ করেত না পারেল স তার NextApprover সট করেব (মােন
িরেকােয় Redirect করেব ) ProjectManager এর কােছ , িঠক একই ভােব ProjectManager না পারেল
করেব ResourceManager এর কােছ । এটাই হে Chaining

চইন অফ র পি িবিলিট 35
সফটওয় ার আিকেটকচার

এর পর একটা রজা িনেয় RequestHandler ব াক করেব য তার কােছ কল কেরিছেলা তার কােছ ।

আমরা আমােদর পুেরা ClientCode টা দেখ ফিলঃ

public class Program


{
private static IApprover CreateChain()
{
IApprover handler = new RequestHandler();
IApprover approver1 = new TeamLeader();
IApprover approver2 = new ProjectManager();
IApprover approver3 = new ResourceManager();
handler.NextApprover = approver1;
approver1.NextApprover = approver2;
approver2.NextApprover = approver3;
return handler;
}

public static void Main(string[] args)


{
var employee = new Employee("Forhad", 7);

IApprover handler = CreateChain();

Response response = handler.Approve(employee);

if (response == Response.Approved)
{
Console.WriteLine("Have A nice Journey Mr:{0}", employee.Name);
}
else if (response == Response.Denied)
{
Console.WriteLine("Sorry Mr:{0} We are busy now", employee.Name);
}
Console.ReadLine();
}
}

দেখ এখন হে এই Chaining ভাঙেবা িকভােব ??

আমরা এই Chaining ভাঙেবা এেকবাের Chain এর সবার শেষ য আেছ স য

return NextApprover.Approve(employee); িরটান কেরিছেলা সটা িরটান না কের ধুমা


Response.Denied য িরটান করেলই Chain ভে যােব । আর চইন ক না করেল সবার শেষর Chain এ য
থােক স তার Responsibility Chain এর পেরর জনেক িদেয় িদেব । তার পের Chain এ তা কঊ নই । তাহেল
আপনারা হি একটা Exception খােবন ( াই কেরই দেখন :) ) । এেকবাের Null Exception :)

এই য পুেরা পা জুেড় আমরা য Chain , Chain Responsibility , Responsibility করলাম এটাই হে


Chain Of Responsibility িডজাইন প াটান

চইন অফ র পি িবিলিট 36
সফটওয় ার আিকেটকচার

ভােলা কথা ছু িট িক আিম পেয়িছলাম ৫ িদন ।

ভুটােন যাওয়ার চেয় ৫ মাস পর আমার াম , আমার মােয়র মুখ দখা আমার কােছ বিশ ভােলালাগার িছেলা :)

চইন অফ র পি িবিলিট 37
সফটওয় ার আিকেটকচার

অবজারভার প াটান
মুলত অবেজ অিরেয়ে ড া ািমং হে অবেজে র এর িবিভ অব া এবং এেদর মােঝ িবিভ রকেমর
ই ােরকশন এর সমি । একিট অবেজ িক অব ায় আেছ , এই অবেজে র সােথ অন অবেজে র িরেলশন িক এরা
িকভােব এেক অপেরর সােথ যাগােযাগ কের এ েলাই হে অবেজ অিরেয়ে ড া ািমং এর িবষয়ব । একজন
অবেজ অিরেয়ে ড া ামারেক এই ব াপার েলা কােডর মাধ েম দ তার সােথ হ াে ল করেত হয় ।

অেনক সময় দখা যায় আমােদর এি েকশেন একিট অবেজে র কানও পািট চ হেল আমােদর িকছু কাজ করেত
হয় অথবা অন কানও অবেজ েক নািটিফেকশন পাঠােত হয় ।

নািটিফেকশন পাবার পর ঐ অবেজ েলােক িকছু কাজ করেত হয় । যমন িবিভ মাবাইল অপােরটররা তােদর
প ােকজ চ করেল অথবা নতুন অফার বাজাের ছাড়েল তা আমােদর এস এম এস এর মাধ েম জািনেয় দয় ।

অবজারভার প াটােনর ে আমােদর দুিট িজিনস মেন রাখা জ রী একিট হে Subject এবং অন িট হে
Observer . উপেরর উদাহরণ এর ে আমরা যারা িবিভ অপােরটেরর িসম ব বহার কির তারা হি Observer
এবং মাবাইল অপােরটর হে Subject . Subject এর একিট পািট যমন প ােকজ চ হেলই আমরা যারা
Observer তারা নািটিফেকশন পাই । এে ে আমরা যারা Observer তারা হি Subject এর উপর িডেপে

GOF এর সং া অনুযায়ী Observer Pattern হে ঃ “Define a one-to-many dependency between


objects so that when one object changes state, all its dependents are notified and updated
automatically.”

অথাৎ Subject এবং Observer এর মধ এমন একিট িরেলশন তির করা যােত কের যখনই Subject চ হেব
তখনই Automatically Observer েলা নািটিফেকশন পেয় যােব ।

খুব দূের না িগেয় চলুন এই গ িদেয়ই একটা উদাহরণ দয়া যাক ।

ত কিট েগই একটা Subscribe অপশন থােক কউ যিদ এই গ থেক নতুন পা পেত চায় তােক ধুমা
ইেমইেলর মাধ েম Subscribe করেত হেব । েগ নতুন কানও পা এেল সই পাে র িলংক অেটােমিটক ািল তার
সই ইেমইেল চেল যােব । েগ ঢু েক তােক আর বার বার চক করেত হেব না য নতুন কানও পা এেসেছ িকনা ।
ওয়াডে েস এই মিডউলটা বািনেয়ই দয়া আেছ ।এখন আমরা যিদ ওয়াডে স এর এই মিডউলটার মত একিট
মিডউল িনেজরা বানােত চাই , তাহেল িকভােব বানােবা । ??

চলুন দেখ আিস ।

েগ যেহতু অেনক Subscriber থাকেত পাের এবং তােদর সবারই একটা কমন পািট থাকেব নাম । এবং সবাই
িকছু মেসজ পােব এর Subject এর কাছ থেক । ধরা যাক GetNotification() মথেডর মাধ েম স িকছু মেসজ
পােব। তাহেল এই িজিনস েলা আমরা একটা ই ারেফস এ রেখ িদই ।

তাহেল আমােদর ই ারেফসটা দাঁড়ােব এরকমঃ

অবজারভার প াটান 38
সফটওয় ার আিকেটকচার

public interface ISubscriber


{
void GetNotification(String postTitle);
String Name { get; set; }
}

এখন পাে র কেমে কউ যিদ াম অথবা কানও বােজ কেম কেরন এ েলা দখার জন একজন Moderator
থাকেব । এই Moderator ও িক একজন Subscriber. সা আমােদর Moderator ISubscriber ক এ েট
করেব এইভােব:

public class Moderator : ISubscriber


{
public String Name { get; set; }
public Moderator(String name)
{
Name = name;
}
public void GetNotification(String postTitle)
{
Console.WriteLine("Hello Mr:{0} A new post named {1} has been posted in the blognyou need
}
}

এভােব েগর সাধারন একজন User বানাই য িকনা ISubscriber ক এ েট করেবঃ

public class User : ISubscriber


{
public String Name { get; set; }
public User(String name)
{
Name = name;
}
public void GetNotification(String postTitle)
{
Console.WriteLine("Hey {0} Checkout the new post named {1}", Name, postTitle);
}
}

এখন আমােদর Blog এর Subscriber দর নািটিফেকশন পাঠােনার কাড টুকু িলেখ ফিলঃ

অবজারভার প াটান 39
সফটওয় ার আিকেটকচার

public class Blog


{
private String _postTitle;
public String PostTitle
{
get
{
return _postTitle;
}
set
{
if (_postTitle != value)
{
_postTitle = value;
NotifySubscribers();
}
}
}
private void NotifySubscribers()
{
ISubscriber observer = new User("Forhad");
observer.GetNotification(_postTitle);
observer = new Moderator("Modu");
observer.GetNotification(_postTitle);
}
}

এখােন আমরা আমােদর েগর পাে র একিট টাইেটল এর জন Getter এবং Setter বািনেয়িছ । Setter এর মধ
আমরা চক কেরিছ টাইেটলটা আেগর কানও টাইেটেলর সােথ িমেল যায় িকনা । িমেল না গেল আমরা আমােদর
টাইেটেল নতুন টাইেটলিট সট কেরিছ এবং নতুন পা টাইেটল সট করার সােথ সােথ NotifySubscribers()
মথডিট কল কেরিছ । NotifySubscribers() এর মধ আমরা ISubscriber এখােন িদেয় আমােদর েগর জন
User এবং Moderator বািনেয়িছ এবং উভেয়র GetNotification() মথেডর মধ িদেয় পা এর টাইেটল িট স
কের িদেয়িছ ।

এখন আমােদর ClientCode িট দখা যাক :

public class Program


{
public static void Main(string[] args)
{
Blog blog = new Blog ();
blog.PostTitle = "ObserverPattern";
Console.ReadLine();
}
}

অবজারভার প াটান 40
সফটওয় ার আিকেটকচার

যাক আমরা যখনই গ পাে র টাইেটল সট করলাম তখনই স Blog এর াইেভট মথড NotifySubscribers()
কল কেরেছ এবং এই মথেডর মধ স Blog এর সব Subscriber এর অবেজ বািনেয় তােদর নতুন পাে র
টাইেটল পািঠেয় িদেয়েছ ।

ব স হেয় গেলা আমােদর েগর মিডউল বানােনার কাজ । এরই মধ আিম এই মিডউলিট একিট CMS বানায়
এরকম একিট কা ানীর কােছ িবি কের িদলাম এবং সাসেকাড এর বদেল আিম এেক একিট ClassLibrary
(DLL) বািনেয় িদেয় দয়ার আেগ আিম DLL এর ভতর সাস কাড েলা Obfuscated Code সাস মােন যেনা
Decompile/Reverse Engineering কেরও সাস কাড উ ার করেত না পাের এরকম কের িদলাম ।

ঐ CMS কা ানী নতুন একধরেনর Subscriber বানােত চাইেলা ধরা যাক Administrator । এখন িকভােব স
নতুন টাইেপর Subscriber বানােব । আিম য DLL তােক িদেয় িদেয়িছলাম স ঐটা িদেয় নতুন টাইেপর
Subscriber বানােত পারেবনা । কননা নতুন Subscriber বানােত হেল তােক Blog class টােত চ করেত হেব
। Administrator নােম একিট class বািনেয় তােক Blog class এর NotifySubscribers() মথেডর মধ এর
অবেজ বানােত হেব তারপর GetNotification() কল করেত হেব । এইভােব তােক নতুন টাইেপর Subscriber
বানােত হেব । িক আমার DLL এ স ধু Blog class এবং PostTitle এে স করেত পারেব তা ছাড়া আর িকছু
পারেব না । তার মােন আমার দয়া DLL তার কানও কােজ আসেব না ।

আর আিম যিদ DLL না বািনেয়ও ধু মা সাস কাড সহ িদেয় িদতাম তাহেলও এিট একিট বােজ িডজাইন হেতা ।
কননা এিট SOLID ি ি পােলর OCP (Open Closed Principle) এর ভােয়ােলশন করেতা ।

OCP আমােদর বেল য একিট াস/ মথড আমরা এমন ভােব িলখব যােত কের আমরা চাইেলই এ েট করেত
পারেবা িক মািডিফেকশন করেত পারেবা না ।

েত কবার আমােদর Blog class এর NotifySubscribers() মািডিফেকশন করেত হেব নতুন টাইেপর
Subscriber যাগ করার জন ।

খুব াভািবকভােবই কা ািনিট আমােক আমার ClassLibrary এর িডজাইন চ কের িদেত বলেলা । আিম
কেয়কিদন সময় চেয় িনলাম িডজাইন িঠক কের দয়ার জন ।

তাহেল আসুন আমরা সবাই িমেল িডজাইনটা চ করার চ া কের দিখ পাির িক না ।

থেম আমরা NotifySubscribers() মথড এর িদেক নজর িদই । আমরা দখেত পােবা অেনক েলা হাড
কােডড অবেজ বানােনা আেছ । আমরা চাি আমরা ClientCode থেক অবেজ বানােবা কানও মথেডর
মাধ েম । তাহেল য কা ািন Blog এর অবেজ বানােব এবং আমােদর বানােনা মথেডর মাধ েম যত ই া তত
রকেমর তত কােরর Subscriber যাগ করেত পারেব তােদর মিডউেলর জন । মেন কির এই নতুন মথেডর নাম
Subscribe() এবং এই মথড প ারািমটার িহেসেব ISubscriber নয় ।

তাহেল আমােদর NotifySubscribers() মথেডর মধ আর কােনাও হাডেকােডড অবেজ থাকেলা না । িক এই


খািল মথেডর তা িকছু একটা করা লাগেব । আমরা যা করেত পাির তা হে Blog এর মেধ আমােদর যত েলা
Subscriber আেছ সবাইেক নতুন পাে র খবরটা পািঠেয় িদেত পাির । তাহেল আমােদর এই Blog class এ সকল
Subscriber এর একটা িল থাকেব । অথাৎ আমােদর ISubscriber টাইেপর একটা িল রাখেলই হে এই
class এ কননা সকল টাইেপর Subscriber ই ISubscriber ক ইমি েম কের ।

Subscribe() মথেডর মধ আমরা য ISubscriber ক পািঠেয়িছলাম ঐ ISubscriber ক আমরা আমােদর


িলে এড কের িনেবা । এভােব ClientCode থেক আমরা যত খুিশ Subscriber এড কের িনেত পারেবা ।

অবজারভার প াটান 41
সফটওয় ার আিকেটকচার

তাহেল আমরা NotifySubscribers() এর মধ একটা লুপ চািলেয় সকল ISubscriber এর GetNotification()


কল করেলই হেয় যাে । GetNotification() এর প ারািমটার িহেসেব Blog class এর _postTitle তা আেছই ।
তাহেল আমােদর নতুন িডজাইন Blog class টা আমরা দেখ ফিলঃ

public class Blog


{
private String _postTitle;
private readonly List<ISubscriber> _subscribers;

public Blog()
{
_subscribers = new List<ISubscriber>();
}
public String PostTitle
{
get
{
return _postTitle;
}
set
{
if (_postTitle != value)
{
_postTitle = value;
NotifySubscribers(_subscribers);
}
}
}

public void Subscribe(ISubscriber subscriber)


{
_subscribers.Add(subscriber);
}

private void NotifySubscribers(List<ISubscriber> subscribers)


{
foreach (ISubscriber subscriber in subscribers)
{
subscriber.GetNotification(_postTitle);
}
}
}

তাহেল আমােদর ClientCode কমন হেলা একটু দেখ আিসঃ

অবজারভার প াটান 42
সফটওয় ার আিকেটকচার

public class Program


{
public static void Main(string[] args)
{
Blog blog = new Blog();

blog.Subscribe(new Moderator("Modu"));

blog.Subscribe(new User("Forhad"));

blog.PostTitle = "Observer Pattern";

Console.ReadLine();
}
}

এখন যিদ আিম আমার ClassLibrary টা ঐ কা ািন ক দই । তারা নতুন টাইেপর Subscriber যাগ করার
জন এর class বানােব যিট ISubscriber ক ইমি েম কের তারপর ClientCode এ Blog এর একিট অবেজ
বানােব এবং এর Subscribe মথেডর ভতর িদেয় নতুন টাইেপর Subscriber এর অবেজ িদেয় িদেব তারপর পা
এর টাইেটল সট করেলই Blog এর Subscriber সবাই পেয় যােব । এভােব যত খুিশ তত Subscriber এড করা
যােব । যিদ কাউেক আমরা Blog থেক ব ান করেত চাই তখন আমরা Blog এ আেরকিট মথড িলখব
UnSubscribe এ নােম যিটও িকনা Subscribe মথেডর মত একিট ISubscriber এর একিট রফাের িনেব
এবং এর মেধ আমরা আমােদর িল থেক এিটেক িরমুভ করেবা । তাহেল এই Subscriber আর নতুন পাে র
মেসজ পােব না ।

আবার আমরা সব সময় Blog class টা ইউজ করিছ । কা ানী যিদ নতুন কানও class বািনেয় কাজ েলা
করেত চায় তাহেল তারা পারেবনা । কারন সকল মথড লিজক Blog class এ । আমরা ই া করেল এই
মথড েলা একিট ই ারেফস এ িনেয় যেত পাির । যােত কের য কউ ই া করেল এই ই ারেফস ক ইমি েম
কের কাজ করেত পাের ।

তাহেল চলুন িলেখ ফিল আমােদর Unsubscribe মথডঃ

অবজারভার প াটান 43
সফটওয় ার আিকেটকচার

public class Blog


{
private String _postTitle;
private readonly List<ISubscriber> _subscribers;

public Blog()
{
_subscribers = new List<ISubscriber>();
}
public String PostTitle
{
get
{
return _postTitle;
}
set
{
if (_postTitle != value)
{
_postTitle = value;
NotifySubscribers(_subscribers);
}
}
}

public void Subscribe(ISubscriber subscriber)


{
_subscribers.Add(subscriber);
}

public void UnSubscribe(ISubscriber subscriber)


{
_subscribers.Remove(subscriber);
}

private void NotifySubscribers(List<ISubscriber> subscribers)


{
foreach (ISubscriber subscriber in subscribers)
{
subscriber.GetNotification(_postTitle);
}
}
}

তাহেল আমােদর ClientCode হেব এরকমঃ

অবজারভার প াটান 44
সফটওয় ার আিকেটকচার

public class Program


{
public static void Main(string[] args)
{
Blog blog = new Blog();

ISubscriber user = new User("DemoUser");


ISubscriber moderator = new User("Modu");
blog.Subscribe(moderator);
blog.Subscribe(user);
blog.PostTitle = "Observer Pattern";

blog.UnSubscribe(moderator);//we unsubscribed themoderator


blog.PostTitle = "Singleton";
Console.ReadLine();
}
}

এখন আমরা Blog class থেক এর মথড েলা আলাদা একটা ই ারেফস এ িনেয় যাই ।

এর নাম িদই IObservable:

public interface IObservable


{
void Subscribe(ISubscriber subscriber);
void UnSubscribe(ISubscriber subscriber);
void NotifySubscribers(List<ISubscriber> subscribers);
}

এখন আমরা আমােদর ফাইনাল কাড দেখ ফিলঃ

অবজারভার প াটান 45
সফটওয় ার আিকেটকচার

public class Blog : IObservable


{
private String _postTitle;
private readonly List<ISubscriber> _subscribers;
public Blog()
{
_subscribers = new List<ISubscriber>();
}
public String PostTitle
{
get
{
return _postTitle;
}
set
{
if (_postTitle != value)
{
_postTitle = value;
NotifySubscribers(_subscribers);
}
}
}

public void Subscribe(ISubscriber subscriber)


{
_subscribers.Add(subscriber);
}

public void UnSubscribe(ISubscriber subscriber)


{
_subscribers.Remove(subscriber);
}

public void NotifySubscribers(List<ISubscriber> subscribers)


{
foreach (ISubscriber subscriber in subscribers)
{
subscriber.GetNotification(_postTitle);
}
}

এবং আমােদর ClientCode আেগর মতই থাকেব :)

এখন আিম আমার DLL কা ানীর কােছ িদেয় িদেল এবং তােদর ধুমা Interface টার নাম বেল িদেলই ,তারা
ই ারেফসটােক ইমি েম কের য কানও class বানােব , এর মথড েলা কমি ট করেব ClientCode এ যত খুিশ
Subscriber বািনেয় Blog এর টাইেটল সট করেলই সকল কার সাব াইবার েগর পা পেয় যােব ।

এটাই হে আমােদর Observer Design Pattern.

অবজারভার প াটান 46
সফটওয় ার আিকেটকচার

পুন ঃ এখােন দখা যাে য আমােদর Subject সব সময় (এে ে Blog) কানও ইেভ আপেডট করেছ
(এে ে PostTitle) অথাৎ ইেভ Push করেছ । আবার এমন সময় দরকার হেত পাের য Observer রাই এেস
কানও নতুন ইেভ থেক থাকেল সটা Pull কের িনেয় যােব । এই Push Pull এর ঝােমলা েলা Java এবং
.Net এর API িদেয়ই সমাধান করা যায় । আপনারা একটু গল করেলই Java এবং .Net এর বািনেয় দয়া class
এবং interface েলা খুেজ পােবন ।

Java এবং .Net এ আপনারা অেনক উদাহরন দখেত পােবন Observer Pattern এর । যমন সকল কার
ইেভ ম ােনজেম েলা ( যমন বাটন একশন ইেভ , মাউস ি ক ইেভ ) এ েলা সবই এই প াটােন করা ।

আবার বতমান সমেয়র সফটওয় ার ডেভেলপেম জ MVC Architectural Pattern এর Model এবং View
হে যথা েম Observable এবং Observer যা িকনা একিট Observer Pattern.

এই প াটানেক আপিন “চুিপ চুিপ বল কউ জেন যােব “ এই ধরেনর কথা বলেত পারেবন না । চুিপ চুিপ হাক আে
আে হাক যভােবই বলুন না কেনা আসেল সবাই জেন যােব আসল ঘটনা :P

অবজারভার প াটান 47
সফটওয় ার আিকেটকচার

কে ািজট িডজাইন প াটান


মেন ক ন, একজন া ামার BFC এর জেন একিট সফটওয় ার ডেভলপ করার জেন চুি ব হল । BFC এর
সফটওয় ার এর অেনক মিডউল এর মেধ একিট মিডউল হে , য BFC এর মািলক ইে করেল কান জােন কত
টাকার লনেদন হেয়েছ এটা িফ ািরং কের দখেত পারেব । যমন, ঢাকা শহের ২০১৫ সােলর জুন মােস BFC এর
সব েলা আউটেলট থেক মাট কত টাকা বচা িবি হেয়েছ তা দখেত পারেব । িতটা জােন BFC এর
অেনক েলা আউটেলট/ ার থাকেত পাের । যমন ঢাকা জােন BFC এর অেনক ার রেয়েছ। এখন া ামারেক
ঢাকা জােনর িতমােসর মাট বচােকনার পিরমাণ বর করেত হেল তােক িতমােস ঢাকা জােনর সব েলা BFC
এর আউটেলেটর বচােকনার িহেসব বর করেত হেব । এজেন া ামার িতটা ােরর িহেসব বর করার জেন
ার েলােক এক একিট এনিটিট িহেসেব িবেবচনা করেলা । িতটা ােরর একিট ইউিনক আইিড থাকেব , নাম
থাকেব এবং িতমােস কতটাকা বচািবি হেয়েছ এটার জেন একটা াপািট থাকেব ।

public class Store


{
public int Id { get; set; }
public String Name { get; set; }
public int Profit { get; set; }
}

এখন ঢাকা শহের / জােনর মাট বচািবি র িহেসব বর করার জেন া ামার একিট City class িলেখ ফলেলা
এভােবঃ

কে ািজট িডজাইন প াটান 48


সফটওয় ার আিকেটকচার

public class City


{
public List<Store> StoreList { get; private set; }
public int Id { get; set; }
public String Name { get; set; }

public City()
{
StoreList = new List<Store>();
}

public void RemoveStore(Store store)


{
StoreList.Remove(store);
}

public void AddStore(Store store)


{
StoreList.Add(store);
}

public int GetCityProfit()


{
int totalProfit = 0;
foreach (Store store in StoreList)
{
totalProfit += store.Profit;
}
return totalProfit;
}
}

এখােন দখা যাে য , City class এ সব েলা ােরর জেন একিট িল আেছ । BFC এর নতুন কানও
আউটেলট হেল িলে নতুন আউটেলট ঢাকােনা অথবা কানও আউটেলট ব হেয় গেল িল থেক আউটেলট
বাদ দয়ার ব ব া রাখা হেয়েছ । শেষ GetCityProfit() মথেড City এর টাটাল িফট ক ালকুেলট করা হেয়েছ ।
সবেশেষ ােয় কােড ইউজ করা হেয়েছ এভােবঃ

কে ািজট িডজাইন প াটান 49


সফটওয় ার আিকেটকচার

class Program
{
public static void Main(string[] args)
{
var store1 = new Store
{
Id = 1,
Name = "Malibagh BFC",
Profit = 2
};
var store2 = new Store
{
Id = 2,
Name = "Gulshan BFC",
Profit = 5
};

var city = new City


{
Id = 10,
Name = "Dhaka"
};
city.AddStore(store1);
city.AddStore(store2);
int totalProfit = city.GetCityProfit();
Console.WriteLine("Total Profit of {0} city is : {1}", city.Name, totalProfit);
Console.ReadLine();
}
}

এখন মেন ক ন িকছু িদেনর মেধ BFC সারােদেশ তােদর ব বসা করেলা । িবভাগীয় শহর এবং শহেরর জলা
উপেজলা পযােয় আউটেলট চালু হেলা । এখন া ামােরর উপর দািয় এেস পড়েলা য তােক িডিভশেনরও িফট
দখােত হেব ।উদাহরন প ,রাজশাহী িবভােগর িতমােস কত লাভ আেস তাও BFC এর মািলকেক দখােত হেব
। এখন িবভােগর লাভ লাকসান বর করার জেন া ামার City Class মত আেরকিট Division Class বানােলা
যিট City Add/Delete করেত পাের এবং GetDivisionProfit() মথড এ িডিভশেনর সব City এর টাটাল
িফট এর যাগফল বর কের । Division class দখেত এরকমঃ

কে ািজট িডজাইন প াটান 50


সফটওয় ার আিকেটকচার

public class Division


{
public List<City> CityList { get; private set; }

public int Id { get; set; }


public int Profit { get; set; }
public Division()
{
CityList = new List<City>();
}

public void AddCity(City city)


{
CityList.Add(city);
}

public void RemoveCity(City city)


{
CityList.Remove(city);
}

public int GetDivisionProfit()


{
int totalProfit = 0;
foreach (City city in CityList)
{
foreach (Store store in city.StoreList)
{
totalProfit += store.Profit;
}
}
return totalProfit;
}
}

িডিভশেনর মাট িফট বর করার জেন ােয় কােড িডিভশেনর ব বহার হেব এভােবঃ

কে ািজট িডজাইন প াটান 51


সফটওয় ার আিকেটকচার

public class Program


{
public static void Main(string[] args)
{
var store1 = new Store
{
Id = 1,
Name = "Malibagh BFC",
Profit = 2
};
var store2 = new Store
{
Id = 2,
Name = "Gulshan BFC",
Profit = 5
};

var city = new City


{
Id = 10,
Name = "Dhaka"
};
city.AddStore(store1);
city.AddStore(store2);

var division = new Division


{
Id = 1,
Name = "Rajshahi"
};

division.AddCity(city);
int totalProfit = division.GetDivisionProfit();
Console.WriteLine("Total Profit of {0} division is : {1}", division.Name, totalProfit);
Console.ReadLine();
}
}

া ামার ল করেলা য , িত লেভেলর িফট ক ালকুেলশেনর জেন তােক িতবার একিট কের লুপ বাড়ােত
হে । আবার স িচ া কের দখেলা য, এখন স িডিভশন লেভেলর িফট ক ালকুেলট করেছ, যিদ তােক এিশয়া
িরিজয়েনর িফট বর করেত বেল ( BFC যিদ KFC মত ই ারন াশনাল চইন শপ হয় কখনও) তাহেল তােক
কেয়কটা দেশর টাটাল িফট বর করেত হেব । সা দখা যাে য িতটা লেভেল া ামারেক লুপ বাড়ােত হে
এবং একিট কের Class যাগ করেত হে । আসেল া ামার একিট ি এর মত একিট hierarchy বািনেয়
ফেলেছ । ি এর Division একিট নাড হেল City েলা হে Division এর িচলে ন ।

া ামার এত ণ যা কেরেছ তা হে ি hierarchy এর িতিট নাড এবং এর চাইে র জেন একই রকম সব
অপােরশন কেরেছ । (City এর িফট এবং Division এর িফট বর করার তিরকা একই, িক তােদর িরেলশন িক
প াের -চাই ) । সা দখা যাে য , া ামার যিদ প াের এবং চাই ক আলাদা িবেবচনা না কের একইরকম

কে ািজট িডজাইন প াটান 52


সফটওয় ার আিকেটকচার

ভােব ি ট কের তাহেলই বেলম স ভ হেয় যাে । এরকম বেলম স ভ করার জেন ই আসেল কে ািজট
িডজাইন প াটােনর আিবভাব ।

িরফ াে ািরং টু কে ািজট িডজাইন প াটানঃ Store,City ও Division এ দখা যাে য Add, Remove এবং
Calculation এর কাজ েলা বার বার করা হেয়েছ । তাই এ েলা ক কমন একিট ই ারেফস এ িনেয় যাওয়া যায়
এভােবঃ

public interface IProfitable


{
int GetProfit();
void AddChild(IProfitable profitable);
void RemoveChild(IProfitable profitable);
int Id { get; set; }
String Name { get; set; }
}

এখন Store class এেক ইমি েম করেব এভােবঃ

public class Store : IProfitable


{
public int Profit { get; set; }
public int Id { get; set; }
public String Name { get; set; }
public int GetProfit()
{
return Profit;
}
public void AddChild(IProfitable profitable)
{
throw new NotImplementedException();
}
public void RemoveChild(IProfitable profitable)
{
throw new NotImplementedException();
}
}

এখােন ল ণীয় য Store class হে ি াকচােরর Leaf, তাই এর AddChild এবং RemoveChild মথড
Unimplemented অব ায় থাকেব । একই ভােব City class IProfitable ক ইমি েম করেব এভােবঃ

কে ািজট িডজাইন প াটান 53


সফটওয় ার আিকেটকচার

public class City : IProfitable


{
public int Id { get; set; }
public String Name { get; set; }
public List<IProfitable> StoreList { get; private set; }
public City()
{
StoreList = new List<IProfitable>();

}
public int GetProfit()
{
int totalProfit = 0;

foreach (IProfitable store in StoreList)


{
totalProfit += store.GetProfit();
}

return totalProfit;
}

public void AddChild(IProfitable profitable)


{
if (profitable is Store)
StoreList.Add(profitable);

}
public void RemoveChild(IProfitable profitable)
{
if (profitable is Store)
StoreList.Remove(profitable);
}
}

এখােন ল ণীয় য ,City class এর AddChild এবং RemoveChild মথেড আমরা টাইপ চক কের িলে
অবেজ ঢু িকেয়িছ কননা , City class ধুমা Store অবেজ িনেয় কাজ করেব । অন িদেক Division class
ধুমা City অবেজ িনেয় কাজ করেব এজেন Division class হেব এরকমঃ

কে ািজট িডজাইন প াটান 54


সফটওয় ার আিকেটকচার

public class Division : IProfitable


{
public int Id { get; set; }
public String Name { get; set; }
public List<IProfitable> CityList { get; private set; }
public Division()
{
CityList = new List<IProfitable>();
}
public int GetProfit()
{
int totalProfit = 0;
foreach (IProfitable city in CityList)
{
totalProfit += city.GetProfit();
}
return totalProfit;
}
public void AddChild(IProfitable profitable)
{
if (profitable is City)
CityList.Add(profitable);
}
public void RemoveChild(IProfitable profitable)
{
if (profitable is City)
CityList.Remove(profitable);
}
}

City class এবং Division class থেক দখা যাে য , এই দুেটা Class অেনকটা একই রকেমর , তােদর মেধ
পাথক ধুমা GetProfit() মথেড । এই মথেড এখন আর কানও মাি পল লুপ নই । আলাদা আলাদা Class
এর GetProfit() মথেডর িবজেনস লিজক আলাদা আলাদা এবং এেদর মেধ কানও িডেপে ি নই । সবেশেষ
ােয় কােড িফট ক ালকুেলট করেব এভােবঃ

কে ািজট িডজাইন প াটান 55


সফটওয় ার আিকেটকচার

public class Program


{
public static void Main(string[] args)
{
IProfitable store1 = new Store
{
Id = 1,
Name = "Malibagh BFC",
Profit = 2
};
IProfitable store2 = new Store
{
Id = 2,
Name = "Gulshan BFC",
Profit = 5
};

IProfitable city = new City


{
Id = 10,
Name = "Dhaka"
};
city.AddChild(store1);
city.AddChild(store2);

IProfitable division = new Division


{
Id = 1,
Name = "Rajshahi"
};
division.AddChild(city);
int totalProfit = division.GetProfit();
Console.WriteLine("Total Profit of {0} division is : {1}", division.Name, totalProfit);
Console.ReadLine();
}
}

সা এইিছেলা আমােদর কে ািজট িডজাইন প াটান । হ ািপ কািডং :)

কে ািজট িডজাইন প াটান 56


সফটওয় ার আিকেটকচার

সূচনা

ট াইেভন ডেভলপেম 57

You might also like