c# - কেন তালিকা থেকে উত্তরাধিকার<টি>?




.net list (18)

আমার প্রোগ্রামগুলি পরিকল্পনা করার সময়, আমি প্রায়শই চিন্তার চেইন দিয়ে শুরু করি:

একটি ফুটবল দল শুধুমাত্র ফুটবল খেলোয়াড়দের একটি তালিকা। অতএব, আমি এটা দিয়ে প্রতিনিধিত্ব করা উচিত:

var football_team = new List<FootballPlayer>();

এই তালিকার অর্ডারগুলি ক্রম অনুসারে প্লেয়ারগুলিতে তালিকাভুক্ত হওয়া ক্রমের প্রতিনিধিত্ব করে।

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

তাই আমি মনে করি:

ঠিক আছে, একটি ফুটবল দল শুধুমাত্র খেলোয়াড়দের একটি তালিকা হিসাবে, তবে অতিরিক্ত, এটি একটি নাম (একটি string ) এবং স্কোরগুলির চলমান মোট (একটি int ) থাকে। .NET ফুটবল দল সংরক্ষণের জন্য একটি ক্লাস সরবরাহ করে না, তাই আমি নিজের ক্লাস তৈরি করব। সবচেয়ে অনুরূপ এবং প্রাসঙ্গিক বিদ্যমান গঠন List<FootballPlayer> , তাই আমি এটি থেকে উত্তরাধিকারী হবে:

class FootballTeam : List<FootballPlayer> 
{ 
    public string TeamName; 
    public int RunningTotal 
}

কিন্তু এটি নির্দেশ করে যে একটি নির্দেশিকা আপনাকে List<T> থেকে উত্তরাধিকারী হতে হবে না । আমি পুঙ্খানুপুঙ্খভাবে এই নির্দেশিকা দ্বারা বিভ্রান্ত করছি দুটি ক্ষেত্রে।

কেন না?

দৃশ্যত List কর্মক্ষমতা জন্য অনুকূলভাবে অপ্টিমাইজ করা হয় । তা কেমন করে? আমি List প্রসারিত হলে কি কর্মক্ষমতা সমস্যা হবে? ঠিক কি ভাঙ্গবে?

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

কেন এটা এমনকি কোন ব্যাপার না? একটি তালিকা একটি তালিকা। সম্ভবত কি পরিবর্তন হতে পারে? আমি কি সম্ভবত পরিবর্তন করতে চান?

এবং শেষ পর্যন্ত, যদি মাইক্রোসফ্ট আমাকে List থেকে উত্তরাধিকারী না করতে চায়, তাহলে তারা কেন ক্লাস sealed ?

আমি আর কি ব্যবহার করতে অনুমিত হয়?

দৃশ্যত, কাস্টম সংগ্রহের জন্য, মাইক্রোসফ্ট একটি Collection শ্রেণী সরবরাহ করেছে যা List পরিবর্তে বর্ধিত করা উচিত। কিন্তু এই ক্লাসটি খুব বেয়ার এবং উদাহরণস্বরূপ AddRange হিসাবে অনেক দরকারী জিনিস নেই। jvitor83 এর উত্তরটি সেই বিশেষ পদ্ধতির জন্য একটি কর্মক্ষমতা রেশনেল সরবরাহ করে, তবে কোনও AddRange চেয়ে ধীর AddRange কীভাবে ভাল নয়?

Collection থেকে উত্তরণ List থেকে উত্তরাধিকার চেয়ে উপায় বেশি কাজ, এবং আমি কোন সুবিধা দেখতে। নিশ্চিতভাবেই মাইক্রোসফ্ট আমাকে কোনও কারণে অতিরিক্ত কাজ করতে বলবে না, তাই আমি অনুভব করতে পারছি না যে আমি কিছুটা ভুল বুঝি, এবং উত্তরাধিকার Collection আসলে আমার সমস্যাটির সঠিক সমাধান নয়।

আমি IList বাস্তবায়ন যেমন পরামর্শ দেখেছি। শুধুমাত্র না. এই boilerplate কোড লাইন কয়েক ডজন যা আমাকে কিছুই লাভ।

শেষ পর্যন্ত, কিছু কিছুতে List মোড়ানো প্রস্তাব করে:

class FootballTeam 
{ 
    public List<FootballPlayer> Players; 
}

এই দুটি সমস্যা আছে:

  1. এটা আমার কোড অযথা verbose করে তোলে। আমি এখন my_team.Players.Count হবে পরিবর্তে শুধু my_team.Count কল। সৌভাগ্যক্রমে, সি # দিয়ে সূচীগুলিকে স্বচ্ছ করে তুলতে এবং অভ্যন্তরীণ তালিকাগুলির সমস্ত পদ্ধতিগুলিকে এগিয়ে নিয়ে যেতে সূচীগুলিকে সংজ্ঞায়িত করতে পারি ... তবে এটি অনেক কোড! আমি যে কাজ জন্য কি পেতে পারি?

  2. এটা শুধু প্লেইন কোন ধারনা না। একটি ফুটবল দল খেলোয়াড়দের একটি তালিকা "আছে" না। এটা খেলোয়াড়দের তালিকা। আপনি বলবেন না "জন ম্যাকফুটবলার কিছুটা খেলোয়াড়ের সাথে যোগ দিয়েছেন"। আপনি বলছেন "জন কিছুটাতে যোগ দিয়েছে"। আপনি "স্ট্রিং এর অক্ষর" তে একটি অক্ষর যোগ করেন না, আপনি একটি স্ট্রিংটিতে একটি অক্ষর যুক্ত করেন। আপনি লাইব্রেরীর বইগুলিতে একটি বই যুক্ত করেন না, আপনি লাইব্রেরিতে একটি বই যোগ করেন।

