ডেলিগেট বনাম ইন্টারফেস-আরও কি কি স্পেসিফিকেশন উপলব্ধ?


23

নিবন্ধটি পড়ার পরে - ইন্টারফেসের পরিবর্তে ডেলিগেটস কখন ব্যবহার করবেন (সি # প্রোগ্রামিং গাইড) , আমার নীচের প্রদত্ত পয়েন্টগুলি বোঝার জন্য কিছুটা সাহায্যের প্রয়োজন, যা আমি এতটা স্পষ্ট (আমার জন্য) খুঁজে পাইনি। এগুলির জন্য কোনও উদাহরণ বা বিস্তারিত ব্যাখ্যা উপলব্ধ?

প্রতিনিধি ব্যবহার করুন যখন:

  • একটি ইভেন্ট ডিজাইনের প্যাটার্ন ব্যবহৃত হয়।
  • এটি একটি স্থিতিশীল পদ্ধতি আবদ্ধ করা বাঞ্চনীয়।
  • সহজ রচনাটি পছন্দসই।
  • কোনও শ্রেণীর পদ্ধতির একাধিক বাস্তবায়ন প্রয়োজন হতে পারে।

একটি ইন্টারফেস ব্যবহার করুন যখন:

  • সম্পর্কিত একটি গ্রুপ রয়েছে যা বলা যেতে পারে।
  • একটি শ্রেণীর কেবল পদ্ধতির একটি প্রয়োগ প্রয়োজন।

আমার প্রশ্নগুলি হ'ল,

  1. ইভেন্ট ইভেন্ট ডিজাইনের ধরণ বলতে কী বোঝায়?
  2. যদি কোনও প্রতিনিধি ব্যবহার করা হয় তবে রচনাটি কীভাবে সহজ হতে পারে?
  3. যদি এমন কোনও গ্রুপ রয়েছে যা কল করা যেতে পারে, তবে ইন্টারফেসটি ব্যবহার করুন-এতে কী লাভ?
  4. যদি কোনও শ্রেণীর কেবল পদ্ধতিটির একটি প্রয়োগকরণ প্রয়োজন হয়, তবে ইন্টারফেসটি ব্যবহার করুন-এটি কীভাবে বেনিফিটের ক্ষেত্রে ন্যায়সঙ্গত?

উত্তর:


11

ইভেন্ট ইভেন্ট ডিজাইনের ধরণ বলতে কী বোঝায়?

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

যদি কোনও প্রতিনিধি ব্যবহার করা হয় তবে রচনাটি কীভাবে সহজ হতে পারে?

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

class Bunny
{
    Func<bool> _canHop;

    public Bunny( Func<bool> canHop )
    {
        _canHop = canHop;
    }

    public void Hop()
    {
        if ( _canHop() )  Console.WriteLine( "Hop!" );
    }
}

Bunny captiveBunny = new Bunny( () => IsBunnyReleased );
Bunny lazyBunny = new Bunny( () => !IsLazyDay );
Bunny captiveLazyBunny = new Bunny( () => IsBunnyReleased && !IsLazyDay );

ইন্টারফেসের সাথে অনুরূপ কিছু করার জন্য আপনাকে কৌশল প্যাটার্ন ব্যবহার করতে হবে বা এমন একটি (বিমূর্ত) বেস Bunnyক্লাস ব্যবহার করা উচিত যা থেকে আপনি আরও নির্দিষ্ট বার্নি প্রসারিত করেন extend

যদি এমন কোনও গ্রুপ রয়েছে যা কল করা যেতে পারে, তবে ইন্টারফেসটি ব্যবহার করুন-এতে কী লাভ?

আবার, আমি কীভাবে আরও সহজ হব তা প্রদর্শনের জন্য আমি বানি ব্যবহার করব।

interface IAnimal
{
    void Jump();
    void Eat();
    void Poo();
}

class Bunny : IAnimal { ... }
class Chick : IAnimal { ... }

// Using the interface.
IAnimal bunny = new Bunny();
bunny.Jump();  bunny.Eat();  bunny.Poo();
IAnimal chick = new Chick();
chick.Jump();  chick.Eat();  chick.Poo();

// Without the interface.
Action bunnyJump = () => bunny.Jump();
Action bunnyEat = () => bunny.Eat();
Action bunnyPoo = () => bunny.Poo();
bunnyJump(); bunnyEat(); bunnyPoo();
Action chickJump = () => chick.Jump();
Action chickEat = () => chick.Eat();
...

যদি কোনও শ্রেণীর কেবল পদ্ধতিটির একটি প্রয়োগকরণ প্রয়োজন হয়, তবে ইন্টারফেসটি ব্যবহার করুন-এটি কীভাবে বেনিফিটের ক্ষেত্রে ন্যায়সঙ্গত?

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

উপসংহার

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

প্রতিনিধিদের ব্যবহার করার সময় অতিরিক্ত কারণ হ'ল আপনি যখন কোনও শ্রেণীর কেবলমাত্র অংশটিই প্রকাশ করতে চান যা থেকে উত্স ফাইলটি সামঞ্জস্য করতে পারেন না।

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


12

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

একটি ইন্টারফেস হ'ল একটি ভাষার কাঠামো যা কিছু চুক্তির প্রতিনিধিত্ব করে - "আমি এর মাধ্যমে গ্যারান্টি দিচ্ছি যে আমি নিম্নলিখিত পদ্ধতি এবং বৈশিষ্ট্য উপলব্ধ করব"।

এছাড়াও, আমি সম্পূর্ণরূপে সম্মত নই যে পর্যবেক্ষক / গ্রাহক প্যাটার্নের সমাধান হিসাবে প্রতিনিধিরা প্রাথমিকভাবে কার্যকর। এটি "জাভা ভার্বোসিটি সমস্যা" এর মার্জিত সমাধান।

আপনার প্রশ্নের জন্য:

1 এবং 2)

