ইন্টারফেস এবং উত্তরাধিকার: উভয় বিশ্বের সেরা?


10

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

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

কেস 1 (ব্যক্তিগত সদস্যদের সাথে উত্তরাধিকারী, ভাল এনক্যাপসুলেশন, শক্তভাবে মিলিত)

class Employee
{
int money_earned;
string name;

public:
 void do_work(){money_earned++;};
 string get_name(return name;);
};


class Nurse : public Employee: 
{
   public:
   void do_work(/*do work. Oops, can't update money_earned. Unaware I have to call superclass' do_work()*/);

};

void HireNurse(Nurse *n)
{
   nurse->do_work();
)

কেস 2 (কেবল একটি ইন্টারফেস)

class IEmployee
{
     virtual void do_work()=0;
     virtual string get_name()=0;
};

//class Nurse implements IEmployee.
//But now, for each employee, must repeat the get_name() implementation,
//and add a name member string, which breaks DRY.

কেস 3: (উভয় বিশ্বের সেরা?)

কেস 1 এর অনুরূপ । তবে, কল্পনা করুন যে (অনুমানের) সি ++ খাঁটি ভার্চুয়াল এমন পদ্ধতিগুলি বাদ দিয়ে ওভাররাইড পদ্ধতিগুলিকে মঞ্জুরি দেয় না ।

সুতরাং, কেস 1-এ , do_work () ওভাররাইড করা একটি সংকলন-সময় ত্রুটির কারণ হতে পারে। এটি ঠিক করার জন্য, আমরা do_work () কে খাঁটি ভার্চুয়াল হিসাবে সেট করেছি এবং একটি পৃথক পদ্ধতি বৃদ্ধি_মনি_যুক্ত () যুক্ত করি। উদাহরণ হিসাবে:

class Employee
{
int money_earned;
string name;

public:
 virtual void do_work()=0;
 void increment_money_earned(money_earned++;);
 string get_name(return name;);
};


class Nurse : public Employee: 
{
   public:
   void do_work(/*do work*/ increment_money_earned(); ); .
};

এমনকি এটিতেও সমস্যা রয়েছে। যদি এখন থেকে 3 মাস পরে জো কোডার একটি চিকিত্সক কর্মচারী তৈরি করেন তবে তিনি ডু-ওয়ার্ক () এ ইনক্রিমেন্ট_মনি_এয়ার্নড () কল করতে ভুলে যান?


প্রশ্নটি:

  • কি কেস 3 উচ্চতর কেস 1 ? এটি 'ভাল এনক্যাপসুলেশন' বা 'আরও আলগাভাবে মিলিত', বা অন্য কোনও কারণে?

  • কি কেস 3 উচ্চতর করার কেস 2 কারণ শুকিয়ে সঙ্গে কে কনর্ফাম করে?


2
... আপনি বিমূর্ত ক্লাস পুনরুদ্ধার করছেন বা কি?
জেডজেআর

উত্তর:


10

কল-দ্য-সুপার-ক্লাস সমস্যার সমাধানের একটি উপায় হ'ল নিয়ন্ত্রণটি সুপারক্লাসে ফিরিয়ে দেওয়া! কীভাবে (এবং এটি সংকলন করে দিয়েছিল) তা দেখানোর জন্য আমি আপনার প্রথম উদাহরণটি আবার জেগরি করেছি। ওহ, আমি এছাড়াও অনুমান do_work()মধ্যে Employeeহতে অনুমিত ছিল virtualআপনার প্রথম উদাহরণ।

#include <string>

using namespace std;

class Employee
{
    int money_earned;
    string name;
    virtual void on_do_work() {}

    public:
        void do_work() { money_earned++; on_do_work(); }
        string get_name() { return name; }
};

class Nurse : public Employee
{
    void on_do_work() { /* do more work. Oh, and I don't have to call do_work()! */ }
};

void HireNurse(Nurse* nurse)
{
    nurse->do_work();
}

এখন do_work()ওভাররাইড করা যাবে না। আপনি যদি এটি প্রসারিত করতে চান তবে আপনাকে এটি করতে হবে on_do_work()যার মাধ্যমে do_work()নিয়ন্ত্রণ রয়েছে।

এটি অবশ্যই আপনার দ্বিতীয় উদাহরণ থেকে ইন্টারফেসের সাথেও Employeeপ্রসারিত হলে ব্যবহার করা যেতে পারে । সুতরাং, আমি যদি আপনাকে সঠিকভাবে বুঝতে পারি তবে আমি অনুভব করি যে এটি এই কেস 3 করে তবে হাইপোথিটিকাল সি ++ ব্যবহার না করেই! এটি DRY এবং এটি শক্তিশালী encapsulation রয়েছে।


3
এবং এটি হ'ল ডিজাইনের প্যাটার্নটি "টেম্পলেট পদ্ধতি" ( en.wikedia.org/wiki/Template_method_ Pattern) হিসাবে জানেন ।
জোরিস টিমারম্যানস

