অনেকগুলি ছোট ক্লাস বনাম লজিক্যাল (তবে) জটিল উত্তরাধিকার


24

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

Class A
{
  String name;
  string description;
}

Class B
{
  String name;
  String count;
  String description;
}

Class C
{
  String name;
  String count;
  String description;
  String imageUrl;
}

Class D
{
  String name;
  String count;
}

Class E
{
  String name;
  String count;
  String imageUrl;
  String age;
}

"আরও ভাল" পাঠযোগ্যতা পাওয়ার জন্য তাদের আলাদা ক্লাসে রাখা কি আরও ভাল, তবে অনেক কোডের পুনরাবৃত্তিগুলি বুদ্ধিমান হয়, বা আরও ডিআরওয়ির জন্য উত্তরাধিকার ব্যবহার করা আরও ভাল কি?

উত্তরাধিকার ব্যবহার করে, আপনি এরকম কিছু দিয়ে শেষ করবেন তবে শ্রেণির নামগুলি এর প্রাসঙ্গিক অর্থটি হারাবে (কারণ- এ-এর কারণে নেই):

Class A
{
  String name;
  String description;
}

Class B : A
{
  String count;
}

Class C : B
{
  String imageUrl;
}

Class D : C
{
  String age;
}

আমি জানি যে উত্তরাধিকার কোড পুনরায় ব্যবহারের জন্য নয় এবং ব্যবহার করা উচিত নয়, তবে এই জাতীয় ক্ষেত্রে কোড পুনরাবৃত্তি হ্রাস করার উপায় আমি অন্য কোনও সম্ভাব্য উপায় দেখছি না।

উত্তর:


58

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

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


অবশ্যই, পরিবর্তনের কারণটি ভাল পয়েন্ট, তবে পরিস্থিতি কী, যেখানে এই ক্লাসগুলি থাকে এবং সর্বদা অবিচ্ছিন্ন থাকবে?
ব্যবহারকারী 969153

20
@ user969153: ক্লাসগুলি যখন সত্যই স্থির থাকবে তখন তাতে কিছু আসে যায় না। সমস্ত ভাল সফটওয়্যার ইঞ্জিনিয়ারিং ভবিষ্যতের রক্ষণাবেক্ষণকারীদের জন্য, যার পরিবর্তনগুলি করা দরকার। যদি ভবিষ্যতে কোনও পরিবর্তন না ঘটে, সবকিছু যায় তবে আমার উপর বিশ্বাস রাখুন, আপনি ট্র্যাশপাইলের জন্য প্রোগ্রাম না করলে আপনার সর্বদা পরিবর্তন হবে ।
thiton

@ user969153: বলা হচ্ছে, "পরিবর্তনের কারণ" হিউরিস্টিক। এটি আপনাকে সিদ্ধান্ত নিতে সহায়তা করে, আরও কিছু নয়।
thiton

2
ভাল উত্তর. পরিবর্তনের কারণগুলি হ'ল চাচা বব এর সলিউড সংক্ষিপ্ত বিবরণ যা ভাল সফ্টওয়্যার ডিজাইনে সহায়তা করবে।
ক্লি

4
@ user969153, আমার অভিজ্ঞতায়, "এই ক্লাসগুলি কোথায় এবং সর্বদা স্থির থাকবে?" বৈধ ব্যবহারের মামলা নয় :) আমি এখনও একটি অর্থপূর্ণ আকারের অ্যাপ্লিকেশন নিয়ে কাজ করতে পেরেছি যা সম্পূর্ণ অপ্রত্যাশিত পরিবর্তন অনুভব করে নি।
সিডিকেমুজ

18

উত্তরাধিকার ব্যবহার করে, আপনি এরকম কিছু দিয়ে শেষ করবেন তবে শ্রেণির নামগুলি এর প্রাসঙ্গিক অর্থটি হারাবে (কারণ- এ-এর কারণে নেই):

যথাযথভাবে। প্রসঙ্গের বাইরে এই দেখুন:

Class D : C
{
    String age;
}

একজন ডি এর কী কী সম্পত্তি রয়েছে? মনে আছে? আপনি যদি শ্রেণিবদ্ধকরণ আরও জটিল করে তোলেন:

Class E : B
{
    int numberOfWheels;
}

Class F : E
{
    String favouriteColour;
}

এবং তারপরে কী, যদি ভয়াবহতার ভয়াবহতা ঘটে, আপনি F তে কোনও চিত্রযুক্তি ক্ষেত্র যুক্ত করতে চান তবে ই তে নয়? আপনি এটি সি এবং ই থেকে প্রাপ্ত করতে পারবেন না

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

একই কারণে পণ্যগুলির একটি আইডি, নাম এবং বিবরণও ছিল। কিন্তু তারা উপাদান ছিল না, না উপাদান উপাদান ছিল। আপনি দুটি জিনিস একসাথে দেখতে পাবেন না।

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

আমি এটি দৃ strongly়ভাবে বলতে পারি না: এটি ভাল ধারণা নয়।

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

এটি ঘটেছে, শেষ পর্যন্ত, আমাদের বিবরণ ছাড়াই উপাদান ছিল। সুতরাং আমরা এই জিনিসগুলিতে নাল বর্ণনা করা শুরু। নমনীয় নয়। শূন্য. সর্বদা. টাইপ এক্স এর কোনও পণ্য ... বা পরবর্তী ওয়াই ... এবং এন

এটি লিসকোভ সাবস্টিটিউশন নীতিমালার একটি অত্যন্ত লঙ্ঘন।

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

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


4

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

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


3

ইন্টারফেসের জন্য এটি কি নয়? বিভিন্ন ফাংশন সহ তবে অনুরূপ সম্পত্তি সহ সম্পর্কিত নয় ক্লাস।

IName = Interface(IInterface)
  function Getname : String;
  property Name : String read Getname
end;

Class Dog(InterfacedObject, IName)
private
  FName : String;
  Function GetName : String;
Public
  Name : Read Getname;
end;

Class Movie(InterfacedObject, IName)
private
  FCount;
  FName : String;
  Function GetName : String;
Public
  Name : String Read Getname;
  Count : read FCount; 
end;

1

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

একাধিক উত্তরাধিকার ব্যবহার করে কীভাবে এটি সমাধান করা যায় তার একটি উদাহরণ এখানে।

trait Nameable { String name; }
trait Describable { String description; }
trait Countable { Integer count; }
trait HasImageUrl { String imageUrl; }
trait Living { String age; }

class A : Nameable, Describable;
class B : Nameable, Describable, Countable;
class C : Nameable, Describable, Countable, HasImageUrl;
class D : Nameable, Countable;
class E : Nameable, Countable, HasImageUrl, Living;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.