আমি বুঝতে পারি যে "হুডের নিচে" কি "Y এর অভ্যন্তরীণ তালিকায় যোগ করা" বলে মনে করা যেতে পারে, কিন্তু এটি বিশ্ব সম্পর্কে চিন্তাভাবনা করার মত একটি অত্যন্ত পাল্টা-বুদ্ধিমান উপায় বলে মনে হয়।

আমার প্রশ্ন (সারসংক্ষেপ)

কোনও তথ্য কাঠামোর প্রতিনিধিত্ব করার সঠিক C # উপায় যা "যৌক্তিকভাবে" (অর্থাৎ "মানুষের মনকে" বলা হয়) কেবল কয়েক ঘন্টাধ্বনি এবং সিঁড়ির সাথে things একটি list ?

List<T> থেকে উত্তরাধিকারী List<T> সর্বদা অগ্রহণযোগ্য? এটা গ্রহণযোগ্য যখন? কেন কেন না? List<T> থেকে না উত্তরাধিকারী কিনা তা নির্ধারণ করার সময় কোন প্রোগ্রামার বিবেচনা করতে হবে?


শেষ পর্যন্ত, কিছু কিছুতে তালিকা মোড়ানো প্রস্তাব করে:

যে সঠিক উপায়। "অযথাযথভাবে wordy" এই তাকান একটি খারাপ উপায়। যখন আপনি আমার my_team.Players.Count লিখুন তখন এটি একটি সুস্পষ্ট অর্থ my_team.Players.Count । আপনি খেলোয়াড় গণনা করতে চান।

my_team.Count

..আমি কিছুই না। কি গণনা?

একটি দল একটি তালিকা নয় - শুধুমাত্র খেলোয়াড়দের একটি তালিকা ছাড়া গঠিত। একটি দল খেলোয়াড়দের মালিক, সুতরাং খেলোয়াড়দের এটি একটি অংশ হতে হবে (একটি সদস্য)।

আপনি যদি এটি অত্যধিক verbose হচ্ছে সম্পর্কে সত্যিই উদ্বিগ্ন, আপনি সবসময় দলের থেকে বৈশিষ্ট্য প্রকাশ করতে পারেন:

public int PlayerCount {
    get {
        return Players.Count;
    }
}

.. যা হয়ে যায়:

my_team.PlayerCount

এই এখন অর্থ আছে এবং ডিমিটার আইন মেনে চলে।

আপনি কম্পোজিট পুনর্ব্যবহার নীতি অনুসরণ করা বিবেচনা করা উচিত। List<T> থেকে উত্তরাধিকারসূত্রে, আপনি বলছেন একটি দল খেলোয়াড়দের একটি তালিকা এবং এটির প্রয়োজনীয় পদ্ধতি প্রকাশ করছে। এটি ভুল - যেমন আপনি বলেছেন, একটি দল খেলোয়াড়দের তালিকা থেকে বেশি: এটি একটি নাম, পরিচালক, বোর্ড সদস্য, প্রশিক্ষক, চিকিৎসা কর্মী, বেতন ক্যাপ ইত্যাদি। আপনার টিমের ক্লাসে খেলোয়াড়দের একটি তালিকা রয়েছে, আপনি "বলছে একটি দলের খেলোয়াড়দের একটি তালিকা আছে ", কিন্তু এটি অন্যান্য জিনিস থাকতে পারে।


একটি তথ্য কাঠামো প্রতিনিধিত্ব সঠিক C # উপায় কি ...

Remeber, "সব মডেল ভুল, কিন্তু কিছু দরকারী।" - জর্জ ইপি বক্স

কোন "সঠিক উপায়" নেই, শুধুমাত্র একটি দরকারী।

আপনি এবং আপনার ব্যবহারকারীদের জন্য দরকারী যে একটি চয়ন করুন। এটাই. অর্থনৈতিকভাবে বিকাশ, ওভার ইঞ্জিনিয়ার না। আপনি কম কোড লিখুন, কম কোড আপনি ডিবাগ করতে হবে। (নিম্নলিখিত সংস্করণ পড়ুন)।

- সম্পাদিত

আমার ভাল উত্তর হবে ... এটা নির্ভর করে। একটি তালিকা থেকে উত্তোলন এই শ্রেণির ক্লায়েন্টদের এমন পদ্ধতিতে উন্মোচিত করবে যা উন্মুক্ত করা উচিত নয়, প্রাথমিকভাবে কারণ ফুটবলটাইম একটি ব্যবসায়িক সত্তা বলে মনে হচ্ছে।

- সংস্করণ 2

আমি আন্তরিকভাবে মনে করি না যে আমি "ওভার-ইঞ্জিনিয়ার" না মন্তব্যের বিষয়ে উল্লেখ করছিলাম। যদিও আমি বিশ্বাস করি KISS মানসিকতা একটি ভাল নির্দেশিকা, আমি জোর দিয়ে বলতে চাই যে তালিকা থেকে একটি ব্যবসায় শ্রেণির উত্তরাধিকারী এটি সমাধান করার চেয়ে আরও সমস্যার সৃষ্টি করবে, কারণ বিমূর্তীকরণ ফুটো

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

উত্তর সম্পর্কে আরো অবিকল চিন্তা করতে সাহায্য করার জন্য @ কেইয়ের ধন্যবাদ।


ক্লাস উপর ইন্টারফেস পছন্দ

ক্লাস ক্লাস থেকে deriving এড়াতে এবং পরিবর্তে প্রয়োজনীয় অন্তর্বর্তী ইন্টারফেস বাস্তবায়ন করা উচিত।

উত্তরাধিকার বিরতি Encapsulation

ক্লাস বিরতি encapsulation থেকে deriving :

  • আপনার সংগ্রহ কিভাবে বাস্তবায়িত হয় সে সম্পর্কে অভ্যন্তরীণ বিশদ প্রকাশ করে
  • একটি ইন্টারফেস (পাবলিক ফাংশন এবং বৈশিষ্ট্যের সেট) ঘোষণা করে যা উপযুক্ত নাও হতে পারে

