একটি বাস্তব বিশ্বের উদাহরণ সহ "সজ্জিত প্যাটার্ন" বুঝতে


167

আমি জিওএফ-তে ডকুমেন্টেড হিসাবে ডেকরেটার প্যাটার্ন অধ্যয়ন করছিলাম ।

দয়া করে, আমাকে সজ্জিত প্যাটার্নটি বুঝতে সহায়তা করুন । সত্যিকারের বিশ্বে এটি কোথায় কার্যকর তা ব্যবহারের ক্ষেত্রে কেউ উদাহরণ দিতে পারে?


8
: আপনি এখানে জাভা এপিআই মধ্যে কিছু সফটওয়ারটি আরেকটি জটিল উদাহরণ জানতে পারেন stackoverflow.com/questions/1673841/...
BalusC

একটি নিবন্ধ যা সাধারণ উদাহরণগুলির সাথে সজ্জিত
nbilal

উত্তর:


226

ডেকোরেটর প্যাটার্নটি কোনও বস্তুর গতিশীলভাবে দায়িত্ব যুক্ত করার একক লক্ষ্য অর্জন করে।

একটি পিজা দোকানে একটি মামলা বিবেচনা করুন। পিজ্জার দোকানে তারা কয়েকটি পিজ্জা জাত বিক্রি করবে এবং তারা মেনুতে শীর্ষস্থানগুলি সরবরাহ করবে। এখন এমন পরিস্থিতিটি কল্পনা করুন যার মধ্যে যদি পিজ্জা শপকে পিজ্জা এবং টপিংয়ের প্রতিটি সংমিশ্রনের জন্য দাম সরবরাহ করতে হয়। এমনকি যদি চারটি বেসিক পিজ্জা এবং 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;
    }
}

104
এই প্যাটার্নটি কিছুটা পছন্দ করবেন না। যদিও এটি উদাহরণ হতে পারে। ওওডির সাথে আমার এটির প্রধান সমস্যাটি হ'ল টপিং পিজ্জা নয় । এটি যে পিজ্জার জন্য প্রয়োগ করা হয়েছে কেবল তার মূল্যের জন্য শীর্ষস্থান নির্ধারণ করা আমার সাথে ঠিক বসে না। এটি যদিও খুব চিন্তাশীল এবং বিশদ উদাহরণ, তাই এর জন্য আপনাকে কড়া নাড়ানোর অর্থ আমার নেই।
টম ডব্লিউ

39
@ টমডব্লু আমি মনে করি যে ইস্যুটির একটি অংশ নামকরণ। "শীর্ষস্থানীয়" শ্রেণীর সকলকেই "পিজ্জাউথ <টপিং>" বলা উচিত। উদাহরণস্বরূপ, "পিজ্জাবিথমশরুম"।
জোশ নয়ে

2
আমার মতে, সাজসজ্জারগুলি যথাসম্ভব সমতলভাবে ব্যবহৃত হয়। এর মাধ্যমে আমি যতটা সম্ভব "সজ্জিত মোড়ক সজ্জিত" বলতে চাইছি। সুতরাং সম্ভবত এই উদাহরণটি সবচেয়ে উপযুক্ত নয়। তবে এটি বেশ পুঙ্খানুপুঙ্খ, যা দুর্দান্ত।
thekingoftruth

17
অন্য দৃষ্টিকোণ থেকে এটি "রিয়েল ওয়ার্ল্ড" এর কাছাকাছিও নয়। বাস্তব বিশ্বে আপনার প্রত্যেকবার মেনুতে নতুন টপিং যুক্ত করতে (বা দাম পরিবর্তন করতে হবে) পুনরায় সংকলন করা উচিত নয়। শীর্ষস্থানীয়গুলি (সাধারণত) ডাটাবেসে সঞ্চিত থাকে এবং উপরের উদাহরণটি অকেজো করে দেয়।
স্টিলিওস অ্যাডামেন্টিডিস

