সি # তে সদস্যদের আড়াল করার জন্য সুস্পষ্ট ইন্টারফেস বাস্তবায়ন কি জায়েজ?


14

আমি কীভাবে সি # তে ইন্টারফেস এবং সুস্পষ্ট ইন্টারফেস বাস্তবায়নের সাথে কীভাবে কাজ করব তা আমি বুঝতে পেরেছিলাম, তবে আমি ভাবছিলাম যে নির্দিষ্ট সদস্যদের প্রায়শই ব্যবহার করা হবে না যা ঘন ঘন ব্যবহার করা হবে না এটি লুকানো রূপ হিসাবে বিবেচিত হয় considered উদাহরণ স্বরূপ:

public interface IMyInterface
{
    int SomeValue { get; set; }
    int AnotherValue { get; set; }
    bool SomeFlag { get; set; }

    event EventHandler SomeValueChanged;
    event EventHandler AnotherValueChanged;
    event EventHandler SomeFlagChanged;
}

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


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

1
আমি একজন লোকের সাথে কাজ করেছি যিনি নিয়মিত এই কাজটি করেছিলেন। এটি আমাকে একেবারে বাদাম চালিয়েছে।
জোয়েল ইথারটন

... এবং সমষ্টি ব্যবহার শুরু করুন।
মিকালাই

উত্তর:


39

হ্যাঁ, এটি সাধারণত খারাপ ফর্ম।

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

যদি আপনার ইন্টেলিজেন্স খুব বেশি বিশৃঙ্খল থাকে তবে আপনার ক্লাসটি খুব বড়। আপনার শ্রেণিটি যদি খুব বড় হয় তবে এটি সম্ভবত অনেকগুলি কাজ করছে এবং / অথবা খারাপভাবে ডিজাইন করেছে।

আপনার সমস্যাটি ঠিক করুন, আপনার লক্ষণ নয়।


অব্যক্ত সদস্যদের সম্পর্কে সংকলক সতর্কতাগুলি সরাতে এটি ব্যবহার করা কি উপযুক্ত?
Gusdor

11
"আপনার সমস্যাটি ঠিক করুন, আপনার লক্ষণ নয়" " +1
ফ্রিএএসআইনবিয়ার

11

বৈশিষ্ট্যটি যার উদ্দেশ্যে হয়েছিল তা ব্যবহার করুন। নেমস্পেসের বিশৃঙ্খলা হ্রাস করা এর মধ্যে একটি নয়।

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

কিছু লেখক / বিশেষজ্ঞরা এটিকে কোনও বৈশিষ্ট্যের কুঁচকে বিবেচনা করে (পদ্ধতিগুলি প্রকৃতপক্ষে ধরণের বস্তুর মডেলের অংশ নয়)। তবে সমস্ত বৈশিষ্ট্যগুলির মতো, কোথাও কারও এটির প্রয়োজন রয়েছে।

আবার, আমি এটি লুকানোর বা সংস্থার জন্য ব্যবহার করব না । ইন্টেলিজেন্স থেকে সদস্যদের আড়াল করার উপায় রয়েছে।

[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]

"এমন বিশিষ্ট লেখক / বিশেষজ্ঞ রয়েছেন যা এটিকে কোনও বৈশিষ্ট্যের কুঁচকে বিবেচনা করে।" কে? প্রস্তাবিত বিকল্প কি? কমপক্ষে একটি সমস্যা রয়েছে (যেমন একটি উপ-পৃষ্ঠ / প্রয়োগকারী শ্রেণীর ইন্টারফেস পদ্ধতির বিশেষীকরণ) যার সুস্পষ্ট বাস্তবায়নের অভাবে সমাধান করার জন্য সি # তে আরও কিছু বৈশিষ্ট্য যুক্ত করা প্রয়োজন (ADO.NET এবং জেনেরিক সংগ্রহ দেখুন) ।
ঝোমিনাল

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

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

@ ঝোমিনাল - অবশ্যই, আমি যখন কয়েক মিনিট পরে আপডেট করব। ধন্যবাদ।
কোডেনহেম

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

5

আমি অগোছালো কোডের লক্ষণ হতে পারি তবে কখনও কখনও আসল জগাখিচুড়ি হয়। .NET ফ্রেমওয়ার্কের একটি উদাহরণ হ'ল ReadOnlyColection যা পরিবর্তক সেটারটিকে []], অ্যাড এবং সেটটি লুকিয়ে রাখে।

আইই রিডঅনলি ক্লেশন IList <টি> প্রয়োগ করে। আরও দেখুন আমার প্রশ্নের আগে যখন আমি এই চিন্তা তাই বেশ কয়েক বছর হয়।


আচ্ছা এটি আমার নিজস্ব ইন্টারফেস আমিও ব্যবহার করব, তাই এটি শুরু থেকে ভুল করার কোনও বুদ্ধি নেই।
কাইল বারান 21

2
আমি বলব না যে এটি রূপান্তরকারী সেটারটি লুকিয়ে রাখে বরং এটি যে এটি প্রদান করে না তা মোটেই দেয় না। এর চেয়ে ভাল উদাহরণ হ'ল ConcurrentDictionary, যা IDictionary<T>স্পষ্টভাবে বিভিন্ন সদস্যকে কার্যকর করে যাতে ConcurrentDictionaryক) গ্রাহকরা তাদের সরাসরি ডাকে না এবং বি) এমন পদ্ধতি ব্যবহার করতে পারে যাগুলির প্রয়োজনের জন্য IDictionary<T>যদি বাস্তবায়ন প্রয়োজন require যেমন, ব্যবহারকারীদের ConcurrentDictionary<T> উচিত কল TryAddবদলে Addঅপ্রয়োজনীয় ব্যতিক্রম প্রয়োজন এড়ানো।
ব্রায়ান

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