অন্যান্য জিনিসগুলির মধ্যে এটি আপনার কোডকে পুনরায় সংশোধন করা কঠিন করে তোলে।

ক্লাস একটি বাস্তবায়ন বিস্তারিত

ক্লাস একটি বাস্তবায়ন বিস্তারিত যা আপনার কোডের অন্যান্য অংশ থেকে লুকানো উচিত। সংক্ষেপে একটি System.Listবিমূর্ত ডাটা টাইপের একটি নির্দিষ্ট বাস্তবায়ন, যা এখন এবং ভবিষ্যতে উপযুক্ত নাও হতে পারে।

ধারণাগতভাবে যে তথ্যটি System.List"তালিকা" বলা হয় তা লাল-হেরিংয়ের একটি বিট। A System.List<T>একটি পরিবর্তনযোগ্য অর্ডার সংগ্রহ যা উপাদানগুলি যুক্ত, সন্নিবেশ, এবং সরানোর জন্য এম্টরাইজড O (1) অপারেশনগুলিকে সমর্থন করে এবং উপাদানগুলির সংখ্যা পুনরুদ্ধার বা সূচী দ্বারা উপাদানটি পাওয়ার এবং সেট করার জন্য O (1) অপারেশনগুলিকে সমর্থন করে।

ক্ষুদ্রতর ইন্টারফেসটি আরও বেশি নমনীয় কোড

একটি তথ্য কাঠামো নকশা করার সময়, সহজ ইন্টারফেস, কোডটি আরও নমনীয়। এই লিংকটি দেখানোর জন্য কীভাবে শক্তিশালী লিংকটি দেখুন।

কিভাবে ইন্টারফেস চয়ন করুন

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

এই প্রক্রিয়াটি পরিচালনা করতে সহায়তা করতে পারে এমন কিছু প্রশ্ন:

  • আমার কি গণনা দরকার? বাস্তবায়ন বিবেচনা না করা হলেIEnumerable<T>
  • এই সংগ্রহটি চালু হওয়ার পরে কি এটি পরিবর্তন হচ্ছে? বিবেচনা না করা হলে IReadonlyList<T>
  • আমি সূচক দ্বারা আইটেম অ্যাক্সেস করতে পারেন যে এটা গুরুত্বপূর্ণ? বিবেচনাICollection<T>
  • আমি ক্রম আইটেম সংগ্রহ যা ক্রম গুরুত্বপূর্ণ? হয়তো এটা একটা ISet<T>?
  • আপনি যদি সত্যিই এই জিনিস চান তাহলে এগিয়ে যান এবং বাস্তবায়ন IList<T>

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

এই পদ্ধতিটি গ্রহণ করে আপনি কোডটি পড়তে, রিফ্যাক্টর এবং পুনঃব্যবহার করা সহজ পাবেন।

Boilerplate এড়ানো সম্পর্কে নোট

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

যে বলে, আপনি যদি অনেক বয়লারপ্লেট লেখেন তবে এটি সম্ভাব্য কারণ আপনি আপনার চেয়ে বেশি ফাংশন প্রকাশ করছেন। এটি একই কারণে আপনি একটি বর্গ থেকে উত্তরাধিকারী উচিত নয়।

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


নকশা> বাস্তবায়ন

আপনি কি পদ্ধতি এবং বৈশিষ্ট্য প্রকাশ করা একটি নকশা সিদ্ধান্ত। আপনি থেকে উত্তরাধিকার বেস বেস একটি বাস্তবায়ন বিস্তারিত। আমি এটা প্রাক্তন ফিরে একটি পদক্ষেপ নিতে মূল্য মনে হয়।

একটি বস্তু তথ্য এবং আচরণ একটি সংগ্রহ।

সুতরাং আপনার প্রথম প্রশ্ন হওয়া উচিত:

  • এই বস্তুটি আমি তৈরি করছি এমন মডেলটিতে কোন তথ্যটি অন্তর্ভুক্ত করে?
  • কি আচরণ এই বস্তু প্রদর্শন করা হয় যে মডেল?
  • কিভাবে ভবিষ্যতে এই পরিবর্তন হতে পারে?

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

আপনি কংক্রিট ধরনের মনে করার আগে ইন্টারফেসে চিন্তা বিবেচনা করুন, কিছু মানুষ তাদের মস্তিষ্ককে "ডিজাইন মোডে" এটিকে আরও সহজ করে তুলতে পারে।

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

ডিজাইন স্পেসিফিকেসন বিবেচনা করুন

MSDN বা ভিজ্যুয়াল স্টুডিওতে তালিকা <টি> এবং IList <T> এ একবার দেখুন। তারা প্রকাশ করা কি পদ্ধতি এবং বৈশিষ্ট্য দেখুন। এই পদ্ধতিগুলি কি কেউ আপনার মতামত ফুটবলটাইমকে করতে চান এমন কিছু দেখতে চান?

ফুটবল টিম। রিভার্স () আপনার কাছে ধারনা করে? FootballTeam.ConvertAll <টুপুট> () আপনি চান এমন কিছু দেখতে চান?

এটি একটি কৌতুক প্রশ্ন নয়; উত্তর প্রকৃতপক্ষে "হ্যাঁ" হতে পারে। আপনি তালিকা <প্লেয়ার> বা IList <প্লেয়ার> প্রয়োগ / উত্তরাধিকারী হন, তবে আপনি তাদের সাথে আটকে আছেন; যদি আপনার মডেলের জন্য এটি আদর্শ, তা করুন।

আপনি যদি হ্যাঁটি নির্ধারণ করেন তবে তা বোঝা যায় এবং আপনি আপনার অবজেক্টগুলি খেলোয়াড়দের (আচরণ) সংগ্রহ / তালিকার তালিকা হিসাবে কার্যকর করতে চান এবং আপনি আইসিওলেকশন বা ইলিস্ট প্রয়োগ করতে চান। ধারণাগত:

class FootballTeam : ... ICollection<Player>
{
    ...
}