আপনি যদি জাভাতে কোনও ইভেন্ট সিস্টেম তৈরি করতে চান তবে আপনি সাধারণত ইভেন্টটি প্রচারের জন্য একটি ইন্টারফেস ব্যবহার করেন, এরকম কিছু:

interface KeyboardListener
{
    void KeyDown(int key);
    void KeyUp(int key)
    void KeyPress(int key);
    .... and so on
}

এর অর্থ হল আপনার শ্রেণিকে স্পষ্টভাবে এই সমস্ত পদ্ধতি প্রয়োগ করতে হবে এবং আপনি কেবল প্রয়োগ করতে চাইলে এমনকি সেগুলির জন্য স্টাব সরবরাহ করতে হবে KeyPress(int key)

সি # তে, এই ইভেন্টগুলিকে প্রতিনিধিদের তালিকা হিসাবে উপস্থাপন করা হবে, সি # তে "ইভেন্ট" কীওয়ার্ড দ্বারা গোপন করা, প্রতিটি একক ইভেন্টের জন্য একটি করে। এর অর্থ আপনি আপনার ক্লাসে জনসাধারণের "কী" পদ্ধতিগুলি দিয়ে বোঝা না করে আপনি যা চান তা সহজেই সাবস্ক্রাইব করতে পারবেন etc.

3-5 পয়েন্টের জন্য +1।

উপরন্তু:

প্রতিনিধিরা খুব দরকারী যখন আপনি উদাহরণস্বরূপ একটি "মানচিত্র" ফাংশন সরবরাহ করতে চান যা একটি তালিকা নেয় এবং প্রতিটি উপাদানকে একটি নতুন তালিকায় প্রজেক্ট করে, একই পরিমাণে উপাদানগুলির সাথে, তবে কোনও উপায়ে আলাদা। মূলত, IEnumerable.Select (...)।

আইনিউমারেবল.সিলেক্টটি একটি গ্রহণ করে Func<TSource, TDest>, যা একটি প্রতিনিধি যা একটি ফাংশন মোড়ানো একটি টিসোর্স উপাদান নেয় এবং সেই উপাদানটিকে একটি টেডেস্ট উপাদান হিসাবে রূপান্তর করে।