হ্যাঁ, এটি কেস 3-কমপ্লায়েন্ট। এটি আশাব্যঞ্জক মনে হচ্ছে। বিস্তারিত পরীক্ষা করবে। এছাড়াও, এটি ইভেন্ট সিস্টেমের এক ধরণের। এই 'প্যাটার্ন' এর কোনও নাম আছে?
মোস্তফাএম

@ ম্যাডকিথভি আপনি কি নিশ্চিত যে এটি 'টেম্পলেট পদ্ধতি'?
মোস্তফাএম

@ মেলমাথ - হ্যাঁ, এটি একটি অ-ভার্চুয়াল পাবলিক পদ্ধতি যা এর প্রয়োগের বিশদগুলির অংশগুলি ভার্চুয়াল সুরক্ষিত / ব্যক্তিগত পদ্ধতিতে অর্পণ করে।
জোরিস টিমারম্যানস

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

1

একটি ইন্টারফেসের সাথে সমস্যাটি হ'ল এটির একটি ডিফল্ট বাস্তবায়ন থাকতে পারে না, যা জাগতিক বৈশিষ্ট্যের জন্য ব্যথা এবং ডিআরওয়াইকে পরাস্ত করে।

আমার নিজের মতে, ইন্টারফেসের কেবল খাঁটি পদ্ধতি থাকা উচিত - একটি ডিফল্ট বাস্তবায়ন ছাড়াই। এটি কোনওভাবেই DRY নীতিটি ভঙ্গ করে না, কারণ ইন্টারফেসগুলি দেখায় যে কীভাবে কোনও সত্তাকে অ্যাক্সেস করতে হয়। কেবলমাত্র রেফারেন্সের জন্য, আমি এখানে ডিআরওয়াই ব্যাখ্যার দিকে নজর দিচ্ছি :
"জ্ঞানের প্রতিটি অংশের অবশ্যই একটি সিস্টেমে একক, দ্ব্যর্থহীন, কর্তৃত্বমূলক প্রতিনিধিত্ব থাকতে হবে।"

অন্যদিকে, সলিড আপনাকে বলে যে প্রতিটি শ্রেণীর একটি ইন্টারফেস থাকা উচিত।

কেস 3 কেস কেস 1 এর চেয়ে সেরা? এটি 'ভাল এনক্যাপসুলেশন' বা 'আরও আলগাভাবে মিলিত', বা অন্য কোনও কারণে?

না, কেস 3 কেস 1 এর চেয়ে উচ্চতর নয় You আপনাকে আপনার মন আপ করতে হবে। যদি আপনি একটি ডিফল্ট বাস্তবায়ন করতে চান তবে তা করুন। আপনি যদি খাঁটি পদ্ধতি চান তবে এটির সাথে যান।

যদি এখন থেকে 3 মাস পরে জো কোডার একটি চিকিত্সক কর্মচারী তৈরি করেন তবে তিনি ডু-ওয়ার্ক () এ ইনক্রিমেন্ট_মনি_এয়ার্নড () কল করতে ভুলে যান?

তারপরে জো কোডারকে ব্যর্থ ইউনিট পরীক্ষাগুলি উপেক্ষা করার জন্য যা প্রাপ্য তা পাওয়া উচিত। সে এই ক্লাসটি পরীক্ষা করেছিল, তাই না? :)

কোনও সফ্টওয়্যার প্রকল্পের জন্য কোন কেসটি সেরা যার পক্ষে ৪০,০০০ লাইন কোড থাকতে পারে?

একটি আকার সব ফিট করে না। কোনটি আরও ভাল তা বলা অসম্ভব। এমন কিছু ঘটনা রয়েছে যেখানে একজনের পরে অন্যটির চেয়ে ভাল মানা যায়।

আপনার নিজের কিছু আবিষ্কার করার চেষ্টা না করে আপনার কিছু নকশার ধরণগুলি শেখা উচিত ।


আমি কেবল বুঝতে পেরেছি যে আপনি নন-ভার্চুয়াল ইন্টারফেস ডিজাইনের প্যাটার্নটি খুঁজছেন, কারণ এটি আপনার ক্ষেত্রে 3 শ্রেণির মতো দেখাচ্ছে।


মন্তব্যের জন্য ধন্যবাদ. আমার উদ্দেশ্য আরও সুস্পষ্ট করতে আমি কেস 3 আপডেট করেছি।
মোস্তফাএম

1
আমি আপনাকে এখানে -1 করতে হবে। সমস্ত ইন্টারফেস খাঁটি হওয়া উচিত, বা সমস্ত শ্রেণি ইন্টারফেস থেকে উত্তরাধিকারী হওয়া উচিত তা বলার কোনও কারণ নেই ।
ডেড এমএমজি

@ ডিড এমজি আইএসপি
02-

@ ভিজোভিচ: সলিড এবং "প্রত্যেকটি ইন্টারফেস থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হতে হবে" এর মধ্যে একটি বড় পার্থক্য রয়েছে।
ডেডএমজি

"একটি আকার সবই মাপসই করে না" এবং "কিছু নকশার ধরণগুলি শিখুন" সঠিক - আপনার উত্তরটির বাকী অংশগুলি আপনার নিজের পরামর্শটিকে লঙ্ঘন করে যে একটি আকার সবই ফিট করে না।
জোরিস টিমারম্যানস