4
এই। আমি মনে করি এই প্যাটার্নটি অধ্যয়ন করার সময় এটিই আমাকে বিরক্ত করেছিল। আমি যদি একটি সফ্টওয়্যার সংস্থা হয়ে পিৎজা শপের সফটওয়্যারটি লিখতাম তবে প্রতিবার পুনরায় সংযোগ করতে এবং পুনরায় চালনা করতে চাই না। আমি ব্যাকএন্ডে একটি টেবিলের মধ্যে একটি সারি বা এমন কিছু যুক্ত করতে চাই যা সহজেই তাদের প্রয়োজনীয়তার যত্ন নিতে পারে। ভাল বলেছেন, @ স্টেলিয়াস অ্যাডামেন্টিডিস আমার ধারণা, প্যাটার্নগুলির বৃহত্তম শক্তি যদিও তৃতীয় পক্ষের ক্লাসগুলি সংশোধন করা হবে।
কানুকলস্যান্ডউইচ

33

এটি কোনও বিদ্যমান অবজেক্টে গতিশীলভাবে নতুন আচরণ বা ডেকরেটার প্যাটার্ন যুক্ত করার সহজ উদাহরণ। জাভাস্ক্রিপ্টের মতো গতিময় ভাষার প্রকৃতির কারণে, এই প্যাটার্নটি নিজেই ভাষার অংশ হয়ে যায়।

// 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');


সহজ এবং নির্ভুল! দুর্দান্ত উদাহরণ!
নগেন্দ্র 547

1
আমি মনে করি না যে ডেকরেটর প্যাটার্নের ধারণাটি এখানে প্রযোজ্য। আসলে এটি আদৌ কোনও প্যাটার্ন নয়! হ্যাঁ, আপনি রানটাইমে একটি নতুন পদ্ধতি যুক্ত করছেন। এবং সম্ভবত কোনও switchবা ifসাধারণের অভ্যন্তরে, আপনি দাবি করতে সক্ষম হবেন যে এটি একটি ক্লাসে গতিশীল আচরণ যুক্ত করার একটি দুর্দান্ত উদাহরণ B তবে আমাদের এই প্যাটার্নে সাজসজ্জা এবং সজ্জিত বস্তুর সংজ্ঞা দিতে আমাদের কমপক্ষে দুটি শ্রেণি প্রয়োজন।
ইমান

1
@ জিচ আমি বুঝতে পারি যে আমার উদাহরণে কোনও ডেকরেটার নেই তবে এটি একটি ফাংশন যোগ করে সহজেই সংশোধন করা যায় যা ডেকরেটর হিসাবে কাজ করে। তবে আমার উদাহরণে একটি সজ্জিত বস্তু রয়েছে। প্যাটার্নটি কোথাও বলছে যে আপনার বিশেষভাবে দুটি ক্লাসের প্রয়োজন ?
অনুরাগ

18

এটি লক্ষণীয় যে জাভা i / o মডেলটি সাজসজ্জার প্যাটার্নের উপর ভিত্তি করে। শীর্ষে থাকা এই পাঠকের শীর্ষে এই পাঠকের স্তর ... সাজসজ্জার এক বাস্তব বাস্তব উদাহরণ।


বাস্তব পাবলিক এপিআইগুলিতে কি অন্য কোনও উদাহরণ রয়েছে? এটিই আমি জানি।
জোশিয়ার যোদার

দেখে মনে হয় প্রকৃতির সমস্ত মোড়ক ফাংশনগুলির মধ্যে কিছু সাজসজ্জা বিন্যাস রয়েছে যা আমি মনে করি এটি কি?
হার্ভে লিন

ভালো উদাহরণ !!
নগেন্দ্র 547

8

উদাহরণ - পরিস্থিতি- ধরা যাক আপনি একটি এনক্রিপশন মডিউল লিখছেন। এই এনক্রিপশনটি ডিইএস - ডেটা এনক্রিপশন মান ব্যবহার করে পরিষ্কার ফাইল এনক্রিপ্ট করতে পারে। একইভাবে, কোনও সিস্টেমে আপনার কাছে এইএস - অ্যাডভান্স এনক্রিপশন মান হিসাবে এনক্রিপশন থাকতে পারে। এছাড়াও, আপনার এনক্রিপশনের সংমিশ্রণ থাকতে পারে - প্রথম ডিইএস, তারপরে এইএস। অথবা আপনি প্রথম এইএস, তারপরে ডিইএস রাখতে পারেন।

আলোচনা- আপনি এই পরিস্থিতিটি কীভাবে পূরণ করবেন? আপনি যেমন সংমিশ্রণগুলির অবজেক্ট তৈরি করে রাখতে পারবেন না - উদাহরণস্বরূপ - এইএস এবং ডিইএস - মোট 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