জাভাতে এটি একটি ইন্টারফেস ব্যবহার করে প্রয়োগ করতে হবে। এই জাতীয় ইন্টারফেস বাস্তবায়নের জন্য প্রায়শই কোনও প্রাকৃতিক জায়গা নেই। যদি কোনও শ্রেণীর কোনও তালিকা থাকে যা এটি কোনও উপায়ে রূপান্তর করতে চায়, তবে এটি খুব স্বাভাবিক নয় যে এটি "লিস্টট্রান্সফর্মার" ইন্টারফেসটি প্রয়োগ করে, বিশেষত যেহেতু দুটি ভিন্ন তালিকা থাকতে পারে যা বিভিন্ন উপায়ে রূপান্তর করা উচিত should

অবশ্যই, আপনি বেনামে ক্লাস ব্যবহার করতে পারেন যা একই ধরণের ধারণা (জাভাতে)।


তাঁর প্রশ্নের উত্তর দেওয়ার জন্য আপনার পোস্টটি সম্পাদনা করার কথা বিবেচনা করুন
ইয়াম মার্কোভিচ

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

স্বাভাবিকভাবে. আমার সাথেও ঘটে এবং এর মূল্য প্রতি সেও আছে। এ কারণেই আমি কেবল এটির পরামর্শ দিয়েছি , তবে এ সম্পর্কে কোনও অভিযোগ করি নি। :)
ইয়াম মার্কোভিচ

3

1) ইভেন্ট নিদর্শন, ভাল ক্লাসিক হ'ল পর্যবেক্ষক প্যাটার্ন, এখানে একটি ভাল মাইক্রোসফ্ট লিঙ্ক মাইক্রোসফ্ট টক পর্যবেক্ষক

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

উপরের লিঙ্কটি প্রতিনিধিদের সম্পর্কে আলোচনা করে এবং কেন রচনার জন্য ভাল রয়েছে, যাতে আপনার প্রশ্নের সাথে সহায়তা করতে পারে।


3

সবার আগে, ভাল প্রশ্ন। অন্ধভাবে "সেরা অনুশীলনগুলি" গ্রহণ না করে ইউটিলিটিতে আপনার ফোকাসের প্রশংসা করি। +1 এর জন্য

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

আমি আপনার প্রশ্নের উত্তর দিতে পয়েন্টে পৌঁছে যাব।

প্রথমত, আমি ধরে নিয়েছি আপনি ইতিমধ্যে জানেন যে একটি ইন্টারফেস কী। কোনও প্রতিনিধি হিসাবে, এটি যথেষ্ট বলা যায় যে এটি কোনও পদ্ধতির টাইপড পয়েন্টারযুক্ত একটি কাঠামো, thisসেই পদ্ধতির পক্ষে যুক্তি উপস্থাপনকারী অবজেক্টের একটি বিকল্প পয়েন্টার সহ । স্থির পদ্ধতির ক্ষেত্রে, পরবর্তী পয়েন্টারটি শূন্য।
মাল্টিকাস্ট ডেলিগেটসও রয়েছে, যা ঠিক প্রতিনিধিদের মতোই, তবে তাদের মধ্যে এই কাঠামোগুলির বেশ কয়েকটি নির্ধারিত থাকতে পারে (অর্থাত্ মাল্টিকাস্ট ডেলিগেটের কাছে দাওয়াতকে ডাকা একক কল তার নির্ধারিত অনুরোধ তালিকার সমস্ত পদ্ধতি আহ্বান করে)।

ইভেন্ট ইভেন্ট ডিজাইনের ধরণ বলতে কী বোঝায়?

সেগুলির অর্থ সি # তে ইভেন্টগুলি ব্যবহার করা (যা অত্যন্ত চূড়ান্তভাবে এই দরকারী উপায়ে কার্যকর করার জন্য বিশেষ কীওয়ার্ড রয়েছে)। সি # তে ইভেন্টগুলি বহুজাতিক ক্রেতাদের দ্বারা চালিত করা হয়।

আপনি যখন কোনও ইভেন্টের সংজ্ঞা দেন, যেমন এই উদাহরণে:

class MyClass {
  // Note: EventHandler is just a multicast delegate,
  // that returns void and accepts (object sender, EventArgs e)!
  public event EventHandler MyEvent;