আপনি যদি আপনার বস্তুর একটি সংগ্রহ / খেলোয়াড়দের তালিকা (তথ্য) রাখতে চান এবং আপনি তাই সংগ্রহ বা তালিকাটি কোনও সম্পত্তি বা সদস্য হতে চান, তা হলে তা সব উপায়ে করুন। ধারণাগত:

class FootballTeam ...
{
    public ICollection<Player> Players { get { ... } }
}

আপনি হয়তো মনে করতে পারেন যে আপনি কেবলমাত্র তাদের গণনা করার পরিবর্তে খেলোয়াড়দের সেটকে গণনা করতে, তাদের যুক্ত করতে বা অপসারণ করতে সক্ষম হবেন। IEnumerable <প্লেয়ার> বিবেচনা করার জন্য একটি পুরোপুরি বৈধ বিকল্প।

আপনি হয়ত মনে করতে পারেন যে এই ইন্টারফেসগুলির মধ্যে কোনটি আপনার মডেলে উপকারী নয়। এটি কম সম্ভাবনাময় (আয়তনযোগ্য <টি> অনেক ক্ষেত্রে কার্যকর) তবে এটি এখনও সম্ভব।

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

বাস্তবায়ন উপর সরানো

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

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

একটি চিন্তাধারা পরীক্ষা

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

class FootballTeam : ... ICollection<Player>, 
                         ICollection<StaffMember>,
                         ICollection<Score>
{
    ....
}

ডিজাইনটি সত্ত্বেও, C # এ এই স্থানে আপনি তালিকা <টি> থেকে উত্তরাধিকারসূত্রে এই সমস্তগুলি বাস্তবায়ন করতে পারবেন না, কারণ C # "শুধুমাত্র" একক উত্তরাধিকারকে সমর্থন করে। (যদি আপনি C ++ এ এই malarky চেষ্টা করেছেন, তবে আপনি এটি একটি ভাল জিনিস বিবেচনা করতে পারেন।) উত্তরাধিকারের মাধ্যমে একটি সংগ্রহ বাস্তবায়ন করা এবং সংকলনের মাধ্যমে একটিকে মলিন মনে হতে পারে । এবং আইলিস্ট <প্লেয়ার> প্রয়োগ না করা পর্যন্ত গণনা হিসাবে বৈশিষ্ট্যগুলি ব্যবহারকারীদের বিভ্রান্তিকর হয়ে ওঠে .কাউন্ট এবং IList <StaffMember> .খাত ইত্যাদি স্পষ্টভাবে, এবং তারপর তারা বিভ্রান্তিকর পরিবর্তে শুধু বেদনাদায়ক। আপনি এই যাচ্ছে যেখানে দেখতে পারেন; এই উপায়ে চিন্তাভাবনা করার সময় অন্তরঙ্গ অনুভূতি আপনাকে ভালভাবে বলতে পারে যে এই দিকটিতে মাথা খারাপ মনে হচ্ছে (এবং সঠিকভাবে বা ভুলভাবে, আপনার সহকর্মীরাও যদি এটিকে বাস্তবায়ন করেন!)

সংক্ষিপ্ত উত্তর (খুব লম্বা)

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


এখানে কিছু ভাল উত্তর আছে। আমি তাদের নিম্নলিখিত পয়েন্ট যোগ হবে।

কোনও তথ্য কাঠামোর প্রতিনিধিত্ব করার সঠিক C # উপায় যা "যৌক্তিকভাবে" (অর্থাৎ "মানুষের মনকে" বলা হয়) কেবল কয়েক ঘন্টাধ্বনি এবং সিঁড়ির সাথে জিনিসগুলির একটি তালিকা?

ফাঁকা পূরণ করতে ফুটবলের অস্তিত্ব সম্পর্কে পরিচিত দশজন কম্পিউটার ব্যবহারকারী প্রোগ্রামারকে জিজ্ঞাসা করুন:

A football team is a particular kind of _____

কেউ কি বললো "কয়েক ঘণ্টা এবং সিঁড়ি দিয়ে ফুটবল খেলোয়াড়দের তালিকা", নাকি তারা সবাই "স্পোর্টস টিম" বা "ক্লাব" বা "সংস্থা" বলে? আপনার ধারণার যে ফুটবল দলগুলি একটি বিশেষ ধরণের খেলোয়াড়ের তালিকা আপনার মনুষ্যসৃষ্টিতে এবং আপনার মনুষ্য মনের মধ্যে।

List<T> একটি প্রক্রিয়া । ফুটবল দলটি একটি ব্যবসায়িক অবজেক্ট - অর্থাৎ, এমন একটি অবজেক্ট যা প্রোগ্রামের ব্যবসায়িক ডোমেনে কিছু ধারণা উপস্থাপন করে। যারা মিশ্রিত করবেন না! একটি ফুটবল দল এক ধরনের দল; এটি একটি রস্টার আছে, একটি রস্টার খেলোয়াড়দের একটি তালিকা । একটি রস্টার খেলোয়াড়দের একটি নির্দিষ্ট ধরনের তালিকা নয় । একটি রস্টার খেলোয়াড়দের একটি তালিকা। সুতরাং Roster নামক একটি সম্পত্তি তৈরি করুন যা একটি List<Player> । এবং এটি কেবলমাত্র ReadOnlyList<Player> যখন আপনি এটিতে থাকবেন, যদি না আপনি বিশ্বাস করেন যে ফুটবল টিমের সম্পর্কে যারা জানে তারা সবাই রস্টার থেকে খেলোয়াড়দের মুছে ফেলবে।

List<T> থেকে উত্তরাধিকারী List<T> সর্বদা অগ্রহণযোগ্য?

কে অগ্রহণযোগ্য? আমাকে? না।

এটা গ্রহণযোগ্য যখন?

যখন আপনি এমন একটি প্রক্রিয়া তৈরি করছেন যা List<T> প্রক্রিয়াটি প্রসারিত করে