এখানে ইউএমএল চিত্র - এর শ্রেণি উপস্থাপনা। সেক্ষেত্রে আপনি কোডটি এড়িয়ে ডিজাইনের দিকটিতে ফোকাস করতে চান।

এখানে চিত্র বর্ণনা লিখুন


1
উদাহরণ কি আরও উপযুক্ত নয় strategy pattern?
এক্সেক্সিয়ান

@ এক্সেক্সিয়ান হ্যাঁ, আমার শিক্ষার্থীরা ধারাবাহিকভাবে এই ধরণের সমস্যার জন্য আমাকে কৌশলগুলির একটি তালিকার পরামর্শ দেয় এবং এটি আমার কাছেও সবচেয়ে পরিষ্কার সমাধান বলে মনে হয়।
জোশিয়ার যোদার

না, কৌশল বিন্যাসের সাহায্যে আপনি এনক্রিপশন পদ্ধতিগুলি একত্রিত করতে পারবেন না। থিওফোর আপনাকে প্রতিটি সম্ভাব্য সংমিশ্রনের জন্য কৌশল শ্রেণি তৈরি করতে হবে।
ডিটজ

4

ডেকোরেটর প্যাটার্ন আপনাকে এই অবজেক্টের অন্যান্য অনুরূপ উপশ্রেণীর সাথে শৃঙ্খলাবদ্ধ করে আপনার অবজেক্টের কার্যকারিতা পরিবর্তন বা কনফিগার করতে সহায়তা করে।

জাভা.ইও প্যাকেজের ইনপুটস্ট্রিম এবং আউটপুট স্ট্রিম ক্লাসগুলির সর্বোত্তম উদাহরণ

    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.

এই ক্ষেত্রে, কলিং চেইনটি অবজেক্টআউটপুট স্ট্রিম থেকে শুরু হয়, তারপরে ফাইল ক্লাস পর্যন্ত সমস্ত পথ যায়, তারপরে ফাইল শ্রেণিটি মানটি দেয়, অন্য তিনটি সাবক্লাস তাদের সমস্ত যোগ করে এবং শেষ অবধি, অবজেক্টআউটপুটস্ট্রিমের পদ্ধতির মান এটি ফেরত দেয়, ঠিক?
হার্ভে লিন

3

জাভাতে সজ্জা নকশার প্যাটার্নটি কী।

জিওএফ বইয়ের (ডিজাইনের প্যাটার্নস: এলিজেন্টস অফ রিজ্যাবল অবজেক্ট-ওরিয়েন্টড সফটওয়্যার, 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());

}

}

3

আমি আমার কাজগুলিতে সজ্জিত প্যাটার্ন ব্যবহার করেছি। লগিংয়ের মাধ্যমে এটি কীভাবে ব্যবহার করতে হয় সে সম্পর্কে আমি আমার ব্লগে একটি পোস্ট তৈরি করেছি


আমি পছন্দ করি না আপনি উত্তর হিসাবে কেবল একটি লিঙ্ক ছুঁড়ে দিয়েছেন। তবে আপনার ব্লগ আর্টিকেলটি এত সহায়ক, যে আমাকে সবেমাত্র উজ্জীবিত করতে হয়েছিল :)। এখন আমি সত্যিই এটি বুঝতে। প্রত্যেকে পিজ্জা নিয়ে আসছেন, এবং আপনি একটি নিখুঁত উদাহরণ সহ।
নিক্লাস রাব

2

ডেকোরেটর প্যাটার্ন আপনাকে বস্তুগুলিতে গতিশীল আচরণ করতে দেয়।

আসুন একটি উদাহরণ নেওয়া যাক যেখানে আপনাকে এমন অ্যাপ তৈরি করতে হবে যা বিভিন্ন ধরণের বার্গারের দাম গণনা করে। আপনাকে বার্গারের বিভিন্ন প্রকারের হ্যান্ডেল করতে হবে, যেমন "লার্জ" বা "পনির সহ", যার প্রত্যেকটিরই মূল বার্গারের সাথে দাম রয়েছে। যেমন পনির দিয়ে বার্গারের জন্য 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 প্রতিটি নতুন সম্পত্তির জন্য সমস্ত অনুমতিগুলি কভার করার জন্য আরও বেশি সাজসজ্জার প্রয়োজন।