  public void DoSomethingThatTriggersMyEvent() {
    // ... some code
    var handler = MyEvent;
    if (handler != null)
      handler(this, EventArgs.Empty);
    // ... some other code
  }
}

সংকলক আসলে এটি নিম্নলিখিত কোডে রূপান্তর করে:

class MyClass {
  private EventHandler MyEvent = null;

  public void add_MyEvent(EventHandler value) {
    MyEvent += value;
  }

  public void remove_MyEvent(EventHandler value) {
    MyEvent -= value;
  }

  public void DoSomethingThatTriggersMyEvent() {
    // ... some code
    var handler = MyEvent;
    if (handler != null)
      handler(this, EventArgs.Empty);
    // ... some other code
  }
}

আপনি তারপরে একটি ইভেন্টের সদস্যতা নিন

MyClass instance = new MyClass();
instance.MyEvent += SomeMethodInMyClass;

যা সংকলিত হয়

MyClass instance = new MyClass();
instance.add_MyEvent(new EventHandler(SomeMethodInMyClass));

সুতরাং এটি ইভেন্টে সি # (বা সাধারণভাবে নেট)

যদি কোনও প্রতিনিধি ব্যবহার করা হয় তবে রচনাটি কীভাবে সহজ হতে পারে?

এটি সহজেই প্রদর্শিত হতে পারে:

মনে করুন আপনার কাছে এমন একটি শ্রেণি রয়েছে যা এটিতে পাস করা ক্রয়ের একটি সেটের উপর নির্ভর করে। আপনি একটি ইন্টারফেসে এই ক্রিয়াগুলি encapsulate করতে পারে:

interface RequiredMethods {
  void DoX();
  int DoY();
};

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

sealed class RequiredMethods {
  public Action DoX;
  public Func<int> DoY();
}

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

জিনিসগুলি করার এই পদ্ধতিটি সঠিক পরিস্থিতিতে অত্যন্ত উপকারী। এটি সম্পর্কে চিন্তাভাবনা করুন - আপনি যখন সত্যিই যত্নবান হন সমস্ত কিছু আপনার কাছে চলে আসে তখন কেন একটি ইন্টারফেসের উপর নির্ভর করুন?

ইন্টারফেস ব্যবহারের সুবিধাগুলি যখন সম্পর্কিত পদ্ধতির একটি গ্রুপ থাকে

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

ইন্টারফেস ব্যবহারের সুবিধা যদি কোনও শ্রেণীর শুধুমাত্র একটি বাস্তবায়ন প্রয়োজন implementation

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

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

শব্দটি এখানে মাল্টিকাস্ট প্রতিনিধিদেরও উল্লেখ করতে পারে। ইন্টারফেস দ্বারা ঘোষিত পদ্ধতিগুলি শুধুমাত্র একবার প্রয়োগকারী শ্রেণিতে প্রয়োগ করা যেতে পারে। তবে প্রতিনিধিরা একাধিক পদ্ধতি জড়ো করতে পারে, যা ক্রমানুসারে বলা হবে।

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

আমি আশা করি আপনার প্রশ্নের আপনার সন্তুষ্টির জবাব দেওয়া হয়েছে। এবং আবার, প্রশ্নের জন্য কুডোস।


2

আমার .NET এর স্মৃতি যদি এখনও ধরে রাখে তবে একটি প্রতিনিধি মূলত একটি ফাংশন পিটিআর বা ফান্টেক্টর। এটি একটি ফাংশন কলে ইন্ডিয়ারেশনের একটি স্তর যুক্ত করে যাতে কলিং কোডটি পরিবর্তন না করে ফাংশনগুলি প্রতিস্থাপন করা যায়। এটি একটি ইন্টারফেস একই কাজ করে, ব্যতীত কোনও ইন্টারফেস একাধিক ফাংশন একসাথে প্যাকেজ করে এবং কোনও প্রয়োগকারীকে সেগুলি একসাথে প্রয়োগ করতে হয়।

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

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

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

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


1

