<T> তালিকা থেকে উত্তরাধিকারী হন না কেন?


1398

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

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

var football_team = new List<FootballPlayer>();

এই তালিকার ক্রমটি ক্রমকে প্রতিনিধিত্ব করে যাতে খেলোয়াড়দের রোস্টারে তালিকাভুক্ত করা হয়।

তবে আমি পরে বুঝতে পেরেছি যে খেলোয়াড়দের নিছক তালিকা ছাড়াও দলগুলিরও অন্যান্য সম্পত্তি রয়েছে that উদাহরণস্বরূপ, এই মরসুমে চলমান মোট স্কোর, বর্তমান বাজেট, ইউনিফর্ম রঙ, stringদলের নাম উপস্থাপনা ইত্যাদি etc

তাহলে আমার মনে হয়:

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

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

তবে দেখা যাচ্ছে যে কোনও গাইডলাইন আপনাকে উত্তরাধিকার সূত্রে উত্তম হওয়া উচিত নয়List<T> । আমি দুটি দিক থেকে এই নির্দেশিকাটি থেকে পুরোপুরি বিভ্রান্ত।

কেন না?

দৃশ্যত Listকোনওভাবে পারফরম্যান্সের জন্য অনুকূলিত । তা কিভাবে? যদি আমি প্রসারিত করি তবে কোন পারফরম্যান্স সমস্যা হতে পারে List? ঠিক কী ভাঙবে?

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

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

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

আমার আর কী ব্যবহার করার কথা?

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

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

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

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

class FootballTeam 
{ 
    public List<FootballPlayer> Players; 
}

এটির সাথে দুটি সমস্যা রয়েছে:

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

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

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

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

একটি ডাটা স্ট্রাকচার, যা, "কথাটি" ( "মানুষের মনের থেকে" বলতে হয় যে,) শুধু একটি হল প্রতিনিধিত্বমূলক সঠিক C # এর উপায় কি listএর thingsকয়েক ঘন্টাধ্বনি এবং whistles সঙ্গে?

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


90
সুতরাং, উত্তরাধিকারটি কখন ব্যবহার করবেন (আপনার একটি বর্গক্ষেত্রটি একটি আয়তক্ষেত্রের কারণ যখন জেনেরিক আয়তক্ষেত্রের অনুরোধ করা হয়েছিল তখন স্কয়ার সরবরাহ করা সর্বদা যুক্তিসঙ্গত) এবং সংমিশ্রণটি কখন ব্যবহার করবেন (একটি ফুটবলমেট-এর সাথে ফুটবলপ্লেয়ারগুলির একটি তালিকা রয়েছে) অন্যান্য বৈশিষ্ট্যগুলিতে যা এটির মতো "মৌলিক", নাম হিসাবে)? অন্যান্য প্রোগ্রামাররা কি বিভ্রান্ত হবে যদি কোডের অন্য কোথাও আপনি তাদের একটি ফুটবল টিম পাস করেছেন যখন তারা সরল তালিকার প্রত্যাশা করছেন?
ফ্লাইট ওডিসি

77
যদি আমি আপনাকে বলি যে একটি ফুটবল দল এমন একটি ব্যবসায়িক সংস্থা যা ওডব্লিউএনএসের অতিরিক্ত কিছু সম্পত্তি যুক্ত খেলোয়াড়ের খালি তালিকার পরিবর্তে খেলোয়াড়ের চুক্তির একটি তালিকা রয়েছে?
এসটিটি এলসিইউ

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

45
@ ফ্লাইটডিসি: ধরুন আপনার কাছে এমন একটি স্কোয়াশআরেক্টাঙ্গল রয়েছে যা একটি আয়তক্ষেত্র গ্রহণ করে, এর উচ্চতা অর্ধেক করে দেয় এবং প্রস্থ দ্বিগুণ করে। এখন একটি আয়তক্ষেত্র যে মধ্যে পাস ঘটে 4x4 হতে কিন্তু টাইপ আয়তক্ষেত্র, এবং একটি বর্গক্ষেত্র যে 4x4। স্কোয়াশেক্টাঙ্গেল বলার পরে অবজেক্টের মাত্রা কী? আয়তক্ষেত্রের জন্য পরিষ্কারভাবে এটি 2x8। বর্গটি 2x8 হয় তবে এটি আর বর্গক্ষেত্র নয়; যদি এটি 2x8 না হয় তবে একই আকারে একই ক্রিয়াকলাপটি ভিন্ন ফলাফলের জন্ম দেয়। উপসংহার যে একটি চপল বর্গ হয় না আয়তক্ষেত্র এক ধরনের।
এরিক লিপার্ট

29
@ গাংনাস: আপনার বক্তব্যটি কেবল মিথ্যা; একটি আসল সাবক্লাসের কার্যকারিতা থাকা প্রয়োজন যা সুপারক্লাসের সুপারসেট । একজন stringসবকিছু একটি করার প্রয়োজন হয় objectকি করতে পারেন এবং আরো
এরিক লিপার্ট

উত্তর:


1564

এখানে কিছু ভাল উত্তর আছে। আমি তাদের সাথে নিম্নলিখিত বিষয়গুলি যুক্ত করব।

কোনও ডাটা স্ট্রাকচারকে উপস্থাপনের সঠিক সি # উপায় কী, যা "যৌক্তিকভাবে" (এটি বলতে গেলে "মানুষের মনে" বলা হয়) কয়েকটি ঘণ্টা এবং শিসিসহ কিছু জিনিস তালিকাভুক্ত?