পুনশ্চ. এটি রুবিতে ডেকোরেটর প্যাটার্নটি ব্যবহার করার বিষয়ে আমি যে নিবন্ধটি লিখেছি তার সংক্ষিপ্ত সংস্করণ , যা আপনি আরও বিস্তারিত উদাহরণগুলি সন্ধান করতে চাইলে আপনি পড়তে পারেন।


2

প্রসাধক:

  1. রান সময় অবজেক্টের সাথে আচরণ যুক্ত করুন । উত্তরাধিকার এই কার্যকারিতা অর্জনের মূল চাবিকাঠি, যা এই প্যাটার্নটির সুবিধা এবং অসুবিধা উভয়ই।
  2. এটি আচরণকে বাড়ায় ইন্টারফেসের ।
  3. সাজসজ্জারকে ডিজেনারেট কম্পোজিট হিসাবে দেখা যেতে পারে শুধুমাত্র একটি উপাদান সহ । যাইহোক, কোনও সাজসজ্জা অতিরিক্ত দায়িত্ব যুক্ত করে - এটি উদ্দেশ্য সামগ্রীর জন্য নয়।
  4. ডেকোরেটর শ্রেণি এলসিডি (নিম্নতম শ্রেণি ডিনোমিনেটর) ইন্টারফেসের সাথে একটি রচনা সম্পর্ক ঘোষণা করে এবং এই ডেটা সদস্যটি তার নির্মাত্রে আরম্ভ করা হয়।
  5. উপ-শ্রেণিবদ্ধকরণ ছাড়াই আপনাকে অবজেক্টগুলিতে দায়িত্ব যুক্ত করতে দেওয়ার জন্য সজ্জিত ডিজাইন করা হয়েছে

পড়ুন 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);;
}

ইউএমএল ডায়াগ্রাম এবং কোড উদাহরণগুলির জন্য এসই নীচে প্রশ্নটি দেখুন।

আইও এর জন্য সজ্জিত প্যাটার্ন

দরকারী নিবন্ধ:

journaldev

উইকিপিডিয়া

ডেকোরেটার প্যাটার্নের আসল শব্দের উদাহরণ: ভেন্ডিংম্যাচাইনডেকরেটরটি ব্যাখ্যা করা হয়েছে @

সজ্জিত প্যাটার্ন কখন ব্যবহার করবেন?

Beverage beverage = new SugarDecorator(new LemonDecorator(new Tea("Assam Tea")));
beverage.decorateBeverage();

beverage = new SugarDecorator(new LemonDecorator(new Coffee("Cappuccino")));
beverage.decorateBeverage();

উপরের উদাহরণে, চা বা কফি (পানীয়) চিনি এবং লেবু দ্বারা সজ্জিত করা হয়েছে।


2

ডেকোরেটর প্যাটার্নটি কোনও বস্তুর গতিশীলভাবে দায়িত্ব যুক্ত করার একক লক্ষ্য অর্জন করে

জাভা আই / ও মডেল সাজসজ্জার ধরণের উপর ভিত্তি করে।

ডেকরেটার প্যাটার্ন হিসাবে জাভা আইও


1

স্ক্রোলবার দিয়ে উইন্ডো সাজানোর বিষয়ে উইকিপিডিয়ায় একটি উদাহরণ রয়েছে:

http://en.wikipedia.org/wiki/Decorator_pattern

এখানে "টিম মেম্বার, টিম লিড এবং ম্যানেজার" এর আরও একটি 'বাস্তব জগত' উদাহরণ রয়েছে যা বর্ণনা করে যে ডেকোরেটার প্যাটার্নটি সহজ উত্তরাধিকারের সাথে অপরিবর্তনীয়:

https://zishanbilal.wordpress.com/2011/04/28/design-patterns-by-examples-decorator-pattern/


সেই জিশান বিলালের লিঙ্কটি দুর্দান্ত - সর্বোত্তম উদাহরণ আমি দেখেছি
স্টোনডাউজ

1

কিছুক্ষণ আগে আমি ডেকরেটার প্যাটার্ন ব্যবহার করে একটি কোডবেস রিফ্যাক্টর করেছি, তাই আমি ব্যবহারের কেসটি ব্যাখ্যা করার চেষ্টা করব।

ধরে নেওয়া যাক আমাদের পরিষেবাগুলির একটি সেট রয়েছে এবং ব্যবহারকারী নির্দিষ্ট পরিষেবার লাইসেন্স অর্জন করেছে কিনা তার উপর ভিত্তি করে আমাদের পরিষেবাটি শুরু করা দরকার।