"ইভেন্টিং" ডিজাইন প্যাটার্ন (আরও ভাল পর্যবেক্ষক প্যাটার্ন হিসাবে পরিচিত) আপনাকে একই স্বাক্ষরের একাধিক পদ্ধতি প্রতিনিধিদের সাথে সংযুক্ত করতে দেয়। আপনি একটি ইন্টারফেস দিয়ে সত্যিই এটি করতে পারবেন না।

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


1

আমি যে সবচেয়ে বড় স্পষ্টতা দিতে পারি তা:

  1. একটি প্রতিনিধি একটি ফাংশন স্বাক্ষর সংজ্ঞায়িত করে - কোন প্যারামিটারগুলির সাথে কোনও মিলবে ফাংশন গ্রহণ করবে এবং কী ফিরে আসবে।
  2. একটি ইন্টারফেস ফাংশন, ইভেন্ট, বৈশিষ্ট্য এবং ক্ষেত্রগুলির পুরো সেট নিয়ে কাজ করে।

তাই:

  1. যখন আপনি একই স্বাক্ষর সহ কিছু ফাংশন সাধারণ করতে চান - একটি প্রতিনিধি ব্যবহার করুন।
  2. আপনি যখন কোনও শ্রেণীর কিছু আচরণ বা গুণমানকে সাধারণ করতে চান - একটি ইন্টারফেস ব্যবহার করুন।

1

ইভেন্টগুলির বিষয়ে আপনার প্রশ্নটি ইতিমধ্যে দুর্দান্তভাবে কভার করা হয়েছে। এবং এটি সত্য, এটি একটি ইন্টারফেসও পারে একাধিক পদ্ধতি সংজ্ঞায়িত পারে (তবে আসলে প্রয়োজন নেই), যখন একটি ফাংশন টাইপ কেবল কোনও পৃথক ফাংশনে বাধা দেয়।

তবে আসল পার্থক্যটি হ'ল:

  • কাঠামোগত সাব টাইপিংয়ের মাধ্যমে ফাংশন মানগুলি ফাংশনের ধরণের সাথে মিলিত হয় (অর্থাত সামঞ্জস্য) । এর অর্থ, যদি কোনও ফাংশনের মানটির সাথে ফাংশনের ধরণের সাথে সামঞ্জস্যপূর্ণ স্বাক্ষর থাকে তবে এটি ধরণের জন্য একটি বৈধ মান।
  • উদাহরণগুলি নামমাত্র সাব টাইপিং (অর্থাত্ একটি নামের স্পষ্ট ব্যবহার) দ্বারা ইন্টারফেসের সাথে মিলে যায় । এর অর্থ, যদি কোনও উদাহরণ কোনও শ্রেণীর সদস্য হয়, যা প্রদত্ত ইন্টারফেসটি স্পষ্টভাবে প্রয়োগ করে, উদাহরণটি ইন্টারফেসের জন্য একটি বৈধ মান। যাইহোক, যদি বস্তুটির কেবল ইন্টারফেসগুলির দ্বারা সমস্ত সদস্য দাবি করা থাকে এবং সমস্ত সদস্যের সাথে সামঞ্জস্যপূর্ণ স্বাক্ষর রয়েছে তবে স্পষ্টভাবে ইন্টারফেসটি প্রয়োগ করে না, এটি ইন্টারফেসের জন্য বৈধ মান নয়।

অবশ্যই, তবে এর অর্থ কী?