যে কোনও দশটি কম্পিউটার-প্রোগ্রামার লোককে ফুটবলের অস্তিত্বের সাথে পরিচিত শূন্যস্থান পূরণ করতে বলুন:

একটি ফুটবল দল একটি বিশেষ ধরণের _____

কি যে কেউ বলে "কয়েক ঘন্টাধ্বনি এবং whistles সঙ্গে ফুটবল খেলোয়াড় তালিকা", বা তারা সব বলে "ক্রীড়া দল" বা "ক্লাব" বা "সংগঠন" করেছিলেন? আপনার ধারণা যে কোনও ফুটবল দল খেলোয়াড়দের একটি বিশেষ ধরণের তালিকা যা আপনার মন এবং আপনার মানবিক মনের মধ্যে রয়েছে।

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

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

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

কখন তা গ্রহণযোগ্য?

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

একজন প্রোগ্রামারকে অবশ্যই কোন বিষয় বিবেচনা করতে হবে, যখন উত্তরাধিকারী হতে হবে কিনা তা সিদ্ধান্ত নেওয়ার সময় List<T>?

আমি কি কোনও প্রক্রিয়া তৈরি করছি বা কোনও ব্যবসায়িক অবজেক্ট ?

তবে তা অনেকটা কোড! এই সমস্ত কাজের জন্য আমি কী পেতে পারি?

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

হালনাগাদ

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

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


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

127
@ সুপর্বেষ্ট: খুশী আমি সাহায্য করতে পারি! আপনি এই সন্দেহগুলি শুনতে ঠিক বলেছেন; আপনি যদি কিছু কোড কেন লিখছেন তা বুঝতে না পারলে তা নির্ধারণ করুন, বা আপনি বুঝতে পারেন এমন আলাদা কোড লিখুন।
এরিক লিপার্ট

48
@ মেহরদাদ তবে আপনি অপ্টিমাইজেশনের সুবর্ণ নিয়মগুলি ভুলে যাবেন বলে মনে হচ্ছে: 1) এটি করবেন না, 2) এটি এখনও করবেন না, এবং 3) কীটি অপ্টিমাইজ করা প্রয়োজন তা প্রদর্শন করার জন্য প্রথমে পারফরম্যান্স প্রোফাইল না করে এটি করবেন না।
এজেম্যান্সফিল্ড

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

44
@ সুপুস্টেস্ট: এখন আমরা অবশ্যই বর্ণালীটির শেষে "কম্পোজিশন নয় উত্তরাধিকার" এ আছি । একটি রকেট রকেট অংশ গঠিত হয় । রকেট "বিশেষ ধরণের পার্টস লিস্ট" নয়! আমি আপনাকে পরামর্শ দেব যে আপনি এটি আরও ছাঁটাই; একটি তালিকা, কেন একটি বিপরীতে IEnumerable<T>- একটি ক্রম ?
এরিক লিপার্ট

161

বাহ, আপনার পোস্টে পুরো প্রশ্ন এবং পয়েন্ট রয়েছে। মাইক্রোসফ্টের কাছ থেকে আপনি বেশিরভাগ যুক্তিটি হুবহু পয়েন্টে। এর সবকিছু দিয়ে শুরু করা যাকList<T>

  • List<T> হয় অত্যন্ত অপ্টিমাইজ করা। এর প্রধান ব্যবহারটি কোনও বস্তুর ব্যক্তিগত সদস্য হিসাবে ব্যবহার করা হয়।
  • মাইক্রোসফট এটা সীল করা হয়নি কারণ কখনও কখনও আপনি একটি বর্গ একটি বন্ধুত্বপূর্ণ নাম আছে তৈরি করতে চান করতে পারেন: class MyList<T, TX> : List<CustomObject<T, Something<TX>> { ... }। এখন এটি করা যেমন সহজ var list = new MyList<int, string>();
  • CA1002: জেনেরিক তালিকাগুলি প্রকাশ করবেন না : মূলত, আপনি যদি এই অ্যাপটিকে একমাত্র বিকাশকারী হিসাবে ব্যবহার করার পরিকল্পনা করেন তবে ভাল কোডিং অনুশীলনগুলির সাথে এটি বিকাশ লাভজনক, তাই এগুলি আপনার এবং দ্বিতীয় প্রকৃতির অন্তর্ভুক্ত হয়ে যায়। আপনার IList<T>যদি তালিকাভুক্ত তালিকার জন্য কোনও গ্রাহকের প্রয়োজন হয় তবে আপনাকে তালিকাটি প্রকাশের অনুমতি দেয়। এটি আপনাকে পরে ক্লাসের মধ্যে প্রয়োগটি পরিবর্তন করতে দেয়।
  • মাইক্রোসফ্ট Collection<T>খুব জেনেরিক তৈরি করেছে কারণ এটি একটি জেনেরিক ধারণা ... নামটি সব বলে; এটি কেবল একটি সংগ্রহ। যেমন আরও ভালো সংস্করণ আছে SortedCollection<T>, ObservableCollection<T>, ReadOnlyCollection<T>প্রতিটি যা বাস্তবায়ন ইত্যাদি IList<T>কিন্তু না List<T>
  • Collection<T>সদস্যদের (যেমন যোগ, সরান, ইত্যাদি) ওভাররাইড করার অনুমতি দেয় কারণ তারা ভার্চুয়াল are List<T>না.
  • আপনার প্রশ্নের শেষ অংশটি স্পট রয়েছে। একটি ফুটবল দল খেলোয়াড়ের তালিকার চেয়ে আরও বেশি কিছু, তাই এটি এমন একটি শ্রেণি হওয়া উচিত যাতে সেই খেলোয়াড়ের তালিকা থাকে। রচনা বনাম উত্তরাধিকার মনে করুন । একটি ফুটবল দলের হয়ে গেছে একটি (ক পালা) খেলোয়াড়দের তালিকা, এটা খেলোয়াড়দের একটি তালিকা নয়।