List<T> থেকে না উত্তরাধিকারী কিনা তা নির্ধারণ করার সময় কোন প্রোগ্রামার বিবেচনা করতে হবে?

আমি একটি প্রক্রিয়া বা একটি ব্যবসায়িক বস্তু নির্মাণ করছি?

কিন্তু যে কোড অনেক! আমি যে কাজ জন্য কি পেতে পারি?

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

হালনাগাদ

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

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


ফুটবলটাইমের প্রধান দলের সাথে রিজার্ভ টিম থাকলে কী হবে?

class FootballTeam
{
    List<FootballPlayer> Players { get; set; }
    List<FootballPlayer> ReservePlayers { get; set; }
}

আপনি যে কিভাবে মডেল হবে?

class FootballTeam : List<FootballPlayer> 
{ 
    public string TeamName; 
    public int RunningTotal 
}

সম্পর্ক স্পষ্টভাবে আছে এবং একটি হয় না।

নাকি RetiredPlayers ?

class FootballTeam
{
    List<FootballPlayer> Players { get; set; }
    List<FootballPlayer> ReservePlayers { get; set; }
    List<FootballPlayer> RetiredPlayers { get; set; }
}

থাম্ব একটি নিয়ম হিসাবে, আপনি যদি কখনও সংগ্রহ থেকে উত্তরাধিকার করতে চান, ক্লাস SomethingCollection নাম।

আপনার SomethingCollection semantically ইন্দ্রিয় তোলে? আপনার টাইপ Something সংগ্রহ যদি শুধুমাত্র এই কাজ।

ফুটবলটাইম ক্ষেত্রে এটি সঠিক নয়। একটি Team একটি Collection চেয়ে বেশি। কোচ, প্রশিক্ষক ইত্যাদি একটি Team থাকতে পারে যেমন অন্য উত্তরগুলি উল্লেখ করেছে।

FootballCollection কলেকশন ফুটবলের সংগ্রহের মতো বা ফুটবলের উপাদান সংগ্রহের মতো শোনাচ্ছে। TeamCollection , দলগুলোর একটি সংগ্রহ।

FootballPlayerCollection এমন খেলোয়াড়দের সংগ্রহের মতো শোনাচ্ছে যা List<FootballPlayer> থেকে উত্তরাধিকারী একটি শ্রেণির জন্য বৈধ নাম হবে যদি আপনি সত্যিই এটি করতে চান।

সত্যিই List<FootballPlayer> সঙ্গে মোকাবিলা করার জন্য একটি পুরোপুরি ভাল টাইপ। হয়তো IList<FootballPlayer> যদি আপনি এটি একটি পদ্ধতি থেকে ফিরে আসছেন।

সংক্ষেপে

নিজেকে জিজ্ঞাসা করুন

  1. X একটি Y ? অথবা X একটি Y ?

  2. আমার ক্লাস নাম কি তারা মানে?


সবাই যেমন উল্লেখ করেছেন, খেলোয়াড়দের একটি দল খেলোয়াড়দের তালিকা নয়। এই ভুলটি সর্বত্র অনেক লোকের দ্বারা তৈরি করা হয়, সম্ভবত দক্ষতার বিভিন্ন স্তরে। প্রায়ই সমস্যা সূক্ষ্ম এবং মাঝে মাঝে খুব স্থূল, এই ক্ষেত্রে হিসাবে। এই ডিজাইনগুলি খারাপ কারণ এটি লস্কোভ প্রতিস্থাপন নীতি লঙ্ঘন করে। এই ধারণাটি ব্যাখ্যা করার জন্য ইন্টারনেটে অনেক ভাল নিবন্ধ রয়েছে যেমন, http://en.wikipedia.org/wiki/Liskov_substitution_principle

সংক্ষেপে, ক্লাসের মধ্যে একটি পিতামাতা / শিশু সম্পর্কের মধ্যে সংরক্ষিত দুটি নিয়ম রয়েছে:

  • একটি সন্তানের পিতামাতার সম্পূর্ণরূপে সংজ্ঞায়িত চেয়ে কম কোন চরিত্রগত প্রয়োজন হবে।
  • একটি সন্তানের সম্পূর্ণরূপে শিশুর সংজ্ঞায়িত ছাড়াও কোন চরিত্রগত প্রয়োজন হবে।

অন্য কথায়, একটি সন্তানের একটি শিশুর একটি প্রয়োজনীয় সংজ্ঞা, এবং একটি সন্তানের একটি পিতামাতার যথেষ্ট সংজ্ঞা।

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

  • একটি ফুটবল দল ফুটবল খেলোয়াড়দের একটি তালিকা? (একটি তালিকা সব বৈশিষ্ট্য একই অর্থ একটি দলের প্রয়োগ)
    • একটি দল homogenous সত্তা একটি সংগ্রহ? হ্যাঁ, দল খেলোয়াড়দের একটি সংগ্রহ
    • দলের রাষ্ট্রের বর্ণনামূলক খেলোয়াড়দের অন্তর্ভুক্ত করার আদেশ কি দলটি নিশ্চিত করে যে ক্রমটি পরিবর্তিত না হওয়া পর্যন্ত ক্রমটি সংরক্ষিত হয়? না, এবং না
    • খেলোয়াড়দের মধ্যে তাদের sequencial অবস্থান উপর ভিত্তি করে অন্তর্ভুক্ত / বাদ দেওয়া প্রত্যাশিত হয়? না

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

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


সর্বোপরি, এটি ব্যবহারযোগ্যতা সঙ্গে আছে। আপনি উত্তরাধিকার ব্যবহার করলে, Team ক্লাসটি আচরণ (পদ্ধতি) প্রকাশ করবে যা বস্তু ম্যানিপুলেশনের জন্য সম্পূর্ণভাবে ডিজাইন করা হয়েছে। উদাহরণস্বরূপ, AsReadOnly() অথবা CopyTo(obj) পদ্ধতিগুলি দলের বস্তুর জন্য কোন ধারনা দেয় না।পরিবর্তে AddRange(items)পদ্ধতিটি সম্ভবত আপনি একটি আরো বর্ণনামূলক AddPlayers(players)পদ্ধতি চাই।

