পলিমারফিক আচরণের জন্য নকশার প্যাটার্ন লাইব্রেরি পৃথককরণের অনুমতি দেওয়ার সময়


10

আসুন আমি একটি অনুক্রমের আছে Itemক্লাস: Rectangle, Circle, Triangle। আমি সেগুলি আঁকতে সক্ষম হতে চাই, সুতরাং আমার প্রথম সম্ভাবনাটি Draw()প্রতিটিটিতে একটি ভার্চুয়াল পদ্ধতি যুক্ত করা:

class Item {
public:
   virtual ~Item();
   virtual void Draw() =0; 
};

যাইহোক, আমি অঙ্কন কার্যকারিতাটি একটি পৃথক ড্র লাইব্রেরিতে বিভক্ত করতে চাই যখন কোর লাইব্রেরিতে কেবলমাত্র প্রাথমিক উপস্থাপনা রয়েছে contains আমি ভাবতে পারি এমন বেশ কয়েকটি সম্ভাবনা রয়েছে:

1 - এ DrawManagerযা Itemএর তালিকা নিয়েছে এবং dynamic_cast<>কী করতে হবে তা কাজে লাগাতে হবে:

class DrawManager {
  void draw(ItemList& items) {
    FOREACH(Item* item, items) {
       if (dynamic_cast<Rectangle*>(item)) {
          drawRectangle();
       } else if (dynamic_cast<Circle*>(item)) {
          drawCircle();
       } ....
    }
  }
};

এটি আদর্শ নয় কারণ এটি আরটিটিআইয়ের উপর নির্ভর করে এবং এক শ্রেণিকে শ্রেণিবিন্যাসের সমস্ত আইটেম সম্পর্কে সচেতন হতে বাধ্য করে।

2 - অন্য পদ্ধতিটি ItemDrawerহায়ারার্কির প্রতি অঙ্কন করার দায়িত্ব স্থগিত করা ( RectangleDrawerইত্যাদি):

class Item {
   virtual Drawer* GetDrawer() =0;
}

class Rectangle : public Item {
public:
   virtual Drawer* GetDrawer() {return new RectangleDrawer(this); }
}

এটি আইটেমগুলির বেস উপস্থাপন এবং অঙ্কন করার কোডের মধ্যে উদ্বেগের বিভাজন অর্জন করে। সমস্যাটি হ'ল আইটেম ক্লাসগুলি অঙ্কন ক্লাসের উপর নির্ভরশীল।

আমি কীভাবে এই অঙ্কন কোডটি আলাদা লাইব্রেরিতে আলাদা করতে পারি? আইটেমগুলির সমাধানটি কি কোনও বিবরণের কারখানার শ্রেণি ফেরত দেয়? তবে এটি কীভাবে সংজ্ঞায়িত করা যায় যাতে কোর লাইব্রেরি ড্র লাইব্রেরির উপর নির্ভরশীল না?

উত্তর:


3

কটাক্ষপাত পরিদর্শক প্যাটার্ন

এর উদ্দেশ্যটি হ'ল একটি অ্যালগরিদমকে (আপনার ক্ষেত্রে অঙ্কনে) কোনও অবজেক্ট স্ট্রাকচারের উপর (আইটেমগুলি) চালনা করে separate

আপনার সমস্যাটির জন্য একটি সাধারণ উদাহরণটি হ'ল:

class Item
{
public:
    virtual void visit(Visitable v)
    {
        v.accept(*this)
    }
};

class Rectangle : public Item
{
public:
    virtual void visit(Visitable v)
    {
        v.accept(*this)
    }
};

class Circle : public Item
{
public:
    virtual void visit(Visitable v)
    {
        v.accept(*this)
    }
};


class Visitable
{
public:
    virtual void accept(Rectangle& r);
    virtual void accept(Circle& c);
};

class Drawer : public Visitable
{
public:
    void accept(Rectangle& r)
    {
        // draw rectangle
    }   
    void accept(Circle& c)
    {
        // draw circle
    }
};


int main()
{
    Item* i1 = new Circle;
    Item* i2 = new Rectangle;

    Drawer d;
    i1->visit(d); // Draw circle
    i2->visit(d); // Draw rectangle

    return 1;
}

আকর্ষণীয় - পলিমারফিজম অর্জনের জন্য আমি ওভারলোডিংয়ের সাথে দর্শনার্থীর ব্যবহার সম্পর্কে কখনও ভাবিনি। যদিও রানটাইমের সময় এই ওভারলোডটি সঠিকভাবে হবে?
the_mandrill

হ্যাঁ এটি সঠিকভাবে ওভারলোড হবে। সম্পাদিত উত্তর দেখুন
হটপোটাতো