আমি যদি এই কোডটি লিখতাম তবে ক্লাসটি সম্ভবত এর মতো কিছু দেখত:

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; }
    }

    // Yes. I used LINQ here. This is so I don't have to worry about
    // _roster.Length vs _roster.Count vs anything else.
    public int PlayerCount
    {
        get { return _roster.Count(); }
    }

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

6
" আপনার পোস্টে পুরো প্রশ্ন রয়েছে " - ভাল, আমি বলেছিলাম যে আমি পুরোপুরি বিভ্রান্ত ছিলাম। @ রিডোনালির প্রশ্নের সাথে যুক্ত করার জন্য ধন্যবাদ, আমি এখন দেখতে পাচ্ছি যে আমার প্রশ্নের একটি বড় অংশ আরও সাধারণ রচনা বনাম উত্তরাধিকার সমস্যার একটি বিশেষ ক্ষেত্রে is
সুপারবেস্ট

3
@ ব্রায়ান: আপনি উলাম ব্যবহার করে জেনেরিক তৈরি করতে পারবেন না, সমস্ত প্রকারের অবশ্যই কংক্রিট হওয়া উচিত। আমার উদাহরণে, List<T>একটি ব্যক্তিগত অভ্যন্তর শ্রেণি হিসাবে প্রসারিত যা জেনেরিকগুলি ব্যবহারের এবং ঘোষণাকে সহজ করার জন্য ব্যবহার করে List<T>। যদি এক্সটেনশানটি কেবলমাত্র হয় class FootballRoster : List<FootballPlayer> { }, তবে হ্যাঁ আমি পরিবর্তে কোনও উপকরণ ব্যবহার করতে পারতাম। আমি অনুমান করি যে আপনি অতিরিক্ত সদস্য / কার্যকারিতা যুক্ত করতে পারেন তবে এটি সীমাবদ্ধ কারণ আপনি গুরুত্বপূর্ণ সদস্যদের ওভাররাইড করতে পারবেন না List<T>
আমার

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

7
Collection<T> allows for members (i.e. Add, Remove, etc.) to be overriddenএখন যে একটি ভাল কারণ তালিকা থেকে উত্তরাধিকারী নয়। অন্য উত্তরগুলির অনেক বেশি দর্শন রয়েছে।
নবীন

10
@ মাই: আমি সন্দেহ করি আপনার প্রশ্নগুলি "হত্যাকার" বলতে চাইছেন, যেহেতু একটি sleuth একটি গোয়েন্দা।
ব্যাটি

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

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

মানুষ ফুটবল খেলছে

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

public class FootballTeam
{
    // A team's name
    public string TeamName; 

    // 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.
}

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

ম্যানচেস্টার ইউনাইটেড দলের সদস্যদের (এবং অন্যান্য বৈশিষ্ট্যগুলি) চিত্র দেখানো হচ্ছে

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


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

3
আরও অনুকূলিতprivate readonly List<T> _roster = new List<T>(44);
এসইডি

2
System.Linqনেমস্পেসটি আমদানি করা দরকার ।
ডেভিড ক্যানিজো

1
ভিজ্যুয়ালগুলির জন্য: +1
V.7

115

এটি রচনা বনাম উত্তরাধিকারের একটি দুর্দান্ত উদাহরণ ।

এই নির্দিষ্ট ক্ষেত্রে:

দলটি কি যুক্তিযুক্ত আচরণের খেলোয়াড়দের একটি তালিকা

অথবা

দলটি কি তার নিজস্ব একটি জিনিস যা খেলোয়াড়ের একটি তালিকা অন্তর্ভুক্ত করে।

তালিকা প্রসারিত করে আপনি নিজেকে বেশ কয়েকটি উপায়ে সীমাবদ্ধ করছেন:

  1. আপনি অ্যাক্সেসকে সীমাবদ্ধ করতে পারবেন না (উদাহরণস্বরূপ, রোস্টার পরিবর্তন করা লোকদের থামানো)। আপনার সমস্ত তালিকা প্রয়োজন বা না চান সেগুলি আপনি সমস্ত তালিকা পদ্ধতি পান।

  2. আপনার অন্যান্য জিনিসগুলির তালিকা থাকতে চাইলে কী হয়। উদাহরণস্বরূপ, দলগুলির কোচ, ম্যানেজার, অনুরাগী, সরঞ্জামাদি ইত্যাদি রয়েছে those এর মধ্যে কয়েকটি তাদের নিজস্ব তালিকায় ভাল থাকতে পারে।

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

রচনা - আপনার অবজেক্টের অভ্যন্তরে আপনি চান এমন আচরণ প্রদান করে এমন একটি সামগ্রী