0

ইন্টারফেসের সি ++ এ ডিফল্ট বাস্তবায়ন থাকতে পারে। এখানে কোনও কথাই নেই যে কোনও ফাংশনের একটি ডিফল্ট বাস্তবায়ন সম্পূর্ণভাবে অন্যান্য ভার্চুয়াল সদস্যদের (এবং তর্কগুলি) উপর নির্ভর করে না, তাই কোনও ধরণের সংযোগ বাড়ায় না।

কেস 2 এর জন্য, ডিআরওয়াই এখানে সুপারসাইড করছে। আপনার প্রোগ্রাম পরিবর্তন থেকে, বিভিন্ন বাস্তবায়ন থেকে রক্ষা করতে এনক্যাপসুলেশন উপস্থিত রয়েছে তবে এই ক্ষেত্রে আপনার কোনও আলাদা বাস্তবায়ন নেই। সুতরাং YAGNI এনক্যাপসুলেশন।

আসলে, রান-টাইম ইন্টারফেসগুলি সাধারণত তাদের সংকলন-সময়ের সমতুল্যের চেয়ে নিকৃষ্ট বলে বিবেচিত হয়। সংকলন-সময় ক্ষেত্রে, আপনি একই বান্ডলে কেস 1 এবং কেস 2 উভয়ই রাখতে পারেন- এটির অন্যান্য সুবিধাগুলির উল্লেখ না করা। বা রান-টাইমে এমনকি আপনি কার্যকরভাবে একই সুবিধার জন্য করতে পারেন । এই জাতীয় জিনিসগুলি মোকাবেলার জন্য অনেকগুলি উপায় রয়েছে।Employee : public IEmployee

Case 3: (best of both worlds?)

Similar to Case 1. However, imagine that (hypothetically)

পড়া বন্ধ করে দিলাম। YAGNI। সি ++ হ'ল সি ++ হ'ল এবং স্ট্যান্ডার্ডস কমিটি কখনই কখনও দুর্দান্ত কারণগুলির জন্য এই ধরনের পরিবর্তন বাস্তবায়ন করতে চলে না।


আপনি বলছেন "আপনার কোনও আলাদা বাস্তবায়ন নেই"। কিন্তু আমি করি. আমার কর্মচারীর নার্স প্রয়োগ রয়েছে এবং পরে আমার অন্যান্য প্রয়োগও হতে পারে (একজন ডাক্তার, একজন জেনেটর ইত্যাদি)। আমি কী বলতে চাইছিলাম তা আরও পরিষ্কার করার জন্য আমি কেস 3 আপডেট করেছি।
মোস্তফাএম

@ মিলমাথ: তবে আপনার আর কোনও বাস্তবায়ন নেই get_name। আপনার প্রস্তাবিত সমস্ত বাস্তবায়ন একই বাস্তবায়ন ভাগ করে নেবে get_name। এছাড়াও, যেমনটি আমি বলেছি, বেছে নেওয়ার কোনও কারণ নেই, আপনি উভয়ই রাখতে পারেন। এছাড়াও, কেস 3 সম্পূর্ণ নিরর্থক। আপনি খাঁটি-খাঁটি ভার্চুয়ালগুলিকে ওভাররাইড করতে পারেন, তাই এমন নকশার কথা ভুলে যান যেখানে আপনি পারবেন না।
ডেড এমএমজি

ইন্টারফেস কেবল সি ++ এ ডিফল্ট বাস্তবায়ন করতে পারে না, তাদের ডিফল্ট বাস্তবায়ন থাকতে পারে এবং এখনও বিমূর্ত হতে পারে! অর্থাত্ ভার্চুয়াল শূন্যতা আইমেথোদ () = 0 {স্টাডি :: কোট << "নী!" << স্ট্যান্ড :: এন্ডল; }
জোরিস টিমারম্যানস

@ ম্যাডকিথভি: আমি বিশ্বাস করি না যে আপনি তাদের ইনলাইন সংজ্ঞায়িত করতে পারেন, তবে বিষয়টি এখনও একইরকম।
ডেডএমজি

@ ম্যাডকিথ: যেন ভিজ্যুয়াল স্টুডিও স্ট্যান্ডার্ড সি ++ এর বিশেষভাবে নিখুঁত প্রতিনিধিত্ব করে।
ডেডএমজি

0

কেস 3 কেস কেস 1 এর চেয়ে সেরা? এটি 'ভাল এনক্যাপসুলেশন' বা 'আরও আলগাভাবে মিলিত', বা অন্য কোনও কারণে?

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

কোন কেসটি কোনও সফ্টওয়্যার প্রকল্পের জন্য সেরা যাতে ৪০,০০০ লাইন কোড থাকতে পারে।

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

প্রশ্নে সম্পাদনা করুন

যদি এখন থেকে 3 মাস পরে জো কোডার একটি চিকিত্সক কর্মচারী তৈরি করেন তবে তিনি ডু-ওয়ার্ক () এ ইনক্রিমেন্ট_মনি_এয়ার্নড () কল করতে ভুলে যান?

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


0

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

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