আসুন এই উদাহরণটি ধরুন (কোডটি হ্যাক্সে রয়েছে যেহেতু আমার সি # খুব ভাল নয়):

class Collection<T> {
    /* a lot of code we don't care about now */
    public function filter(predicate:T->Bool):Collection<T> { 
         //build a new collection with all elements e, such that predicate(e) == true
    }
    public function remove(e:T):Bool {
         //removes an element from this collection, if contained and returns true, false otherwise
    }
}

এখন ফিল্টার-পদ্ধতিটি সহজেই যুক্তিগুলির একটি ছোট্ট টুকরোটিতে সুবিধাজনকভাবে পাস করা সহজ করে তোলে, এটি সংগ্রহের অভ্যন্তরীণ সংগঠন সম্পর্কে অসচেতন, যখন সংগ্রহটি এটি দেওয়া যুক্তির উপর নির্ভর করে না। গ্রেট। এক সমস্যা ছাড়া:
সংগ্রহ করেন যুক্তিবিজ্ঞান উপর নির্ভর করে। সংগ্রহটি সহজাতভাবে ধারণাটি তৈরি করে, যে কার্যটি পাস হয়েছিল তা একটি শর্তের বিপরীতে একটি মান পরীক্ষা করতে এবং পরীক্ষার সাফল্য ফিরিয়ে আনার জন্য ডিজাইন করা হয়েছে। মনে রাখবেন যে সমস্ত ক্রিয়াকলাপ, যেগুলি আর্গুমেন্ট হিসাবে একটি মান নেয় এবং বুলিয়ান ফেরত দেয় তা কেবলমাত্র পূর্বাভাস। উদাহরণস্বরূপ আমাদের সংগ্রহের অপসারণ পদ্ধতিটি একটি ফাংশন।
ধরা যাক আমরা বলেছিc.filter(c.remove) । ফলাফলের সব উপাদানের সঙ্গে একটি সংগ্রহ হবে cযখনcনিজেই খালি হয়ে যায়। এটি দুর্ভাগ্যজনক, কারণ স্বাভাবিকভাবেই আমরা cনিজেরাই অজানা হওয়ার আশা করতাম ।

উদাহরণ খুব নির্মিত হয়। তবে মূল সমস্যাটি হ'ল, c.filterযুক্তি হিসাবে কিছু ফাংশন মান সহ কোডিং কোডের সেই তর্কটি উপযুক্ত কিনা তা জানার কোনও উপায় নেই (অর্থাৎ শেষ পর্যন্ত আক্রমণকারীটিকে সংরক্ষণ করবে)। যে কোডটি ফাংশনটির মান তৈরি করেছে সেগুলি হয়ত বা নাও জানতে পারে, এটি একটি প্রাকটিক হিসাবে ব্যাখ্যা করা হবে।

এখন জিনিসগুলি পরিবর্তন করা যাক:

interface Predicate<T> {
    function test(value:T):Bool;
}
class Collection<T> {
    /* a lot of code we don't care about now */
    public function filter(predicate:Predicate<T>):Collection<T> { 
         //build a new collection with all elements e, such that predicate.test(e) == true
    }
    public function remove(e:T):Bool {
         //removes an element from this collection, if contained and returns true, false otherwise
    }
}

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

তাই উপরে উপরে যা বলা হয়েছিল তা কেবল কয়েকটি শব্দে পুনরায় ব্যাখ্যা করতে:

  • ইন্টারফেসের অর্থ নামমাত্র টাইপিং এবং এর মাধ্যমে সুস্পষ্ট সম্পর্ক ব্যবহার করা
  • প্রতিনিধিদের অর্থ কাঠামোগত টাইপিং এবং এর মাধ্যমে অন্তর্নিহিত সম্পর্ক ব্যবহার করা

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


1
এটি উল্লেখযোগ্য যে "স্পষ্টতভাবে ইন্টারফেসটি প্রয়োগ করে" ("নামমাত্র সাব টাইপিং" এর অধীনে) ইন্টারফেস সদস্যদের সুস্পষ্ট বা অন্তর্নিহিত প্রয়োগের মতো নয়। সি # তে, ক্লাসগুলি অবশ্যই বলবে যে তারা প্রয়োগ করা ইন্টারফেসগুলি সর্বদা স্পষ্টভাবে ঘোষণা করতে হবে। তবে ইন্টারফেস সদস্যগণ স্পষ্টত (যেমন, int IList.Count { get { ... } }) বা স্পষ্টতই ( ) প্রয়োগ করা যেতে পারে public int Count { get { ... } }। এই পার্থক্য এই আলোচনার সাথে প্রাসঙ্গিক নয়, তবে এটি বিভ্রান্তিকর পাঠকদের এড়ানোর জন্য এটি উল্লেখের দাবিদার।
ফুগ

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

1
  1. ইভেন্টিং ডিজাইনের ধরণটি এমন একটি কাঠামো বোঝায় যা একটি প্রকাশ এবং সাবস্ক্রাইব প্রক্রিয়া জড়িত। ইভেন্টগুলি একটি উত্স দ্বারা প্রকাশিত হয়, প্রতিটি গ্রাহক প্রকাশিত আইটেমটির নিজস্ব অনুলিপি পান এবং এটি নিজের ক্রিয়াকলাপের জন্য দায়ী। এটি একটি স্বচ্ছলভাবে মিলিত প্রক্রিয়া কারণ প্রকাশককে এমনকি সেখানে গ্রাহকরা কী তা জানতে হবে না। গ্রাহক হওয়া একা বাধ্যতামূলক নয় (এটি কোনওটিই হতে পারে না)
  2. ইন্টারফেসের সাথে তুলনা করে যদি কোনও প্রতিনিধি ব্যবহার করা হয় তবে রচনাটি "সহজ"। ইন্টারফেসগুলি একটি শ্রেণীর উদাহরণটিকে "ধরণের হ্যান্ডলার" অবজেক্ট হিসাবে সংজ্ঞায়িত করে যেখানে একটি কম্পোজিশনের কনস্ট্রাক্ট উদাহরণ হিসাবে "হ্যান্ডলার থাকে" বলে মনে হয় সুতরাং প্রতিনিধি ব্যবহার করে উদাহরণটির উপস্থিতি কম সীমাবদ্ধ হয় এবং আরও নমনীয় হয়।
  3. নীচের মন্তব্য থেকে আমি খুঁজে পেয়েছি যে আমার নিজের পোস্টটি উন্নত করা দরকার ছিল, রেফারেন্সের জন্য এটি দেখুন: http://bytes.com/topic/c-sharp/answers/252309-interface-vs-delegate

1
৩. প্রতিনিধিদের কেন আরও বেশি castালাই প্রয়োজন, এবং কেন কঠোর সংযোগকারীদের একটি সুবিধা? ৪. আপনার প্রতিনিধিদের ব্যবহার করার জন্য ইভেন্টগুলি ব্যবহার করতে হবে না, এবং প্রতিনিধিদের সাথে এটি কোনও পদ্ধতি ধরে রাখার মতো - আপনি জানেন যে এটির রিটার্ন টাইপ এবং এটির যুক্তিগুলির ধরণ। এছাড়াও, কেন একটি ইন্টারফেসে ঘোষিত একটি পদ্ধতি প্রতিনিধিদের সাথে সংযুক্ত পদ্ধতির চেয়ে ত্রুটিগুলি পরিচালনা করা সহজ করবে?
ইয়াম মার্কোভিচ

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

যে কারণে আমি মনে করি যে কোনও ইন্টারফেসে সংজ্ঞায়িত একটি পদ্ধতি ত্রুটিগুলি পরিচালনা করা সহজ করে তুলবে তা সংকলকটি সেই পদ্ধতি থেকে ফেলে দেওয়া ব্যতিক্রম প্রকারগুলি পরীক্ষা করতে সক্ষম হয়। আমি জানি এটি দৃinc়প্রত্যয়ী প্রমাণ নয় তবে সম্ভবত পছন্দ হিসাবে বর্ণনা করা উচিত?
কার্লো কুইপ

1
প্রথমত আমরা প্রতিনিধি বনাম ইন্টারফেসের বিষয়ে কথা বলছিলাম, ইভেন্ট বনাম ইন্টারফেস নয়। দ্বিতীয়ত, ইভেন্টহ্যান্ডলার প্রতিনিধিকে ইভেন্টের ভিত্তি তৈরি করা কেবল একটি সম্মেলন এবং কোনওভাবেই বাধ্যতামূলক নয়। কিন্তু আবার, এখানে ঘটনা সম্পর্কে কথা বলতে বিন্দু মিস করে। আপনার দ্বিতীয় মন্তব্য হিসাবে - ব্যতিক্রমগুলি সি # তে চেক করা হয় না। আপনি জাভা নিয়ে বিভ্রান্ত হয়ে পড়ছেন (যা ঘটনাক্রমে প্রতিনিধিও নেই)।
ইয়াম মার্কোভিচ

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