উত্তরাধিকার - আপনার অবজেক্টটি সেই বস্তুর একটি উদাহরণ হয়ে ওঠে যা আপনার পছন্দসই আচরণ করে।

উভয়ের ব্যবহার রয়েছে তবে এটি একটি স্পষ্ট কেস যেখানে রচনাটি পছন্দনীয়।


1
# 2-তে প্রসারিত হওয়া, কোনও তালিকা - তালিকা থাকা কোনও অর্থহীন নয় ।
ক্রંચার

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

6
@ স্যাম তিনি তালিকার আচরণ চান। তার দুটি পছন্দ রয়েছে, তিনি তালিকাটি (উত্তরাধিকার) প্রসারিত করতে পারেন বা তিনি তাঁর বস্তুর (রচনা) ভিতরে একটি তালিকা অন্তর্ভুক্ত করতে পারেন। ৫৫ জনের ভুল হওয়ার পরিবর্তে আপনি প্রশ্ন বা উত্তরের একটি অংশকে ভুল বুঝতে পেরেছেন এবং আপনি সঠিক? :)
টিম বি

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

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

67

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

সংক্ষেপে, শ্রেণীর মধ্যে পিতামাতার / সন্তানের সম্পর্কের জন্য দুটি নিয়ম সংরক্ষণ করা হবে:

  • সন্তানের সম্পূর্ণরূপে পিতামাতার সংজ্ঞা দেয় তার চেয়ে কম কোনও বৈশিষ্ট্যের প্রয়োজন নেই।
  • সন্তানের সম্পূর্ণরূপে সংজ্ঞায়িত করা ছাড়াও পিতামাতার কোনও বৈশিষ্ট্যের প্রয়োজন নেই।

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

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

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

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

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


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

1
কিছু ভাল পয়েন্টের জন্য +1, যদিও এটি জিজ্ঞাসা করা আরও গুরুত্বপূর্ণ যে "ডেটা স্ট্রাকচারটি দরকারী হিসাবে কার্যকরভাবে বেশি কাজ করে" এর চেয়ে "ডেটা স্ট্রাকচারটি দরকারী সমস্ত কিছুকে (আদর্শভাবে স্বল্প ও দীর্ঘমেয়াদী) সমর্থন করতে পারে" ask
টনি ডেলরয়

1
@ টনিড ওয়েল, আমি যে বিষয়গুলি উত্থাপন করছি তা নয় যে "যদি ডেটা স্ট্রাকচারটি দরকারী তার চেয়ে বেশি কাজ করে" তবে এটি পরীক্ষা করা উচিত নয়। এটি "চিত্তাকর্ষক ডেটা কাঠামোটি এমন কিছু করে যা শিশু শ্রেণীর দ্বারা বোঝানো যেতে পারে এমন আচরণের প্রতি অপ্রাসঙ্গিক, অর্থহীন বা পাল্টা স্বজ্ঞাত" তা পরীক্ষা করা উচিত।
সত্যান রায়না

1
@ টনিড আসলে পিতামাতার কাছ থেকে প্রাপ্ত অপ্রাসঙ্গিক বৈশিষ্ট্যগুলি নিয়ে একটি সমস্যা রয়েছে কারণ এটি অনেক ক্ষেত্রে নেতিবাচক পরীক্ষায় ব্যর্থ হবে। একজন প্রোগ্রামার মানব-খাওয়া () প্রসারিত করতে পারে; চালানো (); লিখুন (); G একজন গরিলা থেকে {খাও (); চালানো (); swing ();} দোল করতে সক্ষম হওয়ার অতিরিক্ত বৈশিষ্ট্যযুক্ত কোনও মানুষের মধ্যে কোনও ভুল নেই} এবং তারপরে একটি গেমের জগতে আপনার মানুষ হঠাৎ করে গাছের উপর দোল দিয়ে সমস্ত অনুভূত স্থল বাধাগুলি অতিক্রম করতে শুরু করে। সুস্পষ্টভাবে সুনির্দিষ্টভাবে উল্লেখ না করা পর্যন্ত একজন ব্যবহারিক মানবকে দোল দেওয়া উচিত নয়। এ জাতীয় নকশা এপিআইটিকে খুব খারাপ ব্যবহার এবং বিভ্রান্তির জন্য ছেড়ে দেয়
সত্যান রায়না

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

50

FootballTeamমূল দলের সাথে যদি কোনও রিজার্ভ দল থাকে?

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শব্দার্থগতভাবে কি তা বোঝায়? শুধু এই কাজ যদি আপনার টাইপ একটি হল সংগ্রহ Something

এটি ক্ষেত্রে FootballTeamসঠিক শব্দ না। ক এর Teamচেয়ে বেশি Collection। একজন Teamপ্রশিক্ষক, প্রশিক্ষক, ইত্যাদি হিসাবে অন্যান্য উত্তর নির্দিষ্ট থাকতে পারে।

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

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

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

সংক্ষেপে

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

  1. কি X একটি Y? বা আছে X একটি Y?

  2. আমার শ্রেণীর নামগুলি কি তাদের অর্থ?