সমস্ত পরিষেবাগুলির একটি সাধারণ ইন্টারফেস রয়েছে

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");

takeaways

  • কোডের সংহতি আরও ভাল হয়েছে
  • ইউনিট টেস্টিং আরও সহজ হয়ে উঠেছে, কারণ সার্ভিস সাপোর্টের পরীক্ষা করার সময় লাইসেন্সিং উপহাস করতে হবে না
  • পটভূমি পরিষেবাগুলির জন্য কোনও বিশেষ চেক দ্বারা লাইসেন্সিংকে বাইপাস করার দরকার নেই
  • দায়িত্বের যথাযথ বিভাজন

1

আসুন পাবজির উদাহরণ নিই। অ্যাসল্ট রাইফেলগুলি 4x জুমের সাথে সবচেয়ে ভাল কাজ করে এবং আমরা যখন এটিতে থাকি তখন আমাদের ক্ষতিপূরণকারী এবং দমনকারীও দরকার। এটি হতাশাগুলি হ্রাস করবে এবং ফায়ারিং সাউন্ডের পাশাপাশি প্রতিধ্বনি হ্রাস করবে। আমাদের এই বৈশিষ্ট্যটি প্রয়োগ করতে হবে যেখানে আমরা খেলোয়াড়দের তাদের পছন্দসই বন্দুক এবং তাদের আনুষাঙ্গিক কিনতে দেবো। খেলোয়াড়গণ বন্দুক বা কিছু আনুষাঙ্গিক বা আনুষাঙ্গিকের কিছু কিনতে পারেন এবং সেই অনুযায়ী তাদের চার্জ করা হবে।

আসুন দেখুন এখানে কীভাবে ডেকরেটার প্যাটার্ন প্রয়োগ করা হয়:

মনে করুন উপরে উল্লিখিত তিনটি জিনিসপত্র সহ কেউ এসসিএআর-এল কিনতে চান।

  1. SCAR-L এর একটি অবজেক্ট নিন
  2. 4x জুম অবজেক্টের সাথে SCAR-L সাজাইয়া (বা যুক্ত করুন)
  3. দমনকারী অবজেক্টের সাথে SCAR-L সাজাই Dec
  4. সংকোচকারী বস্তুর সাথে SCAR-L সাজাই
  5. ব্যয় পদ্ধতিটি কল করুন এবং প্রতিটি বস্তুর প্রতিনিধিকে আনুষাঙ্গিক ব্যয়ের পদ্ধতি ব্যবহার করে ব্যয় যোগ করতে দিন

এটি এর মতো শ্রেণীর চিত্র তৈরি করবে:

কর্মক্ষেত্রে সজ্জা প্যাটার্ন

এখন, আমরা এর মতো ক্লাস করতে পারি:

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/


0

সাজসজ্জার ডিজাইন প্যাটার্ন : এই প্যাটার্নটি রানটাইমের সময় কোনও অবজেক্টের বৈশিষ্ট্যগুলিকে সংশোধন করতে সহায়তা করে। এটি কোনও বস্তুকে বিভিন্ন স্বাদ সরবরাহ করে এবং সেই স্বাদে আমরা কী উপাদান ব্যবহার করতে চাই তা চয়ন করার জন্য নমনীয়তা দেয়।

বাস্তব জীবনের উদাহরণ: বলুন যে একটি ফ্লাইটে আপনার কাছে প্রধান কেবিন আসন রয়েছে। এখন আপনাকে আসনটি সহ একাধিক সুযোগ সুবিধা বেছে নেওয়ার অনুমতি দেওয়া হচ্ছে। প্রতিটি সুযোগ সুবিধার সাথে এর নিজস্ব মূল্য যুক্ত হয়। এখন যদি কোনও ব্যবহারকারী ওয়াইফাই এবং প্রিমিয়াম খাবার চয়ন করেন, তবে তাকে সিট + ওয়াইফাই + প্রিমিয়াম খাবারের জন্য চার্জ করা হবে।

এখানে চিত্র বর্ণনা লিখুন

এই ক্ষেত্রে সাজসজ্জার ডিজাইন প্যাটার্ন সত্যই আমাদের সহায়তা করতে পারে। ডেকোরেটর প্যাটার্ন এবং একটি বাস্তব জীবনের উদাহরণ বাস্তবায়ন সম্পর্কে আরও জানতে উপরের লিঙ্কটিতে যান।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.