আমি দেখতে পাচ্ছি যে এটি কাজ করে। এটি প্রতিটি ক্ষেত্রে উত্পন্ন শ্রেণীর visit()পদ্ধতিটি প্রয়োগ করতে হবে যদিও এটি লজ্জাজনক ।
the_mandrill

এটি আমাকে আরও কিছু অনুসন্ধান করতে উত্সাহিত করেছিল এবং আমি এখন লোকির ভিজিটর ধাঁচের বাস্তবায়ন খুঁজে পেয়েছি যা মনে হচ্ছে ঠিক যা খুঁজছি! আমি গাছগুলিতে নোড দেখার জন্য দর্শনার্থীর প্যাটার্নের সাথে পরিচিত ছিলাম তবে এটি সম্পর্কে আরও বিমূর্ত পদ্ধতিতে ভাবা হয়নি।
the_mandrill

2

আপনি যে বিভাজনটি বর্ণনা করেছেন - দুটি সমান্তরাল শ্রেণিবিন্যাসে - এটি মূলত সেতুর প্যাটার্ন

আপনি উদ্বেগ প্রকাশ করেছেন যে এটি পরিমার্জনযুক্ত বিমূর্ততা (আয়তক্ষেত্র ইত্যাদি) বাস্তবায়নের উপর নির্ভর করে (আয়তক্ষেত্রগুলি), তবে আপনি কীভাবে পুরোপুরি এড়াতে পারবেন তা নিশ্চিত নই।

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

এটি একটি দরকারী বিমূর্ততা কিনা তা জিজ্ঞাসা করাও মূল্যবান। একটি আয়তক্ষেত্রটি অঙ্কন করা কি এতই শক্ত যে এটি একটি পৃথক শ্রেণিতে স্থাপন করা উপযুক্ত, বা আপনি কি সত্যিই গ্রাফিক্স লাইব্রেরি বিমূর্ত করার চেষ্টা করছেন?


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

কী আমি ভাবছি হয় RectangleDrawer, CircleDrawerইত্যাদি বিমূর্ত গ্রাফিক্স লাইব্রেরিতে সবচেয়ে দরকারী উপায় নাও হতে পারে। পরিবর্তে, আপনি যদি একটি নিয়মিত বিমূর্ত ইন্টারফেসের মাধ্যমে আদিমতার একটি সেট প্রকাশ করেন তবে আপনি এখনও নির্ভরতা ভঙ্গ করেন।
অকেজো

1

কটাক্ষপাত আছে মূল্য শব্দ এবং ধারণা ভিত্তিক পলিমরফিজ্ম

আমি বহুবর্ষকে কীভাবে দেখি তা এই কাজের পরিবর্তিত হয়েছে। আমরা এই সিস্টেমটি পুনরাবৃত্তি পরিস্থিতিতে দুর্দান্ত প্রভাবিত করতে ব্যবহার করেছি।


এটি আকর্ষণীয় দেখাচ্ছে - মনে হচ্ছে এটি যে দিকে যাচ্ছিল সেদিকেই
চলছে

1
লিঙ্কটি নষ্ট হয়ে গেছে। এ কারণেই উত্তরগুলি যেগুলি কেবলমাত্র লিংকযুক্ত তা নিরুৎসাহিত করা হয়।
এজেবি

0

আপনার সমস্যার কারণ হ'ল কারণ বস্তুগুলি তাদের নিজেরাই আঁকানো উচিত নয়। কোনও কিছুর অঙ্কন সঠিকভাবে এক বিলিয়ন টুকরো রাষ্ট্রের উপর নির্ভর করে এবং একটি আয়তক্ষেত্র those টুকরোটির কোনওটিই পাবে না। আপনার একটি কেন্দ্রীয় গ্রাফিকাল অবজেক্ট থাকা উচিত যা ব্যাকবুফার / গভীরতা বাফার / শেডার / ইত্যাদির মতো মূল রাজ্যের প্রতিনিধিত্ব করে এবং তারপরে এটি একটি অঙ্কন () পদ্ধতি দেয়।


আমি সম্মত হই যে অবজেক্টগুলি তাদের নিজস্ব হওয়া উচিত নয়, তাই উদ্বেগের একটি বিচ্ছেদ অর্জনের জন্য সেই ক্ষমতাটিকে অন্য শ্রেণিতে স্থানান্তরিত করার আকাঙ্ক্ষা। ধরুন এই শ্রেণিগুলি ছিল Dogবা Cat- তাদের আঁকার জন্য যে বিষয়বস্তু দায়বদ্ধ তা আয়তক্ষেত্র আঁকার চেয়ে অনেক জটিল।
the_mandrill
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.