প্রত্যেক প্লেয়ারের টাইপটি হয় একাত্মতার যেমন শ্রেণীভুক্ত তাহলে DefensivePlayers, OffensivePlayersঅথবা OtherPlayers, এটা বৈধভাবে সহায়ক হতে পারে একটি টাইপ যা কোড যা আশা একটি ব্যবহার করতে পারে আছে List<Player>কিন্তু এছাড়াও অন্তর্ভুক্ত সদস্যদের DefensivePlayers, OffsensivePlayersঅথবা SpecialPlayersধরনের IList<DefensivePlayer>, IList<OffensivePlayer>এবং IList<Player>। পৃথক তালিকাগুলি ক্যাশে করতে আলাদা আলাদা অবজেক্ট ব্যবহার করা যেতে পারে, তবে মূল তালিকা হিসাবে একই অবজেক্টের মধ্যে
এ্যাপসপুলেট করা

... মূল তালিকাটি পরিবর্তিত হয়েছে এবং সাব-তালিকাগুলি যখন পরবর্তী অ্যাক্সেস করা হবে তখন তাদের পুনরায় জেনারেট করা প্রয়োজন] এর ইঙ্গিত হিসাবে।
সুপারক্যাট

2
যদিও আমি তৈরি করা বিষয়টির সাথে একমত, যদিও কেউ নকশার পরামর্শ দেয় এবং কোনও ব্যবসায়ের উদ্দেশ্যে কোনও পাবলিক গেটার এবং সেটারের সাথে একটি কংক্রিটের তালিকা <T> প্রকাশের পরামর্শ দেওয়ার জন্য সত্যিই আমার প্রাণকে অশ্রু দেয় :(
সারা

38

ডিজাইন> বাস্তবায়ন

আপনি কোন পদ্ধতি এবং বৈশিষ্ট্য প্রকাশ করবেন তা হ'ল একটি ডিজাইনের সিদ্ধান্ত। আপনি কোন বেস ক্লাস থেকে উত্তরাধিকারী তা হ'ল একটি বাস্তবায়ন বিশদ। আমি মনে করি এটি পূর্বের দিকে এক পদক্ষেপ নেওয়া সার্থক।

একটি অবজেক্ট হ'ল ডেটা এবং আচরণের সংগ্রহ।

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

  • আমি যে মডেলটি তৈরি করছি তাতে এই অবজেক্টটি কী ডেটা নিয়ে গঠিত?
  • এই বস্তুটি সেই মডেলটিতে কী আচরণ করে?
  • ভবিষ্যতে কীভাবে এই পরিবর্তন হতে পারে?

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

কংক্রিটের ধরণগুলি ভাবার আগে ইন্টারফেসগুলিতে চিন্তাভাবনা বিবেচনা করুন, কারণ কিছু লোকেরা তাদের মস্তিষ্ককে "ডিজাইন মোডে" সেইভাবে রাখা সহজ করে find

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

ডিজাইন বিশেষ বিবেচনা করুন

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

ফুটবলটিম.বিপরীত () আপনার কী বোঝায়? ফুটবলটিম.কনভার্টএল << আউটপুট> () আপনার পছন্দ মতো কিছু দেখাচ্ছে?

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

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

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

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

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

আপনার মনে হতে পারে যে আপনি চান লোকেরা কেবল তাদের খেলোয়াড়দের সেট গণনা করার পরিবর্তে তাদের সাথে যোগ করতে বা তাদের সরানোর জন্য সক্ষম হতে পারে। আইনিউবারেবল <প্লেয়ার> বিবেচনা করার জন্য একটি সঠিক বৈধ বিকল্প valid

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

যে কেউ আপনাকে বলার চেষ্টা করে যে এর মধ্যে একটির ক্ষেত্রে এটি স্পষ্টত এবং যথাযথরূপে ভুল , ভুল পথে চালিত। যে কেউ আপনাকে এটিকে বলার চেষ্টা করে, তা প্রতিটি ক্ষেত্রে যথাযথভাবে এবং যথাযথভাবে সঠিক gu

বাস্তবায়নের দিকে এগিয়ে যান

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

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

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

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

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

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

সংক্ষিপ্ত উত্তর (খুব দেরী)

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


34

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

আপনি যদি লিনকিউ ব্যবহার করতে চান তবে জেনেরিক ইন্টারফেস প্রয়োগ করা যেমন আরও ICollection<T>বা IEnumerable<T>তাত্পর্যপূর্ণ।

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


30

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

এটি যৌক্তিকভাবে ভুল:

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

এবং এটি সঠিক:

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

19
এটি কেন ব্যাখ্যা করে না । ওপি জানে যে বেশিরভাগ প্রোগ্রামাররা এইভাবে অনুভব করে, কেন এটি গুরুত্বপূর্ণ তা তিনি বুঝতে পারেন না। এটি ইতিমধ্যে প্রশ্নটিতে ইতিমধ্যে তথ্য সরবরাহ করছে।
11:48

2
এই প্রথম জিনিসটিও আমি ভেবেছিলাম, কীভাবে তার ডেটা কীভাবে ভুলভাবে মডেল করা হয়েছিল। সুতরাং এর কারণ, আপনার ডেটা মডেলটি ভুল।
rball

3
তালিকা থেকে উত্তরাধিকারী হয় না কেন? কারণ তিনি আরও নির্দিষ্ট ধরণের তালিকা চান না।
মারো সাম্পিয়েট্রো

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

1
এনক্যাপসুলেশন প্রশ্নটির মূল বিষয় নয়। আমি যদি আপনি চান না যে প্রকারটি আরও সুনির্দিষ্টভাবে আচরণ করতে চান তবে কোনও প্রকার প্রসারিত না করার বিষয়ে আমি মনোনিবেশ করি। এই ক্ষেত্রগুলি সি # তে অটোপোপার্টি হতে হবে এবং অন্যান্য ভাষায় পদ্ধতি / সেট / সেট করা উচিত তবে এখানে এই প্রসঙ্গে যা একেবারে অতিশয়
মুরো সাম্পিয়েট্রো

28

ইহা পারিপার্শ্বিক অবস্থা উপর নির্ভর করে

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

অস্পষ্ট শব্দার্থক

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

ক্লাসগুলি এক্সটেনসিবল

যখন আপনি কেবলমাত্র একজন সদস্য (উদাঃ IList activePlayers) সহ একটি ক্লাস ব্যবহার করেন, আপনি প্রসঙ্গটি পরিষ্কার করার জন্য সদস্যের নাম (এবং অতিরিক্ত এটির মন্তব্য) ব্যবহার করতে পারেন। যখন অতিরিক্ত প্রসঙ্গ রয়েছে, আপনি কেবলমাত্র একটি অতিরিক্ত সদস্য যুক্ত করুন।

ক্লাসগুলি আরও জটিল

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

উপসংহার / বিবেচনা

যখন আপনার খুব নির্দিষ্ট প্রসঙ্গ থাকে, তখন কোনও দলকে খেলোয়াড়ের তালিকা হিসাবে বিবেচনা করা ঠিক হবে। উদাহরণস্বরূপ কোনও পদ্ধতির অভ্যন্তরে এটি লিখতে সম্পূর্ণ ঠিক:

IList<Player> footballTeam = ...

F # ব্যবহার করার সময়, টাইপ সংক্ষিপ্তসার তৈরি করা এমনকি ঠিক হতে পারে:

type FootballTeam = IList<Player>

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


27

আমাকে আপনার প্রশ্নটি আবার লিখতে দিন। যাতে আপনি বিষয়টিকে অন্য দৃষ্টিকোণ থেকে দেখতে পারেন।

আমার যখন কোনও ফুটবল দলের প্রতিনিধিত্ব করার দরকার হয় তখন আমি বুঝতে পারি যে এটি মূলত একটি নাম। পছন্দ: "agগলস"

string team = new string();

তারপরে আমি বুঝতে পেরেছিলাম যে দলেরও খেলোয়াড় রয়েছে।

আমি কেন কেবল স্ট্রিং ধরণের প্রসারিত করতে পারি না যাতে এটি খেলোয়াড়ের একটি তালিকাও ধারণ করে?

সমস্যাটিতে আপনার প্রবেশের বিন্দু নির্বিচারে। ভাবতে কি একটি দল নেই চেষ্টা আছে (বৈশিষ্ট্যাবলী), এটা কি না হয়

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


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

6
এটিকে দেখার জন্য এটি একটি দুর্দান্ত উপায় asএকদিকে পার্শ্ব নোটটি দয়া করে এটি বিবেচনা করুন: ধনী ব্যক্তি একাধিক ফুটবল দলের মালিক, তিনি একটি বন্ধুকে উপহার হিসাবে উপহার দেন of এবং সমস্ত খেলোয়াড়কে প্রতিস্থাপন করে। বন্ধু দল সবুজ পুরুষদের দলটির সাথে দেখা করে এবং পুরুষদের দল হেরে যাওয়ায় তিনি বলেছিলেন "আমি আপনাকে বিশ্বাস করি না যে আপনি আমাকে যে দলটি দিয়েছিলেন তার সাথে আমাকে মারধর করছে!" লোকটি কি সঠিক? আপনি কিভাবে এটি পরীক্ষা করবেন?
ব্যবহারকারী 1852503

20

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

ওপি প্রধানত List<T>: উত্তরাধিকার সূত্রে প্রাপ্ত দিকনির্দেশগুলির বিষয়ে স্পষ্টতা চেয়েছিল :

একটি গাইডলাইন বলছে যে আপনার কাছ থেকে উত্তরাধিকারী হওয়া উচিত নয় List<T>। কেন না?

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

সার্বজনীন এপিআই কী এবং আমার কেন যত্ন নেওয়া উচিত?

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

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

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

যদি আপনি ভবিষ্যতে কোনও সর্বজনীন এপিআই যোগ করেন তবে আপনার বাস্তবায়ন থেকে আপনার এপিআই বিমূর্ত করা প্রয়োজন ( List<T>সরাসরি সরাসরি প্রকাশ না করে) অথবা সম্ভাব্য ভবিষ্যতের ব্যথার সাথে নির্দেশিকাগুলি লঙ্ঘন করা উচিত।

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

প্রসঙ্গে নির্ভর করে, তবে যেহেতু আমরা 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 */
 }

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

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