ভোক্তার দৃষ্টিকোণ থেকে পদ্ধতিগুলি গোপন রয়েছে।
এসবেন স্কোভ পেডারসেন

1
আপনি আইআরডোনলি সংগ্রহ <T> সম্পর্কে লিখুন তবে কেবলমাত্র পঠন-কল্পনা <T> লিঙ্ক করুন। একটি ইন্টারফেসে প্রথম, দ্বিতীয়টি একটি শ্রেণি। IReadonly Colલેક્ <<> IList <T> বাস্তবায়িত করে না যদিও পঠনকলন <T> করে।
জর্জেন ফোগ

2

সদস্য প্রসঙ্গে নিরর্থক হলে এটি করা ভাল ফর্ম। উদাহরণস্বরূপ, আপনি যদি এমন একটি পঠন সংগ্রহ সংগ্রহ তৈরি করেন যা IList<T>অভ্যন্তরীণ কোনও বিষয়কে অর্পণ করে কার্যকর করে _wrappedতবে আপনার মতো কিছু থাকতে পারে:

public T this[int index]
{
  get
  {
     return _wrapped[index];
  }
}
T IList<T>.this[int index]
{
  get
  {
    return this[index];
  }
  set
  {
    throw new NotSupportedException("Collection is read-only.");
  }
}
public int Count
{
  get { return _wrapped.Count; }
}
bool ICollection<T>.IsReadOnly
{
  get
  {
    return true;
  }
}

এখানে আমরা চারটি পৃথক কেস পেয়েছি।

public T this[int index]ইন্টারফেসের চেয়ে আমাদের ক্লাস দ্বারা সংজ্ঞায়িত করা হয়েছে, এবং এটি অবশ্যই স্পষ্ট বাস্তবায়ন নয়, তবে নোট করুন যে এটি T this[int index]ইন্টারফেসে সংজ্ঞায়িত পঠন-পাঠ্যের সাথে একই রকম হয় তবে কেবল পঠনযোগ্য।

T IList<T>.this[int index]সুস্পষ্ট কারণ এর এক অংশ (প্রাপ্তকারী) উপরের সম্পত্তির সাথে পুরোপুরি মিলেছে এবং অন্য অংশটি সর্বদা একটি ব্যতিক্রম ছুঁড়ে ফেলবে। ইন্টারফেসের মাধ্যমে এই শ্রেণীর উদাহরণটি অ্যাক্সেস করার জন্য কারও পক্ষে অত্যাবশ্যক, তবে ক্লাসের ধরণের পরিবর্তকের মাধ্যমে এটি ব্যবহার করা অর্থহীন।

একইভাবে কারণ bool ICollection<T>.IsReadOnlyসর্বদা সত্য ফিরে আসতে চলেছে এটি শ্রেণীর ধরণের বিরুদ্ধে লেখা কোডের পক্ষে সম্পূর্ণ অর্থহীন, তবে এটি ইন্টারফেসের ধরণের মাধ্যমে এটি ব্যবহার করা অত্যাবশ্যক হতে পারে, এবং তাই আমরা এটিকে স্পষ্টভাবে বাস্তবায়ন করি।

বিপরীতভাবে, public int Countস্পষ্টভাবে প্রয়োগ করা হয় না কারণ এটি সম্ভবত নিজস্ব ধরণের মাধ্যমে উদাহরণ ব্যবহার করে কারও পক্ষে ব্যবহারযোগ্য হতে পারে।

তবে আপনার "খুব বিরল ব্যবহৃত" ক্ষেত্রে, আমি স্পষ্টত বাস্তবায়ন না করার দিকে অবশ্যই দৃ indeed়তার সাথে ঝুঁকতে চাই।

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


আপনি যদি কোনও ইন্টারফেস বাস্তবায়ন করেন তবে ইন্টারফেসটি বাস্তবায়ন করুন। অন্যথায়, এটি লিসকভ সাবস্টিটিউশন নীতিমালার সুস্পষ্ট লঙ্ঘন।
টেলাস্টিন

@ টেলাস্টিন ইন্টারফেস সত্যই কার্যকর করা হয়েছে।
জন হানা

তবে এর চুক্তি সন্তুষ্ট নয় - বিশেষত, "এটি এমন কিছু যা একটি পরিবর্তনীয়, এলোমেলো অ্যাক্সেস সংগ্রহের প্রতিনিধিত্ব করে"।
টেলাস্টিন

1
@ টেলাস্টিন এটি ডকুমেন্টেড চুক্তিটি পূরণ করে, বিশেষত "একটি সংগ্রহ যা কেবলমাত্র পঠনযোগ্য সংগ্রহ সংগ্রহের তৈরি হওয়ার পরে উপাদানগুলির সংযোজন, অপসারণ বা পরিবর্তনের অনুমতি দেয় না।" দেখুন msdn.microsoft.com/en-us/library/0cfatk9t%28v=vs.110%29.aspx
জন হানা

@ টেলাস্টিন: যদি চুক্তিতে পরিবর্তনের বিষয়টি অন্তর্ভুক্ত থাকে তবে কেন ইন্টারফেসটিতে কোনও IsReadOnlyসম্পত্তি থাকবে?
নিকি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.