আপনি LINQ ব্যবহার করতে চান, যেমন একটি জেনেরিক ইন্টারফেস বাস্তবায়ন ICollection<T>বা IEnumerable<T>আরো জ্ঞান করতে হবে।

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


আইফেলের উদ্ভাবক এবং চুক্তি অনুসারে ডিজাইনের বেত্রাণ্ড মেয়েরকে আমি কেবল যুক্ত করতে চেয়েছিলাম, এটি একটি চোখের প্যাটার্ন ব্যাটিংয়ের মতোই Teamউত্তরাধিকারী হবে List<Player>

তার বই, অবজেক্ট-ওরিয়েন্টেড সফটওয়্যার নির্মাণে , তিনি একটি GUI সিস্টেম বাস্তবায়ন নিয়ে আলোচনা করেন যেখানে আয়তক্ষেত্রাকার উইন্ডোতে শিশু উইন্ডো থাকতে পারে। তিনি কেবল হয়েছে Windowউভয় থেকে উত্তরাধিকারী Rectangleএবং Tree<Window>বাস্তবায়ন পুনরায় ব্যবহার করার জন্য।

তবে, সি # আইফেল নয়। পরেরটি একাধিক উত্তরাধিকার এবং বৈশিষ্ট্য পুনর্নাম সমর্থন করে । সি #, যখন আপনি উপবিষ্ট, আপনি ইন্টারফেস এবং প্রয়োগ উভয় উত্তরাধিকারী। আপনি বাস্তবায়ন override করতে পারেন, কিন্তু কলিং কনভেনশন সরাসরি superclass থেকে কপি করা হয়। আইফেল তবে আপনি পাবলিক পদ্ধতির নাম পরিবর্তন করতে পারেন, তাই আপনি নাম পরিবর্তন করতে পারেন Addএবং Removeকরতে Hireএবং Fireআপনার Team। যদি একটি উদাহরণ Teamফিরে আপcast হয় List<Player>, কলার এটি ব্যবহার Addএবং Removeসংশোধন করতে হবে, কিন্তু আপনার ভার্চুয়াল পদ্ধতি Hireএবং Fireবলা হবে।


আপনার ক্লাস ব্যবহারকারীদের সমস্ত পদ্ধতি এবং বৈশিষ্ট্য প্রয়োজন ** তালিকা আছে, আপনি এটি থেকে আপনার বর্গ অর্জন করা উচিত। যদি তাদের প্রয়োজন হয় না, তালিকাটি ঘিরে রাখুন এবং আপনার ক্লাস ব্যবহারকারীদের আসলে প্রয়োজনীয় পদ্ধতিগুলির জন্য মোড়ক তৈরি করুন।

এটি একটি কঠোর নিয়ম, যদি আপনি একটি পাবলিক API টি লিখেন , বা অন্য কোনও কোড ব্যবহার করেন যা অনেক লোকের দ্বারা ব্যবহৃত হবে। আপনার যদি একটি ছোট অ্যাপ্লিকেশন থাকে এবং 2 টিরও বেশি ডেভেলপার থাকে তবে আপনি এই নিয়মটি উপেক্ষা করতে পারেন। এটি আপনাকে কিছু সময় বাঁচাবে।

ক্ষুদ্র অ্যাপ্লিকেশনের জন্য, আপনি আরও কম কঠোর ভাষা বেছে নেওয়ার কথা বিবেচনা করতে পারেন। রুবি, জাভাস্ক্রিপ্ট - আপনি কম কোড লিখতে পারবেন যা কিছু।


আমার নোংরা গোপন রহস্য: আমি মানুষকে কি বলি তা আমি যত্ন করি না, এবং আমি তা করি। .NET ফ্রেমওয়ার্কটি "XxxxCollection" এর সাথে ছড়িয়ে পড়ে (আমার প্রধান উদাহরণের জন্য UIElementCollection)।

তাই আমাকে বলার অপেক্ষা রাখে না:

team.Players.ByName("Nicolas")

আমি এটা চেয়ে ভাল এটি যখন

team.ByName("Nicolas")

তাছাড়া, আমার প্লেয়ার কলেকশনটি অন্য শ্রেণীর দ্বারা ব্যবহৃত হতে পারে, যেমন "ক্লাবে" কোনও কোড অনুলিপি ছাড়াই।

club.Players.ByName("Nicolas")

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

team.Players.ByName("Nicolas") 

অথবা

team.ByName("Nicolas")

সত্যিই। আপনি কি কোন সন্দেহ আছে? এখন আপনার হয়তো অন্যান্য প্রযুক্তিগত সীমাবদ্ধতার সাথে খেলতে হবে যা আপনাকে আপনার আসল ব্যবহারের ক্ষেত্রে তালিকা <টি> ব্যবহার করতে বাধা দেয়। কিন্তু অস্তিত্ব থাকা উচিত যে একটি সীমাবদ্ধতা যোগ করবেন না। যদি মাইক্রোসফট কেন নথি নথিভুক্ত না করে তবে এটি অবশ্যই কোনও "সেরা অনুশীলন" নয়।


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

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

সম্ভবত, একটি PlayerCollection betters ধারণা আপনার পছন্দের পদ্ধতির suits?

public class PlayerCollection : Collection<Player> 
{ 
}

এবং তারপর ফুটবলটাইম এটি দেখতে পারেন:

public class FootballTeam 
{ 
    public string Name { get; set; }
    public string Location { get; set; }

    public ManagementCollection Management { get; protected set; } = new ManagementCollection();

    public CoachingCollection CoachingCrew { get; protected set; } = new CoachingCollection();

    public PlayerCollection Players { get; protected set; } = new PlayerCollection();
}