18

মানুষকে বলতে দেয়

myTeam.subList(3, 5);

আদৌ কোন ধারণা আছে? যদি না হয় তবে এটি একটি তালিকা হওয়া উচিত নয়।


3
এটি যদি আপনি এটি বলে থাকেন তবেmyTeam.subTeam(3, 5);
স্যাম লিচ

3
@ সাম্যলেচ এটি সত্য বলে ধরে নিচ্ছেন, তারপরেও আপনার প্রয়োজন হবে উত্তরাধিকার নয় composition হিসাবে subListএমনকি একটি ফিরবে না Teamআর।
ক্রંચার

1
এটি আমাকে অন্য কোনও উত্তরের চেয়ে বেশি বোঝায়। +1
ফায়ারকিউজ

16

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

এটি আমার কোডটিকে অকারণে ভার্বোস করে। আমার এখন অবশ্যই আমার_টাম.প্লেয়ার্স.একটি কল করতে হবে কেবল আমার_টাম.কাউন্টের পরিবর্তে। ধন্যবাদ, সি # দিয়ে আমি সূচকে স্বচ্ছ করতে সূচকগুলি সংজ্ঞায়িত করতে পারি, এবং অভ্যন্তরীণ তালিকার সমস্ত পদ্ধতি ফরোয়ার্ড করতে পারি ... তবে এটি অনেক কোড! এই সমস্ত কাজের জন্য আমি কী পেতে পারি?

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

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

