আমি জিওএফ-তে ডকুমেন্টেড হিসাবে ডেকরেটার প্যাটার্ন অধ্যয়ন করছিলাম ।
দয়া করে, আমাকে সজ্জিত প্যাটার্নটি বুঝতে সহায়তা করুন । সত্যিকারের বিশ্বে এটি কোথায় কার্যকর তা ব্যবহারের ক্ষেত্রে কেউ উদাহরণ দিতে পারে?
আমি জিওএফ-তে ডকুমেন্টেড হিসাবে ডেকরেটার প্যাটার্ন অধ্যয়ন করছিলাম ।
দয়া করে, আমাকে সজ্জিত প্যাটার্নটি বুঝতে সহায়তা করুন । সত্যিকারের বিশ্বে এটি কোথায় কার্যকর তা ব্যবহারের ক্ষেত্রে কেউ উদাহরণ দিতে পারে?
উত্তর:
ডেকোরেটর প্যাটার্নটি কোনও বস্তুর গতিশীলভাবে দায়িত্ব যুক্ত করার একক লক্ষ্য অর্জন করে।
একটি পিজা দোকানে একটি মামলা বিবেচনা করুন। পিজ্জার দোকানে তারা কয়েকটি পিজ্জা জাত বিক্রি করবে এবং তারা মেনুতে শীর্ষস্থানগুলি সরবরাহ করবে। এখন এমন পরিস্থিতিটি কল্পনা করুন যার মধ্যে যদি পিজ্জা শপকে পিজ্জা এবং টপিংয়ের প্রতিটি সংমিশ্রনের জন্য দাম সরবরাহ করতে হয়। এমনকি যদি চারটি বেসিক পিজ্জা এবং 8 টি আলাদা টপিংস থাকে তবে অ্যাপ্লিকেশনটি পিজ্জা এবং টপিংসের সমস্ত কংক্রিট সংমিশ্রণ বজায় রাখতে উন্মাদ হয়ে যাবে।
এখানে আসে সাজসজ্জার প্যাটার্ন।
সাজসজ্জার প্যাটার্ন অনুসারে, আপনি টপিংগুলি বাস্তবায়ন করবেন কারণ ডেকোরেটর এবং পিজ্জা সেই টপিংসের সাজসজ্জা দ্বারা সজ্জিত হবে। কার্যত প্রতিটি গ্রাহক তার ইচ্ছার শীর্ষস্থানীয় চায় এবং চূড়ান্ত বিল-পরিমাণ বেস পিজ্জা সমন্বিত হবে এবং অতিরিক্ত অর্ডার করা টপিংস। প্রতিটি শীর্ষে সাজসজ্জাকারী পিজ্জা সম্পর্কে জানতেন যে এটি সজ্জিত এবং এটির দাম। টপিং অবজেক্টের গেটপ্রিস () পদ্ধতি পিজ্জা এবং টপিং উভয়েরই ক্রমবর্ধমান দাম ফিরিয়ে আনবে।
উপরে বর্ণনার একটি কোড-উদাহরণ এখানে।
public abstract class BasePizza
{
protected double myPrice;
public virtual double GetPrice()
{
return this.myPrice;
}
}
public abstract class ToppingsDecorator : BasePizza
{
protected BasePizza pizza;
public ToppingsDecorator(BasePizza pizzaToDecorate)
{
this.pizza = pizzaToDecorate;
}
public override double GetPrice()
{
return (this.pizza.GetPrice() + this.myPrice);
}
}
class Program
{
[STAThread]
static void Main()
{
//Client-code
Margherita pizza = new Margherita();
Console.WriteLine("Plain Margherita: " + pizza.GetPrice().ToString());
ExtraCheeseTopping moreCheese = new ExtraCheeseTopping(pizza);
ExtraCheeseTopping someMoreCheese = new ExtraCheeseTopping(moreCheese);
Console.WriteLine("Plain Margherita with double extra cheese: " + someMoreCheese.GetPrice().ToString());
MushroomTopping moreMushroom = new MushroomTopping(someMoreCheese);
Console.WriteLine("Plain Margherita with double extra cheese with mushroom: " + moreMushroom.GetPrice().ToString());
JalapenoTopping moreJalapeno = new JalapenoTopping(moreMushroom);
Console.WriteLine("Plain Margherita with double extra cheese with mushroom with Jalapeno: " + moreJalapeno.GetPrice().ToString());
Console.ReadLine();
}
}
public class Margherita : BasePizza
{
public Margherita()
{
this.myPrice = 6.99;
}
}
public class Gourmet : BasePizza
{
public Gourmet()
{
this.myPrice = 7.49;
}
}
public class ExtraCheeseTopping : ToppingsDecorator
{
public ExtraCheeseTopping(BasePizza pizzaToDecorate)
: base(pizzaToDecorate)
{
this.myPrice = 0.99;
}
}
public class MushroomTopping : ToppingsDecorator
{
public MushroomTopping(BasePizza pizzaToDecorate)
: base(pizzaToDecorate)
{
this.myPrice = 1.49;
}
}
public class JalapenoTopping : ToppingsDecorator
{
public JalapenoTopping(BasePizza pizzaToDecorate)
: base(pizzaToDecorate)
{
this.myPrice = 1.49;
}
}
এটি কোনও বিদ্যমান অবজেক্টে গতিশীলভাবে নতুন আচরণ বা ডেকরেটার প্যাটার্ন যুক্ত করার সহজ উদাহরণ। জাভাস্ক্রিপ্টের মতো গতিময় ভাষার প্রকৃতির কারণে, এই প্যাটার্নটি নিজেই ভাষার অংশ হয়ে যায়।
// Person object that we will be decorating with logging capability
var person = {
name: "Foo",
city: "Bar"
};
// Function that serves as a decorator and dynamically adds the log method to a given object
function MakeLoggable(object) {
object.log = function(property) {
console.log(this[property]);
}
}
// Person is given the dynamic responsibility here
MakeLoggable(person);
// Using the newly added functionality
person.log('name');
switch
বা if
সাধারণের অভ্যন্তরে, আপনি দাবি করতে সক্ষম হবেন যে এটি একটি ক্লাসে গতিশীল আচরণ যুক্ত করার একটি দুর্দান্ত উদাহরণ B তবে আমাদের এই প্যাটার্নে সাজসজ্জা এবং সজ্জিত বস্তুর সংজ্ঞা দিতে আমাদের কমপক্ষে দুটি শ্রেণি প্রয়োজন।
এটি লক্ষণীয় যে জাভা i / o মডেলটি সাজসজ্জার প্যাটার্নের উপর ভিত্তি করে। শীর্ষে থাকা এই পাঠকের শীর্ষে এই পাঠকের স্তর ... সাজসজ্জার এক বাস্তব বাস্তব উদাহরণ।
উদাহরণ - পরিস্থিতি- ধরা যাক আপনি একটি এনক্রিপশন মডিউল লিখছেন। এই এনক্রিপশনটি ডিইএস - ডেটা এনক্রিপশন মান ব্যবহার করে পরিষ্কার ফাইল এনক্রিপ্ট করতে পারে। একইভাবে, কোনও সিস্টেমে আপনার কাছে এইএস - অ্যাডভান্স এনক্রিপশন মান হিসাবে এনক্রিপশন থাকতে পারে। এছাড়াও, আপনার এনক্রিপশনের সংমিশ্রণ থাকতে পারে - প্রথম ডিইএস, তারপরে এইএস। অথবা আপনি প্রথম এইএস, তারপরে ডিইএস রাখতে পারেন।
আলোচনা- আপনি এই পরিস্থিতিটি কীভাবে পূরণ করবেন? আপনি যেমন সংমিশ্রণগুলির অবজেক্ট তৈরি করে রাখতে পারবেন না - উদাহরণস্বরূপ - এইএস এবং ডিইএস - মোট 4 টি সংমিশ্রণ। সুতরাং, আপনার 4 টি পৃথক অবজেক্ট থাকা দরকার এটি এনক্রিপশন ধরণের বাড়ার সাথে সাথে জটিল হয়ে উঠবে।
সমাধান - রান সময় - প্রয়োজনীয়তার উপর নির্ভরশীল সমন্বয় - স্ট্যাকটি তৈরি করে রাখুন। এই স্ট্যাক পদ্ধতির আরেকটি সুবিধা হ'ল আপনি এটি সহজেই আনওয়াইন্ড করতে পারেন।
সমাধানটি এখানে - সি ++ এ।
প্রথমত, আপনার একটি বেস ক্লাস প্রয়োজন - স্ট্যাকের একটি মৌলিক ইউনিট। আপনি স্ট্যাকের বেস হিসাবে ভাবতে পারেন। এই উদাহরণে এটি পরিষ্কার ফাইল। আসুন সর্বদা বহুবচন অনুসরণ করুন। প্রথমে এই মৌলিক ইউনিটের একটি ইন্টারফেস শ্রেণি তৈরি করুন। এইভাবে, আপনি এটি আপনার ইচ্ছা হিসাবে বাস্তবায়ন করতে পারেন। এছাড়াও, এই মৌলিক ইউনিটটি অন্তর্ভুক্ত করার সময় আপনার নির্ভরতার কথা চিন্তা করার দরকার নেই।
এখানে ইন্টারফেস ক্লাস -
class IclearData
{
public:
virtual std::string getData() = 0;
virtual ~IclearData() = 0;
};
IclearData::~IclearData()
{
std::cout<<"Destructor called of IclearData"<<std::endl;
}
এখন, এই ইন্টারফেস শ্রেণীর প্রয়োগ করুন -
class clearData:public IclearData
{
private:
std::string m_data;
clearData();
void setData(std::string data)
{
m_data = data;
}
public:
std::string getData()
{
return m_data;
}
clearData(std::string data)
{
setData(data);
}
~clearData()
{
std::cout<<"Destructor of clear Data Invoked"<<std::endl;
}
};
এখন আসুন একটি সাজসজ্জা বিমূর্ত শ্রেণি তৈরি করুন - এটি যে কোনও ধরণের স্বাদ তৈরি করতে বাড়ানো যেতে পারে - এখানে স্বাদটি হ'ল এনক্রিপশন প্রকার। এই সাজসজ্জা বিমূর্ত শ্রেণি বেস শ্রেণীর সাথে সম্পর্কিত। সুতরাং, সাজসজ্জা "একটি" ইন্টারফেস শ্রেণীর এক ধরণের। সুতরাং, আপনি উত্তরাধিকার ব্যবহার করা প্রয়োজন।
class encryptionDecorator: public IclearData
{
protected:
IclearData *p_mclearData;
encryptionDecorator()
{
std::cout<<"Encryption Decorator Abstract class called"<<std::endl;
}
public:
std::string getData()
{
return p_mclearData->getData();
}
encryptionDecorator(IclearData *clearData)
{
p_mclearData = clearData;
}
virtual std::string showDecryptedData() = 0;
virtual ~encryptionDecorator() = 0;
};
encryptionDecorator::~encryptionDecorator()
{
std::cout<<"Encryption Decorator Destructor called"<<std::endl;
}
এখন, একটি কংক্রিট সাজসজ্জার শ্রেণি তৈরি করা যাক - এনক্রিপশনের ধরণ - এইএস -
const std::string aesEncrypt = "AES Encrypted ";
class aes: public encryptionDecorator
{
private:
std::string m_aesData;
aes();
public:
aes(IclearData *pClearData): m_aesData(aesEncrypt)
{
p_mclearData = pClearData;
m_aesData.append(p_mclearData->getData());
}
std::string getData()
{
return m_aesData;
}
std::string showDecryptedData(void)
{
m_aesData.erase(0,m_aesData.length());
return m_aesData;
}
};
এখন, ধরা যাক সাজসজ্জারের ধরণটি ডিইএস -
const std :: string desEncrypt = "DES এনক্রিপ্ট করা";
class des: public encryptionDecorator
{
private:
std::string m_desData;
des();
public:
des(IclearData *pClearData): m_desData(desEncrypt)
{
p_mclearData = pClearData;
m_desData.append(p_mclearData->getData());
}
std::string getData(void)
{
return m_desData;
}
std::string showDecryptedData(void)
{
m_desData.erase(0,desEncrypt.length());
return m_desData;
}
};
এই সাজসজ্জার শ্রেণিটি ব্যবহার করার জন্য ক্লায়েন্ট কোড তৈরি করা যাক -
int main()
{
IclearData *pData = new clearData("HELLO_CLEAR_DATA");
std::cout<<pData->getData()<<std::endl;
encryptionDecorator *pAesData = new aes(pData);
std::cout<<pAesData->getData()<<std::endl;
encryptionDecorator *pDesData = new des(pAesData);
std::cout<<pDesData->getData()<<std::endl;
/** unwind the decorator stack ***/
std::cout<<pDesData->showDecryptedData()<<std::endl;
delete pDesData;
delete pAesData;
delete pData;
return 0;
}
আপনি নিম্নলিখিত ফলাফল দেখতে পাবেন -
HELLO_CLEAR_DATA
Encryption Decorator Abstract class called
AES Encrypted HELLO_CLEAR_DATA
Encryption Decorator Abstract class called
DES Encrypted AES Encrypted HELLO_CLEAR_DATA
AES Encrypted HELLO_CLEAR_DATA
Encryption Decorator Destructor called
Destructor called of IclearData
Encryption Decorator Destructor called
Destructor called of IclearData
Destructor of clear Data Invoked
Destructor called of IclearData
এখানে ইউএমএল চিত্র - এর শ্রেণি উপস্থাপনা। সেক্ষেত্রে আপনি কোডটি এড়িয়ে ডিজাইনের দিকটিতে ফোকাস করতে চান।
strategy pattern
?
ডেকোরেটর প্যাটার্ন আপনাকে এই অবজেক্টের অন্যান্য অনুরূপ উপশ্রেণীর সাথে শৃঙ্খলাবদ্ধ করে আপনার অবজেক্টের কার্যকারিতা পরিবর্তন বা কনফিগার করতে সহায়তা করে।
জাভা.ইও প্যাকেজের ইনপুটস্ট্রিম এবং আউটপুট স্ট্রিম ক্লাসগুলির সর্বোত্তম উদাহরণ
File file=new File("target","test.txt");
FileOutputStream fos=new FileOutputStream(file);
BufferedOutputStream bos=new BufferedOutputStream(fos);
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.write(5);
oos.writeBoolean(true);
oos.writeBytes("decorator pattern was here.");
//... then close the streams of course.
জাভাতে সজ্জা নকশার প্যাটার্নটি কী।
জিওএফ বইয়ের (ডিজাইনের প্যাটার্নস: এলিজেন্টস অফ রিজ্যাবল অবজেক্ট-ওরিয়েন্টড সফটওয়্যার, 1995, পিয়ারসন এডুকেশন, ইনক। পিয়ারসন অ্যাডিসন ওয়েসলি হিসাবে প্রকাশনা) ডেকোরেটার প্যাটার্নের আনুষ্ঠানিক সংজ্ঞা বলছে আপনি পারেন,
"একটি বস্তুর সাথে গতিশীলভাবে অতিরিক্ত দায়িত্ব সংযোজন করুন function
ধরা যাক আমাদের একটি পিজ্জা আছে এবং আমরা চিকেন মাসালা, পেঁয়াজ এবং মোজারেলা পনির মতো টপিংগুলি দিয়ে এটি সাজাইতে চাই। আসুন দেখি কীভাবে এটি জাভাতে প্রয়োগ করা যায় ...
জাভাতে কীভাবে ডেকোরেটর ডিজাইন প্যাটার্ন প্রয়োগ করতে হবে তা প্রদর্শনের জন্য প্রোগ্রাম।
Pizza.java:
<!-- language-all: lang-html -->
package com.hubberspot.designpattern.structural.decorator;
public class Pizza {
public Pizza() {
}
public String description(){
return "Pizza";
}
}
package com.hubberspot.designpattern.structural.decorator;
public abstract class PizzaToppings extends Pizza {
public abstract String description();
}
package com.hubberspot.designpattern.structural.decorator;
public class ChickenMasala extends PizzaToppings {
private Pizza pizza;
public ChickenMasala(Pizza pizza) {
this.pizza = pizza;
}
@Override
public String description() {
return pizza.description() + " with chicken masala, ";
}
}
package com.hubberspot.designpattern.structural.decorator;
public class MozzarellaCheese extends PizzaToppings {
private Pizza pizza;
public MozzarellaCheese(Pizza pizza) {
this.pizza = pizza;
}
@Override
public String description() {
return pizza.description() + "and mozzarella cheese.";
}
}
package com.hubberspot.designpattern.structural.decorator;
public class Onion extends PizzaToppings {
private Pizza pizza;
public Onion(Pizza pizza) {
this.pizza = pizza;
}
@Override
public String description() {
return pizza.description() + "onions, ";
}
}
package com.hubberspot.designpattern.structural.decorator;
public class TestDecorator {
public static void main(String[] args) {
Pizza pizza = new Pizza();
pizza = new ChickenMasala(pizza);
pizza = new Onion(pizza);
pizza = new MozzarellaCheese(pizza);
System.out.println("You're getting " + pizza.description());
}
}
আমি আমার কাজগুলিতে সজ্জিত প্যাটার্ন ব্যবহার করেছি। লগিংয়ের মাধ্যমে এটি কীভাবে ব্যবহার করতে হয় সে সম্পর্কে আমি আমার ব্লগে একটি পোস্ট তৈরি করেছি ।
ডেকোরেটর প্যাটার্ন আপনাকে বস্তুগুলিতে গতিশীল আচরণ করতে দেয়।
আসুন একটি উদাহরণ নেওয়া যাক যেখানে আপনাকে এমন অ্যাপ তৈরি করতে হবে যা বিভিন্ন ধরণের বার্গারের দাম গণনা করে। আপনাকে বার্গারের বিভিন্ন প্রকারের হ্যান্ডেল করতে হবে, যেমন "লার্জ" বা "পনির সহ", যার প্রত্যেকটিরই মূল বার্গারের সাথে দাম রয়েছে। যেমন পনির দিয়ে বার্গারের জন্য 10 ডলার যোগ করুন, বড় বার্গারের জন্য অতিরিক্ত 15 ডলার যোগ করুন etc.
এই ক্ষেত্রে আপনাকে এগুলি হ্যান্ডেল করার জন্য সাবক্লাস তৈরি করতে প্ররোচিত হতে পারে। আমরা এটি রুবিতে প্রকাশ করতে পারি:
class Burger
def price
50
end
end
class BurgerWithCheese < Burger
def price
super + 15
end
end
উপরের উদাহরণে, বার্গার উইথচিজ ক্লাসটি বার্গারের কাছ থেকে উত্তরাধিকার সূত্রে প্রাপ্ত, এবং সুপার ক্লাসে সংজ্ঞায়িত মূল্যে 15 ডলার যুক্ত করার জন্য মূল্য পদ্ধতিটিকে ওভাররাইড করে। আপনি একটি বৃহত্তর বার্গার ক্লাসও তৈরি করে বার্গারের সাথে সম্পর্কিত দাম নির্ধারণ করবেন। তবে আপনাকে "বৃহত" এবং "পনির সহ" এর সংমিশ্রণের জন্য একটি নতুন শ্রেণিও নির্ধারণ করতে হবে।
এখন যদি আমাদের "ফ্রাই সহ বার্গার" পরিবেশন করা প্রয়োজন তবে কী হবে? এই সংমিশ্রণগুলি পরিচালনা করতে আমাদের ইতিমধ্যে 4 টি ক্লাস রয়েছে এবং "বৃহত", "পনির সহ" এবং "ফ্রাই সহ" 3 টি বৈশিষ্ট্যের সমস্ত সমন্বয় পরিচালনা করতে আমাদের আরও 4 টি যুক্ত করতে হবে। আমাদের এখন 8 টি ক্লাস দরকার। অন্য সম্পত্তি যুক্ত করুন এবং আমাদের 16 টির দরকার হবে এটি 2 ^ n হিসাবে বাড়বে।
পরিবর্তে, আসুন আমরা একটি বার্গার ডেকোরেটর সংজ্ঞায়নের চেষ্টা করি যা একটি বার্গার বস্তু গ্রহণ করে:
class BurgerDecorator
def initialize(burger)
self.burger = burger
end
end
class BurgerWithCheese < BurgerDecorator
def price
self.burger.price + 15
end
end
burger = Burger.new
cheese_burger = BurgerWithCheese.new(burger)
cheese_burger.price # => 65
উপরের উদাহরণে, আমরা একটি বার্গার ডেকোরেটর শ্রেণি তৈরি করেছি, যা থেকে বার্গার উইথচিজ ক্লাস উত্তরাধিকার সূত্রে প্রাপ্ত। লার্জবার্গার ক্লাস তৈরি করে আমরা "বৃহত্তর" প্রকরণটিও উপস্থাপন করতে পারি। রানওয়েতে আমরা এখন পনির সাথে একটি বড় বার্গারটিকে সংজ্ঞায়িত করতে পারি:
b = LargeBurger.new(cheese_burger)
b.price # => 50 + 15 + 20 = 85
মনে রাখবেন কীভাবে "ফ্রাই সহ" বৈচিত্র যুক্ত করতে উত্তরাধিকার ব্যবহার করে আরও 4 টি সাবক্লাস যুক্ত করা যায়? সাজসজ্জারের সাহায্যে আমরা নতুন বৈচিত্র্য পরিচালনা করতে এবং রানটাইমে এটি পরিচালনা করতে কেবল বার্গারভিথফ্রাইস একটি নতুন ক্লাস তৈরি করব would প্রতিটি নতুন সম্পত্তির জন্য সমস্ত অনুমতিগুলি কভার করার জন্য আরও বেশি সাজসজ্জার প্রয়োজন।
পুনশ্চ. এটি রুবিতে ডেকোরেটর প্যাটার্নটি ব্যবহার করার বিষয়ে আমি যে নিবন্ধটি লিখেছি তার সংক্ষিপ্ত সংস্করণ , যা আপনি আরও বিস্তারিত উদাহরণগুলি সন্ধান করতে চাইলে আপনি পড়তে পারেন।
প্রসাধক:
পড়ুন sourcemaking আরো বিস্তারিত জানার জন্য নিবন্ধ।
ডেকোরেটার (বিমূর্ত) : এটি একটি বিমূর্ত শ্রেণি / ইন্টারফেস, যা উপাদান ইন্টারফেস প্রয়োগ করে। এতে কম্পোনেন্ট ইন্টারফেস রয়েছে। এই শ্রেণীর অনুপস্থিতিতে, আপনার বিভিন্ন সংমিশ্রনের জন্য কংক্রিটডেক্টরগুলির অনেকগুলি উপ-শ্রেণীর প্রয়োজন। উপাদানগুলির সংমিশ্রণ অ-প্রয়োজনীয় সাব-ক্লাস হ্রাস করে।
জেডিকে উদাহরণ:
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("a.txt")));
while(bis.available()>0)
{
char c = (char)bis.read();
System.out.println("Char: "+c);;
}
ইউএমএল ডায়াগ্রাম এবং কোড উদাহরণগুলির জন্য এসই নীচে প্রশ্নটি দেখুন।
দরকারী নিবন্ধ:
ডেকোরেটার প্যাটার্নের আসল শব্দের উদাহরণ: ভেন্ডিংম্যাচাইনডেকরেটরটি ব্যাখ্যা করা হয়েছে @
সজ্জিত প্যাটার্ন কখন ব্যবহার করবেন?
Beverage beverage = new SugarDecorator(new LemonDecorator(new Tea("Assam Tea")));
beverage.decorateBeverage();
beverage = new SugarDecorator(new LemonDecorator(new Coffee("Cappuccino")));
beverage.decorateBeverage();
উপরের উদাহরণে, চা বা কফি (পানীয়) চিনি এবং লেবু দ্বারা সজ্জিত করা হয়েছে।
ডেকোরেটর প্যাটার্নটি কোনও বস্তুর গতিশীলভাবে দায়িত্ব যুক্ত করার একক লক্ষ্য অর্জন করে ।
জাভা আই / ও মডেল সাজসজ্জার ধরণের উপর ভিত্তি করে।
স্ক্রোলবার দিয়ে উইন্ডো সাজানোর বিষয়ে উইকিপিডিয়ায় একটি উদাহরণ রয়েছে:
http://en.wikipedia.org/wiki/Decorator_pattern
এখানে "টিম মেম্বার, টিম লিড এবং ম্যানেজার" এর আরও একটি 'বাস্তব জগত' উদাহরণ রয়েছে যা বর্ণনা করে যে ডেকোরেটার প্যাটার্নটি সহজ উত্তরাধিকারের সাথে অপরিবর্তনীয়:
https://zishanbilal.wordpress.com/2011/04/28/design-patterns-by-examples-decorator-pattern/
কিছুক্ষণ আগে আমি ডেকরেটার প্যাটার্ন ব্যবহার করে একটি কোডবেস রিফ্যাক্টর করেছি, তাই আমি ব্যবহারের কেসটি ব্যাখ্যা করার চেষ্টা করব।
ধরে নেওয়া যাক আমাদের পরিষেবাগুলির একটি সেট রয়েছে এবং ব্যবহারকারী নির্দিষ্ট পরিষেবার লাইসেন্স অর্জন করেছে কিনা তার উপর ভিত্তি করে আমাদের পরিষেবাটি শুরু করা দরকার।
সমস্ত পরিষেবাগুলির একটি সাধারণ ইন্টারফেস রয়েছে
interface Service {
String serviceId();
void init() throws Exception;
void start() throws Exception;
void stop() throws Exception;
}
abstract class ServiceSupport implements Service {
public ServiceSupport(String serviceId, LicenseManager licenseManager) {
// assign instance variables
}
@Override
public void init() throws Exception {
if (!licenseManager.isLicenseValid(serviceId)) {
throw new Exception("License not valid for service");
}
// Service initialization logic
}
}
আপনি সাবধানে পর্যবেক্ষণ, ServiceSupport
উপর নির্ভরশীল LicenseManager
। তবে কেন এটি নির্ভর করে LicenseManager
? আমাদের যদি ব্যাকগ্রাউন্ড পরিষেবা প্রয়োজন হয় যা লাইসেন্সের তথ্য যাচাই করার দরকার নেই What বর্তমান পরিস্থিতিতে আমাদের LicenseManager
ফিরে আসার জন্য কোনওভাবে ট্রেন করতে হবেtrue
পটভূমি পরিষেবাগুলির জন্য । এই পদ্ধতির বিষয়টি আমার কাছে ভাল লাগেনি। আমার মতে লাইসেন্স চেক এবং অন্যান্য যুক্তি একে অপরের অর্থেগোনাল ছিল।
সুতরাং ডেকোরেটর প্যাটার্নটি উদ্ধারে আসে এবং এখানে টিডিডি দিয়ে রিফ্যাক্টরিং শুরু হয়।
class LicensedService implements Service {
private Service service;
public LicensedService(LicenseManager licenseManager, Service service) {
this.service = service;
}
@Override
public void init() {
if (!licenseManager.isLicenseValid(service.serviceId())) {
throw new Exception("License is invalid for service " + service.serviceId());
}
// Delegate init to decorated service
service.init();
}
// override other methods according to requirement
}
// Not concerned with licensing any more :)
abstract class ServiceSupport implements Service {
public ServiceSupport(String serviceId) {
// assign variables
}
@Override
public void init() {
// Service initialization logic
}
}
// The services which need license protection can be decorated with a Licensed service
Service aLicensedService = new LicensedService(new Service1("Service1"), licenseManager);
// Services which don't need license can be created without one and there is no need to pass license related information
Service aBackgroundService = new BackgroundService1("BG-1");
আসুন পাবজির উদাহরণ নিই। অ্যাসল্ট রাইফেলগুলি 4x জুমের সাথে সবচেয়ে ভাল কাজ করে এবং আমরা যখন এটিতে থাকি তখন আমাদের ক্ষতিপূরণকারী এবং দমনকারীও দরকার। এটি হতাশাগুলি হ্রাস করবে এবং ফায়ারিং সাউন্ডের পাশাপাশি প্রতিধ্বনি হ্রাস করবে। আমাদের এই বৈশিষ্ট্যটি প্রয়োগ করতে হবে যেখানে আমরা খেলোয়াড়দের তাদের পছন্দসই বন্দুক এবং তাদের আনুষাঙ্গিক কিনতে দেবো। খেলোয়াড়গণ বন্দুক বা কিছু আনুষাঙ্গিক বা আনুষাঙ্গিকের কিছু কিনতে পারেন এবং সেই অনুযায়ী তাদের চার্জ করা হবে।
আসুন দেখুন এখানে কীভাবে ডেকরেটার প্যাটার্ন প্রয়োগ করা হয়:
মনে করুন উপরে উল্লিখিত তিনটি জিনিসপত্র সহ কেউ এসসিএআর-এল কিনতে চান।
এটি এর মতো শ্রেণীর চিত্র তৈরি করবে:
এখন, আমরা এর মতো ক্লাস করতে পারি:
public abstract class Gun {
private Double cost;
public Double getCost() {
return cost;
}
}
public abstract class GunAccessories extends Gun { }
public class Scarl extends Gun {
public Scarl() {
cost = 100;
}
}
public class Suppressor extends GunAccessories {
Gun gun;
public Suppressor(Gun gun) {
cost = 5;
this.gun = gun;
}
public double getCost(){
return cost + gun.getCost();
}
}
public class GunShop{
public static void main(String args[]){
Gun scarl = new Scarl();
scarl = new Supressor(scarl);
System.out.println("Price is "+scarl.getCost());
}
}
আমরা একইভাবে অন্যান্য আনুষাঙ্গিকগুলিও যুক্ত করতে পারি এবং আমাদের গান সাজাতে পারি।
রেফারেন্স:
https://nulpointerexception.com/2019/05/05/a-beginner-guide-to-decorator-pattern/
সাজসজ্জার ডিজাইন প্যাটার্ন : এই প্যাটার্নটি রানটাইমের সময় কোনও অবজেক্টের বৈশিষ্ট্যগুলিকে সংশোধন করতে সহায়তা করে। এটি কোনও বস্তুকে বিভিন্ন স্বাদ সরবরাহ করে এবং সেই স্বাদে আমরা কী উপাদান ব্যবহার করতে চাই তা চয়ন করার জন্য নমনীয়তা দেয়।
বাস্তব জীবনের উদাহরণ: বলুন যে একটি ফ্লাইটে আপনার কাছে প্রধান কেবিন আসন রয়েছে। এখন আপনাকে আসনটি সহ একাধিক সুযোগ সুবিধা বেছে নেওয়ার অনুমতি দেওয়া হচ্ছে। প্রতিটি সুযোগ সুবিধার সাথে এর নিজস্ব মূল্য যুক্ত হয়। এখন যদি কোনও ব্যবহারকারী ওয়াইফাই এবং প্রিমিয়াম খাবার চয়ন করেন, তবে তাকে সিট + ওয়াইফাই + প্রিমিয়াম খাবারের জন্য চার্জ করা হবে।
এই ক্ষেত্রে সাজসজ্জার ডিজাইন প্যাটার্ন সত্যই আমাদের সহায়তা করতে পারে। ডেকোরেটর প্যাটার্ন এবং একটি বাস্তব জীবনের উদাহরণ বাস্তবায়ন সম্পর্কে আরও জানতে উপরের লিঙ্কটিতে যান।