একটি ফুটবল দল ফুটবল খেলোয়াড়দের তালিকা নয় । একটি ফুটবল দল ফুটবল খেলোয়াড়দের তালিকা নিয়ে গঠিত !

এই যুক্তিযুক্ত ভুল:

class FootballTeam : List<FootballPlayer> 
{ 
    public string TeamName; 
    public int RunningTotal 
}

এবং এটি সঠিক:

class FootballTeam 
{ 
    public List<FootballPlayer> players
    public string TeamName; 
    public int RunningTotal 
}

এখানে অনেক চমৎকার উত্তর রয়েছে, কিন্তু আমি এমন কিছু স্পর্শ করতে চাই যা আমি উল্লেখ করিনি: অবজেক্ট ভিত্তিক নকশা বস্তুকে ক্ষমতায়নের বিষয়ে ।

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

যখন আপনি উত্তরাধিকারী হন List, অন্য সমস্ত বস্তু আপনাকে তালিকা হিসাবে দেখতে পারেন। তারা প্লেয়ার যোগ এবং অপসারণ করার পদ্ধতি সরাসরি এক্সেস আছে। এবং আপনি আপনার নিয়ন্ত্রণ হারিয়ে গেছে; উদাহরণ স্বরূপ:

ধরুন, কোন খেলোয়াড় অবসরপ্রাপ্ত, পদত্যাগ করেছেন বা বহিস্কার করা হয়েছে কিনা তা জানার মাধ্যমে আপনি কোনও খেলোয়াড়কে আলাদা করতে চান। আপনি RemovePlayerএকটি উপযুক্ত ইনপুট enum লাগে যে একটি পদ্ধতি বাস্তবায়ন করতে পারে । যাইহোক, উত্তরাধিকার দ্বারা List, আপনি সরাসরি অ্যাক্সেস প্রতিরোধ করতে পারবেন Remove, RemoveAllএমনকি Clear। ফলস্বরূপ, আপনি আসলে আপনার ক্লাস disempowered করেছি FootballTeam

Encapsulation উপর অতিরিক্ত চিন্তা ... আপনি নিম্নলিখিত উদ্বেগ উত্থাপিত:

এটা আমার কোড অযথা verbose করে তোলে। আমি এখন my_team.players.Count করতে হবে পরিবর্তে শুধু my_team কল।

আপনি সঠিক, সমস্ত ক্লায়েন্টদের আপনি দলের ব্যবহার করার জন্য অযথাযথভাবে verbose হবে। তবে, সমস্যাটির তুলনায় এটি খুব ছোট এবং List Playersআপনি সবার কাছে উন্মুক্ত হয়েছেন যাতে তারা আপনার সম্মতি ছাড়াই আপনার দলের সাথে খারাপ আচরণ করতে পারে।

আপনি বলতে যান:

এটা শুধু প্লেইন কোন ধারনা না। একটি ফুটবল দল খেলোয়াড়দের একটি তালিকা "আছে" না। এটা খেলোয়াড়দের তালিকা। আপনি বলবেন না "জন ম্যাকফুটবলার কিছুটা খেলোয়াড়ের সাথে যোগ দিয়েছেন"। আপনি বলছেন "জন কিছুটাতে যোগ দিয়েছে"।

আপনি প্রথম বিট সম্পর্কে ভুল আছেন: শব্দটি 'তালিকা' টিপুন, এবং এটি আসলেই স্পষ্ট যে একটি দলের খেলোয়াড় আছে।
যাইহোক, আপনি দ্বিতীয় সঙ্গে মাথা উপর পেরেক আঘাত। আপনি ক্লায়েন্ট কলিং করতে চান না ateam.Players.Add(...)। আপনি তাদের কলিং করতে চান ateam.AddPlayer(...)। এবং আপনার বাস্তবায়ন (সম্ভবত অন্যান্য জিনিসের মধ্যে) Players.Add(...)অভ্যন্তরীণ কল ।

আশা করছি আপনি আপনার বস্তুকে ক্ষমতায়ন করার উদ্দেশ্যে কীভাবে গুরুত্বপূর্ণ encapsulation হয় তা দেখতে পারেন। আপনি অন্য ক্লাস থেকে হস্তক্ষেপের ভয় ছাড়াই প্রতিটি ক্লাসকে তার কাজ ভালভাবে করতে চান।


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


যখন তারা বলে List<T>"অপ্টিমাইজড" বলে মনে হয় তারা মনে করতে চায় যে এতে ভার্চুয়াল পদ্ধতির মতো বৈশিষ্ট্য নেই যা আরও বেশি ব্যয়বহুল। সুতরাং সমস্যাটি হল যে আপনি একবার List<T>আপনার পাবলিক এপিআইতে প্রকাশ করেন , আপনি ব্যবসায়িক নিয়মগুলি প্রয়োগ করার ক্ষমতা বা পরে তার কার্যকারিতা কাস্টমাইজ করতে পারবেন। কিন্তু আপনি যদি আপনার প্রকল্পের অভ্যন্তরে অভ্যন্তরীণ হিসাবে এই উত্তরাধিকারী শ্রেণির ব্যবহার করছেন (আপনার হাজারো গ্রাহক / অংশীদার / API টি হিসাবে অন্যান্য দলগুলির সম্ভাব্য প্রকাশের বিরোধিতা করে) তাহলে এটি আপনার সময় সংরক্ষণ করে যদি এটি ঠিক থাকে তবে এটি সেই কার্যকারিতা যা আপনি চান নকল. উত্তরাধিকারসূত্রে সুবিধাটি List<T>হ'ল আপনি পুরোপুরি ভবিষ্যতে কাস্টমাইজড হতে যাচ্ছেন না এমন মুঠোফোনের কোডটি সম্পূর্ণভাবে বর্জন করুন। এছাড়াও যদি আপনি আপনার বর্গ স্পষ্টভাবে সঠিক একই semantics আছে চানList<T> আপনার API গুলি এর জন্য এটি ঠিক আছে।