হুবহু :) আপনি বলবেন ফুটবলটিম.আড্ড (জন), ফুটবলটিম.লিস্ট.এড (জোহন) নয়। অভ্যন্তরীণ তালিকাটি দৃশ্যমান হবে না।


1
ওপি মডেল বাস্তবতা কীভাবে তা বুঝতে চায় তবে তারপরে একটি ফুটবল দলকে ফুটবল খেলোয়াড়ের তালিকা হিসাবে সংজ্ঞায়িত করে (যা ধারণাগতভাবে ভুল)। এটাই সমস্যা. অন্য কোনও যুক্তি আমার মতে তাকে বিভ্রান্ত করছে।
22:38

3
আমি একমত নই যে খেলোয়াড়ের তালিকাটি ধারণাগতভাবে ভুল। অগত্যা। এই পৃষ্ঠায় অন্য কেউ যেমন লিখেছেন, "সমস্ত মডেল ভুল, তবে কিছু দরকারী"
xpmatteo

সঠিক মডেলগুলি পাওয়া শক্ত, একবার হয়ে গেলে সেগুলি কার্যকর হয়। যদি কোনও মডেলটির অপব্যবহার করা যায় তবে এটি ধারণাগতভাবে ভুল। stackoverflow.com/a/21706411/711061
মাউরো Sampietro

15

এখানে প্রচুর চমত্কার উত্তর রয়েছে তবে আমি এমন কিছুতে স্পর্শ করতে চাই যা আমি উল্লিখিত দেখিনি: অবজেক্ট ওরিয়েন্টেড ডিজাইন হ'ল বস্তু ক্ষমতায়নের বিষয়ে

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

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

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


এনক্যাপসুলেশন সম্পর্কিত অতিরিক্ত চিন্তা ... আপনি নিম্নলিখিত উদ্বেগ উত্থাপন করেছেন:

এটি আমার কোডটিকে অকারণে ভার্বোস করে। আমার এখন অবশ্যই আমার_টাম.প্লেয়ার্স.একটি কল করতে হবে কেবল আমার_টাম.কাউন্টের পরিবর্তে।

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

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

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

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


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


12

কোনও ডাটা স্ট্রাকচার উপস্থাপনের সঠিক সি # উপায় কী ...

স্মরণকারক, "সমস্ত মডেল ভুল, তবে কিছু কার্যকর।" - জর্জ ইপি বক্স

কোনও "সঠিক উপায়" নেই, কেবল দরকারী।

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

- সম্পাদিত

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

- সংস্করণ 2

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

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

উত্তর সম্পর্কে আরও সঠিকভাবে চিন্তা করতে আমাকে সাহায্য করার জন্য @ কাইকে ধন্যবাদ জানাই।


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

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

3
"অতিরিক্ত প্রকৌশলী করবেন না you আপনি যত কম কোড লিখবেন তত কম কোডটি আপনার ডিবাগ করার দরকার হবে।" <- আমি মনে করি এটি বিভ্রান্তিকর। উত্তরাধিকারের উপর এনক্যাপসুলেশন এবং সংমিশ্রণ বেশি ইঞ্জিনিয়ারিং নয় এবং এটি ডিবাগিংয়ের জন্য আরও প্রয়োজনের কারণ হয় না। এনক্যাপসুলেট করে আপনি ক্লায়েন্টরা যেভাবে আপনার ক্লাস ব্যবহার করতে পারেন (এবং অপব্যবহার) তার সংখ্যা সীমাবদ্ধ করছেন এবং এভাবে আপনার কম প্রবেশ পয়েন্ট রয়েছে যা পরীক্ষার এবং ইনপুট বৈধতার প্রয়োজন। Listএটিকে উত্তোলন করা কারণ এটি দ্রুত এবং সহজ এবং এর ফলে কম বাগের দিকে নিয়ে যাওয়া সহজ সমাধান, এটি কেবল খারাপ ডিজাইনের এবং খারাপ ডিজাইনের ফলে "ওভার ইঞ্জিনিয়ারিং" এর চেয়ে অনেক বেশি বাগ বাড়ে।
সারা

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

11

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

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


9

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

সুতরাং আমাকে কী বলতে বাধা দেয়:

team.Players.ByName("Nicolas")

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

team.ByName("Nicolas")

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

club.Players.ByName("Nicolas")

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

team.Players.ByName("Nicolas") 

অথবা

team.ByName("Nicolas")

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