আমি প্রায়ই FxCop নিয়ম বলার কারণে বা অনেকের ব্লগ বলে যে এটি একটি "খারাপ" অভ্যাস বলে প্রচুর লোককে অতিরিক্ত কাজ করে দেখছে। অনেক বার, এই নকশা প্যাটার্ন weirdness নকশা কোড সক্রিয় করে। গাইডলাইন অনেক হিসাবে, এটি ব্যতিক্রম থাকতে পারে যে নির্দেশিকা হিসাবে আচরণ ।


শুধু কারণ আমি মনে করি অন্য উত্তরগুলি একটি ফুটবল দল "আই-এ" List<FootballPlayer>বা " হ্যা-এ" কিনা তা স্পর্শকাতরভাবে অনেক বেশি দূরে চলে যায় List<FootballPlayer>, যা আসলেই লিখিতভাবে এই প্রশ্নের উত্তর দেয় না।

ওপেন মূলত উত্তরাধিকার সূত্রে প্রাপ্ত নির্দেশিকা সম্পর্কে স্পষ্টতা জানায় List<T>:

একটি নির্দেশিকা বলেছেন যে আপনি উত্তরাধিকারী উচিত নয় List<T>। কেন না?

কারণ List<T>কোন ভার্চুয়াল পদ্ধতি আছে। এটি আপনার নিজের কোডের একটি সমস্যা কম, আপনি সাধারণত অপেক্ষাকৃত কম ব্যথা সহ বাস্তবায়নটি স্যুইচ করতে পারেন - তবে এটি একটি সার্বজনীন API এ একটি বড় চুক্তি হতে পারে।

একটি পাবলিক এপিআই কি এবং আমি কেন যত্ন করা উচিত?

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

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

অনেক অনেক, হ্যাঁ। আপনি যে কোনও অবস্থাতেই এটি প্রযোজ্য কিনা তা দেখতে আপনার পিছনে যুক্তিটি বিবেচনা করতে পারেন, তবে আপনি যদি কোনও সার্বজনীন API তৈরি না করেন তবে আপনাকে বিশেষভাবে সংস্করণ সম্পর্কিত API টির উদ্বেগ সম্পর্কে চিন্তা করতে হবে না (যার মধ্যে এটি একটি উপসেট)।

আপনি যদি ভবিষ্যতে একটি পাবলিক API যোগ করেন, তবে আপনাকে আপনার বাস্তবায়নের (আপনার List<T>সরাসরি প্রকাশ না করে) আপনার API থেকে বিমূর্ততা বা সম্ভাব্য ভবিষ্যতের ব্যথাগুলি সহ নির্দেশিকাগুলি লঙ্ঘন করতে হবে।

কেন এটা এমনকি কোন ব্যাপার না? একটি তালিকা একটি তালিকা। সম্ভবত কি পরিবর্তন হতে পারে? আমি কি সম্ভবত পরিবর্তন করতে চান?

প্রেক্ষাপটে নির্ভর করে, কিন্তু আমরা FootballTeamএকটি উদাহরণ হিসাবে ব্যবহার করছি - কল্পনা করুন যে আপনি FootballPlayerএটি যোগ করতে পারবেন না যদি এটি দলটিকে টুপি টুপি অতিক্রম করতে দেয়। যোগ করার একটি সম্ভাব্য উপায় এমন কিছু হতে পারে:

 class FootballTeam : List<FootballPlayer> {
     override void Add(FootballPlayer player) {
        if (this.Sum(p => p.Salary) + player.Salary > SALARY_CAP)) {
          throw new InvalidOperationException("Would exceed salary cap!");
        }
     }
 }

আহ ... কিন্তু আপনি override Addএটি করতে পারবেন না কারণ virtual(কর্মক্ষমতা কারণে)।

আপনি যদি কোনও অ্যাপ্লিকেশানটিতে থাকেন (যা মূলত, আপনি এবং আপনার সমস্ত কলাম একত্রিত হয়) তাহলে আপনি এখন ব্যবহার করতে IList<T>এবং কোনও কম্পাইল ত্রুটিগুলি ঠিক করতে পারেন :

 class FootballTeam : IList<FootballPlayer> {
     private List<FootballPlayer> Players { get; set; }

     override void Add(FootballPlayer player) {
        if (this.Players.Sum(p => p.Salary) + player.Salary > SALARY_CAP)) {
          throw new InvalidOperationException("Would exceed salary cap!");
        }
     }
     /* boiler plate for rest of IList */
 }

কিন্তু, যদি আপনি প্রকাশ্যে তৃতীয় পক্ষের কাছে প্রকাশ করেছেন তবে আপনি কেবল একটি বিরতি পরিবর্তন করেছেন যা কম্পাইল এবং / অথবা রানটাইম ত্রুটিগুলি সৃষ্টি করবে।

টিএল; ডিআর - নির্দেশিকা পাবলিক APIs জন্য। ব্যক্তিগত API এর জন্য, আপনি যা চান তা করুন।


class FootballTeam : List<FootballPlayer> 
{ 
    public string TeamName; 
    public int RunningTotal;
}

পূর্ববর্তী কোড মানে: রাস্তায় ফুটবল খেলোয়াড়দের একটি গুচ্ছ, এবং তারা একটি নাম আছে ঘটবে। কিছুটা এইরকম:

যাইহোক, এই কোড (আমার উত্তর থেকে)

public class FootballTeam
{
    // Football team rosters are generally 53 total players.
    private readonly List<T> _roster = new List<T>(53);

    public IList<T> Roster
    {
        get { return _roster; }
    }

    public int PlayerCount
    {
    get { return _roster.Count(); }
    }

    // Any additional members you want to expose/wrap.
}

অর্থ: এটি এমন একটি ফুটবল দল যা পরিচালনা করে, খেলোয়াড়, প্রশাসক, ইত্যাদি কিছু পছন্দ করে:

এই ছবিতে আপনার যুক্তি উপস্থাপন করা হয় কিভাবে ...





inheritance