9
যথাযথ হলে গ্রহণযোগ্য প্রজ্ঞাকে চ্যালেঞ্জ করার সাহস এবং উদ্যোগ থাকা গুরুত্বপূর্ণ, যদিও আমি চ্যালেঞ্জ জানার আগে, গ্রহণযোগ্য জ্ঞানকে কেন প্রথম স্থানে গ্রহণ করা হয়েছে তা বুঝতে প্রথমে বুদ্ধিমানের কাজ বলে মনে করি। -1 কারণ "সেই নির্দেশিকা উপেক্ষা করুন!" "এই নির্দেশিকা কেন বিদ্যমান?" এর কোনও উত্তরের উত্তর নয়? ঘটনাচক্রে, সম্প্রদায়টি এই ক্ষেত্রে কেবল "আমাকে দোষ দেয়", তবে একটি সন্তোষজনক ব্যাখ্যা প্রদান করেছিল যা আমাকে রাজি করাতে সফল হয়েছিল।
সুপারবেষ্ট

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

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

2
team.ByName("Nicolas")মানে "Nicolas"দলের নাম।
স্যাম লিচ

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

8

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


রিট্রোস্পেক্টে, @ এরিকলিপার্ট এবং অন্যদের ব্যাখ্যা করার পরে, আপনি আসলে আমার প্রশ্নের API অংশের জন্য একটি দুর্দান্ত উত্তর দিয়েছেন - আপনি যা বলেছিলেন তা ছাড়াও, আমি যদি করি তবে class FootballTeam : List<FootballPlayers>আমার শ্রেণীর ব্যবহারকারীরা আমাকে বলতে সক্ষম হবেন ' থেকে উত্তরাধিকারসূত্রে করেছি List<T>, প্রতিফলন ব্যবহার দেখে List<T>পদ্ধতি একটি ফুটবল দলের জন্য মানে হয় না, এবং ব্যবহার করতে সক্ষম হচ্ছে FootballTeamমধ্যে List<T>, তাই আমি চাই ক্লায়েন্ট প্রকাশ বাস্তবায়ন বিবরণ হতে (অকারণে)।
সুপারবেষ্ট

7

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

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


4

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

class Team : IEnumerable<Player>
{
    private readonly List<Player> playerList;

    public Team()
    {
        playerList = new List<Player>();
    }

    public Enumerator GetEnumerator()
    {
        return playerList.GetEnumerator();
    }

    ...
}

class Player
{
    ...
}

3

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

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

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


3

আমি কেবল এটিকে যুক্ত করতে চেয়েছিলাম যে আইফেলের আবিষ্কারক এবং চুক্তি অনুসারে নকশাকৃত বার্ট্র্যান্ড মেয়ারের চোখের পলকের মতো ব্যাটিংয়ের মতো Teamউত্তরাধিকার সূত্রে প্রাপ্ত হবে List<Player>

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

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


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

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

2

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

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

সম্ভবত, কোনও প্লেয়ার সংগ্রহের বেটারের ধারণাটি আপনার পছন্দসই পদ্ধতির সাথে স্যুট করে?

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();
}

2

ক্লাসের চেয়ে ইন্টারফেস পছন্দ করুন

ক্লাসগুলি ক্লাস থেকে প্রাপ্ত হওয়া এড়ানো উচিত এবং পরিবর্তে প্রয়োজনীয় ন্যূনতম ইন্টারফেস প্রয়োগ করতে হবে।

উত্তরাধিকার এনক্যাপসুলেশন বিরতি দেয়

ক্লাস থেকে উত্সাহিত এনক্যাপসুলেশন বিরতি :

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

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

ক্লাসগুলি একটি বাস্তবায়ন বিশদ

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

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

ছোট ইন্টারফেসটি কোড আরও নমনীয়

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

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

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

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

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

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

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

বয়লারপ্লেট এড়ানো সম্পর্কে নোটস

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

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

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


2

সিরিয়ালাইজেশন নিয়ে সমস্যা

একটি দিক অনুপস্থিত। তালিকা <> থেকে উত্তরাধিকারী ক্লাসগুলি এক্সএমএলসিরাইজার ব্যবহার করে সঠিকভাবে সিরিয়াল করা যায় না । যে ক্ষেত্রে DataContractSerializer পরিবর্তে ব্যবহার করা আবশ্যক, অথবা একটি নিজস্ব serializing বাস্তবায়ন প্রয়োজন হয়।

public class DemoList : List<Demo>
{
    // using XmlSerializer this properties won't be seralized:
    string AnyPropertyInDerivedFromList { get; set; }     
}

public class Demo
{
    // this properties will be seralized
    string AnyPropetyInDemo { get; set; }  
}

আরও পড়ুন: তালিকা <> থেকে কোনও শ্রেণি উত্তরাধিকার সূত্রে প্রাপ্ত হলে, এক্সএমএলসিরাইজার অন্যান্য বৈশিষ্ট্যগুলিকে সিরিয়ালাইজ করে না


0

কখন তা গ্রহণযোগ্য?

এরিক লিপার্টের উদ্ধৃতি দিতে:

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

উদাহরণস্বরূপ, আপনি AddRangeপদ্ধতিটির অনুপস্থিতিতে ক্লান্ত হয়ে পড়েছেন IList<T>:

public interface IMoreConvenientListInterface<T> : IList<T>
{
    void AddRange(IEnumerable<T> collection);
}

public class MoreConvenientList<T> : List<T>, IMoreConvenientListInterface<T> { }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.