নির্দিষ্ট দৃষ্টান্তের জন্য সাবক্লাস তৈরি করা কি খারাপ অভ্যাস?


37

নিম্নলিখিত নকশা বিবেচনা করুন

public class Person
{
    public virtual string Name { get; }

    public Person (string name)
    {
        this.Name = name;
    }
}

public class Karl : Person
{
    public override string Name
    {
        get
        {
            return "Karl";
        }
    }
}

public class John : Person
{
    public override string Name
    {
        get
        {
            return "John";
        }
    }
}

আপনি কি এখানে কিছু ভুল আছে বলে মনে করেন? আমার কাছে কার্ল এবং জন ক্লাসগুলি ক্লাসের পরিবর্তে কেবলমাত্র উদাহরণ হতে হবে কারণ তারা ঠিক একই রকম:

Person karl = new Person("Karl");
Person john = new Person("John");

যখন দৃষ্টান্তগুলি পর্যাপ্ত থাকে তখন আমি কেন নতুন ক্লাস তৈরি করব? ক্লাসগুলি উদাহরণটিতে কিছু যুক্ত করে না।


17
দুর্ভাগ্যক্রমে, আপনি প্রচুর উত্পাদন কোডে এটি পাবেন। আপনি যখন পারেন এটি পরিষ্কার করুন।
অ্যাডাম জুকারম্যান

14
এটি একটি দুর্দান্ত নকশা - যদি কোনও বিকাশকারী ব্যবসায়ের ডেটা পরিবর্তনের জন্য নিজেকে অপরিহার্য করে তুলতে চায় এবং 24/7 ;-) উপলভ্য হতে কোনও সমস্যা না হয়
ডক ব্রাউন

1
এখানে সম্পর্কিত এক ধরণের প্রশ্ন যেখানে ওপি মনে হয় প্রচলিত জ্ঞানের বিপরীতে বিশ্বাস করে। প্রোগ্রামার্স.স্ট্যাকেক্সেঞ্জঞ্জ
প্রশ্নগুলি /

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

2
লাম্বডাস জাভা 8 আসার আগে এটি জাভায় বেনামে সাবক্লাসগুলির (যেমন ইভেন্ট হ্যান্ডলারগুলির) সাথে ব্যাপকভাবে ব্যবহৃত হয় (যা বিভিন্ন সিনট্যাক্সের সাথে একই জিনিস)।
মার্জজেলম

উত্তর:


77

প্রত্যেক ব্যক্তির জন্য নির্দিষ্ট সাবক্লাস করার দরকার নেই।

আপনি ঠিক বলেছেন, পরিবর্তে সেগুলি হওয়া উচিত।

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

প্যারেন্ট ক্লাস দ্বারা সরবরাহিত কার্যকারিতা বাড়ানোর জন্য সাবক্লাসগুলি ব্যবহৃত হয় । উদাহরণস্বরূপ, আপনার থাকতে পারে:

  • একটি প্যারেন্ট ক্লাস Batteryযা Power()কিছু করতে পারে এবং একটি Voltageসম্পত্তি থাকতে পারে,

  • আর উপশ্রেণী RechargeableBattery, যা যা করতে পারেন উত্তরাধিকারী Power()এবং Voltageএছাড়াও হতে পারে, কিন্তু Recharge()ঘ।

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

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

আপনার উদাহরণে, Karlএবং Johnকোনও কিছু প্রসারিত করবেন না, বা তারা কোনও অতিরিক্ত মান সরবরাহ করবেন না: Personসরাসরি ক্লাস ব্যবহার করে আপনার ঠিক একই কার্যকারিতা থাকতে পারে । অতিরিক্ত মূল্য ছাড়াই কোডের আরও লাইন থাকা কখনই ভাল।

একটি ব্যবসায়ের ক্ষেত্রে একটি উদাহরণ

এমন কোনও ব্যবসায়ের ক্ষেত্রে কী হতে পারে যেখানে এটি কোনও নির্দিষ্ট ব্যক্তির জন্য একটি সাবক্লাস তৈরি করার পক্ষে বাস্তবে বোঝা যায়?

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

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

এই জাতীয় অ্যাপ্লিকেশনটির জন্য দরিদ্রতম মডেলের ক্লাসগুলি যেমন:

          শ্রেণীর চিত্রটি হেলেন, থমাস, মেরি এবং জিমি ক্লাস এবং তাদের সাধারণ অভিভাবক: বিমূর্ত ব্যক্তি শ্রেণি দেখায়।

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

          বর্গ চিত্রটি তিনটি শিশু সহ একটি বিমূর্ত ব্যক্তি দেখায়: বিমূর্ত হিসাবরক্ষক, একটি বিমূর্ত প্রোগ্রামার এবং জিমি।  হিসাবরক্ষকের একটি সাবক্লাস হেলেন রয়েছে, এবং প্রোগ্রামারের দুটি সাবক্লাস রয়েছে: থমাস এবং মেরি।

এখন, আপনি লক্ষ্য করেছেন যে ক্লাসটি Helenরাখা খুব বেশি কার্যকর নয়, পাশাপাশি রাখা Thomasএবং Mary: আপনার বেশিরভাগ কোড উচ্চতর স্তরে যেকোন উপায়ে কাজ করে - অ্যাকাউন্টেন্টস, প্রোগ্রামার এবং জিমির স্তরে। থমাস বা মেরি যিনি লগটি অ্যাক্সেস করতে হবে তা এসভিএন সার্ভারের কোনও যত্ন নেই — এটি কেবল প্রোগ্রামার বা অ্যাকাউন্ট্যান্ট কিনা তা জানতে হবে।

if (person is Programmer)
{
    this.AccessGranted = true;
}

সুতরাং আপনি যে ক্লাসগুলি ব্যবহার করেন না সেগুলি সরিয়ে আপনি শেষ করেন:

          শ্রেণীর চিত্রটিতে অ্যাকাউন্টেন্ট, প্রোগ্রামার এবং জিমি সাবক্লাস রয়েছে যার সাধারণ পিতাম শ্রেণি: বিমূর্ত ব্যক্তি।

"তবে আমি জিমিকে যেমন থাকি তেমন রাখতে পারি, যেহেতু সর্বদা কেবলমাত্র একজন প্রধান নির্বাহী, একজন বিগ বস - জিমি" থাকবেন, আপনি মনে করেন। তদ্ব্যতীত, জিমি আপনার কোডে প্রচুর ব্যবহৃত হয়, যা প্রকৃতপক্ষে এর চেয়ে বেশি দেখায়, আগের উদাহরণের মতো নয়:

if (person is Jimmy)
{
    this.GiveUnrestrictedAccess(); // Because Jimmy should do whatever he wants.
}
else if (person is Programmer)
{
    this.AccessGranted = true;
}

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


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

3
সংক্ষিপ্ত উত্তর প্রথমে পোস্ট করা হয়। আগের পোস্টগুলি আরও বেশি ভোট পান।
টিম বি

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

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

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

15

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

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

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


12

যখন দৃষ্টান্তগুলি পর্যাপ্ত থাকে তখন আমি কেন নতুন ক্লাস তৈরি করব?

বেশিরভাগ ক্ষেত্রে, আপনি না। আপনার উদাহরণটি সত্যিই একটি ভাল ক্ষেত্রে যেখানে এই আচরণটি আসল মান যোগ করে না।

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

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


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

@ বেনআরনসন যতক্ষণ না সম্পত্তি নিজেই আচরণের পরিবর্তন না করা হয় আপনি ওসিপি লঙ্ঘন করেন না, তবে তারা এখানে they অবশ্যই আপনি সেই সম্পত্তিটিকে এর অভ্যন্তরীণ কাজের ক্ষেত্রে ব্যবহার করতে পারেন। তবে আপনার বিদ্যমান আচরণ পরিবর্তন করা উচিত নয়! আপনার কেবল আচরণ প্রসারিত করা উচিত, উত্তরাধিকারের সাথে এটি পরিবর্তন করা উচিত নয়। অবশ্যই, প্রতিটি নিয়মের ব্যতিক্রম আছে।
ফ্যালকন

1
সুতরাং ভার্চুয়াল সদস্যদের কোন ব্যবহার একটি ওসিপি লঙ্ঘন?
বেন অ্যারনসন

3
@ ফ্যালকন পুনরাবৃত্তিমূলক জটিল কনস্ট্রাক্টর কল এড়াতে নতুন ক্লাস নেওয়া দরকার নেই। সাধারণ-ক্ষেত্রেগুলির জন্য কেবল কারখানাগুলি তৈরি করুন এবং ছোট প্রকরণকে পরামিতি করুন।
আগ্রহী

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

8

যদি এটি অনুশীলনের সীমানা হয়, তবে আমি সম্মতি জানাই এটি একটি খারাপ অভ্যাস।

জন এবং কার্লের আচরণ যদি আলাদা হয় তবে জিনিসগুলি কিছুটা পরিবর্তন হয়। এটি personএমন একটি পদ্ধতি থাকতে পারে cleanRoom(Room room)যেখানে দেখা যায় যে জন একজন দুর্দান্ত রুমমেট এবং খুব কার্যকরভাবে পরিষ্কার করেছেন, কিন্তু কার্ল নন এবং ঘরটি খুব বেশি পরিষ্কার করেন না।

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


আলাদা আচরণ নয়, ঠিক আলাদা ডেটা। ধন্যবাদ।
ইগনাসিও সোলার গার্সিয়া

6

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

জাভা উদাহরণ:

public enum Person
{
    KARL("Karl"),
    JOHN("John")

    private final String name;

    private Person(String name)
    {
        this.name = name;
    }

    public String getName()
    {
        return this.name;
    }
}

6

ইতিমধ্যে অনেক লোক উত্তর দিয়েছে। ভেবেছিলাম আমি নিজের ব্যক্তিগত দৃষ্টিভঙ্গি দেব।


একসময় আমি এমন একটি অ্যাপে কাজ করেছি (এবং এখনও করি) যা সংগীত তৈরি করে।

অ্যাপ্লিকেশন একটি বিমূর্ত ছিল Scale: বিভিন্ন উপশ্রেণী সঙ্গে বর্গ CMajor, DMinorইত্যাদি, Scaleতাই ভালো কিছু লাগছিল:

public abstract class Scale {
    protected Note[] notes;
    public Scale() {
        loadNotes();
    }
    // .. some other stuff ommited
    protected abstract void loadNotes(); /* subclasses put notes in the array
                                          in this method. */
}

সঙ্গীত জেনারেটর Scaleসঙ্গীত উত্পন্ন করতে একটি নির্দিষ্ট উদাহরণ সহ কাজ করেছিলেন । ব্যবহারকারী কোনও তালিকার থেকে কোনও স্কেল নির্বাচন করবেন, যাতে থেকে সংগীত তৈরি করতে পারে।

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

তবে আমি এটি করতে সক্ষম হইনি। এটি ছিল কারণ সমস্ত স্কেলগুলি ইতিমধ্যে সংকলনের সময় সেট করা আছে - যেহেতু তারা শ্রেণি হিসাবে প্রকাশ করা হয়। তারপর এটি আমার আঘাত:

এটি প্রায়শই 'সুপার ক্লাস এবং সাবক্লাস' এর ক্ষেত্রে বিবেচনা করা স্বজ্ঞাত। এই সিস্টেমের মাধ্যমে প্রায় সমস্ত কিছুই প্রকাশ করা যায়: সুপারক্লাস Personএবং সাবক্লাস Johnএবং Mary; সুপারক্লাস Carএবং সাবক্লাস Volvoএবং Mazda; সুপারক্লাস Missileএবং সাবক্লাস SpeedRocked, LandMineএবং TrippleExplodingThingy

এইভাবে চিন্তা করা খুব স্বাভাবিক, বিশেষত ওওতে তুলনামূলকভাবে নতুন ব্যক্তির পক্ষে।

কিন্তু আমরা সবসময় মনে রাখা উচিত শ্রেণীর টেমপ্লেট হয় , এবং বস্তু বিষয়বস্তু এই টেমপ্লেটগুলি ঢেলে হয় । আপনি টেম্পলেটটিতে যা কিছু সামগ্রী চান তা intoালতে পারবেন, অসংখ্য সম্ভাবনা তৈরি করে।

টেমপ্লেটটি পূরণ করা সাবক্লাসের কাজ নয়। এটি বস্তুর কাজ। সাবক্লাসের কাজটি হ'ল আসল কার্যকারিতা যুক্ত করা বা টেমপ্লেটটি প্রসারিত করা

এবং এজন্যই আমার Scaleএকটি Note[]ক্ষেত্র সহ একটি কংক্রিট শ্রেণি তৈরি করা উচিত ছিল এবং বস্তুগুলিকে এই টেম্পলেটটি পূরণ করতে দেওয়া উচিত ; সম্ভবত কনস্ট্রাক্টর বা কোনও কিছুর মাধ্যমে। এবং শেষ পর্যন্ত, তাই আমি করেছি।

প্রতিবার যখন আপনি কোনও ক্লাসে কোনও টেম্পলেট ডিজাইন করেন (যেমন, একটি শূন্য Note[]সদস্য যা পূরণ করা প্রয়োজন, বা একটি String nameক্ষেত্র যা একটি মূল্য নির্ধারণ করা প্রয়োজন), মনে রাখবেন যে টেমপ্লেটটি পূরণ করা এই শ্রেণীর অবজেক্টগুলির কাজ ( বা সম্ভবত যারা এই বিষয়গুলি তৈরি করে)। সাবক্লাসগুলি টেমপ্লেটগুলি পূরণ করার জন্য নয়, কার্যকারিতা যুক্ত করার জন্য।


আপনি যেমন "সুপারক্লাস Person, সাবক্লাস Johnএবং Mary" ধরণের সিস্টেম তৈরি করতে প্ররোচিত হতে পারেন কারণ আপনি যে আনুষ্ঠানিকতা চান তা পছন্দ করে like

এইভাবে, আপনি কেবল Person p = new Mary()পরিবর্তে, বলতে পারেন Person p = new Person("Mary", 57, Sex.FEMALE)। এটি জিনিসগুলিকে আরও সংগঠিত এবং আরও কাঠামোগত করে তোলে। তবে যেমনটি আমরা বলেছি, তথ্যের প্রতিটি সংমিশ্রনের জন্য একটি নতুন শ্রেণি তৈরি করা ভাল পন্থা নয়, কারণ এটি কোনও কোডের জন্য কোডটি ফুলে যায় না এবং রানটাইম সক্ষমতার ক্ষেত্রে আপনাকে সীমাবদ্ধ করে দেয়।

সুতরাং এখানে একটি সমাধান রয়েছে: একটি বেসিক কারখানা ব্যবহার করুন, এমনকি এটি একটি স্থিরও হতে পারে। তাই ভালো:

public final class PersonFactory {
    private PersonFactory() { }

    public static Person createJohn(){
        return new Person("John", 40, Sex.MALE);
    }

    public static Person createMary(){
        return new Person("Mary", 57, Sex.FEMALE);
    }

    // ...
}

এইভাবে, আপনি সহজেই 'প্রোগ্রামের সাথে আসা' 'প্রিসেটগুলি' ব্যবহার করতে পারেন, যেমন: Person mary = PersonFactory.createMary()তবে আপনি নতুন ব্যক্তিকে গতিশীলভাবে নকশার অধিকারও সংরক্ষণ করতে পারেন, উদাহরণস্বরূপ আপনি ব্যবহারকারীকে এটি করার অনুমতি দিতে চান । উদাহরণ:

// .. requesting the user for input ..
String name = // user input
int age = // user input
Sex sex = // user input, interpreted
Person newPerson = new Person(name, age, sex);

বা আরও ভাল: এরকম কিছু করুন:

public final class PersonFactory {
    private PersonFactory() { }

    private static Map<String, Person> persons = new HashMap<>();
    private static Map<String, PersonData> personBlueprints = new HashMap<>();

    public static void addPerson(Person person){
        persons.put(person.getName(), person);
    }

    public static Person getPerson(String name){
        return persons.get(name);
    }

    public static Person createPerson(String blueprintName){
        PersonData data = personBlueprints.get(blueprintName);
        return new Person(data.name, data.age, data.sex);
    }

    // .. or, alternative to the last method
    public static Person createPerson(String personName){
        Person blueprint = persons.get(personName);
        return new Person(blueprint.getName(), blueprint.getAge(), blueprint.getSex());
    }

}

public class PersonData {
    public String name;
    public int age;
    public Sex sex;

    public PersonData(String name, int age, Sex sex){
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
}

আমি বহন করলাম। আমি মনে করি আপনি ধারণা পেতে পারেন।


সাবক্লাসগুলি তাদের সুপারক্লাসগুলির দ্বারা সেট করা টেম্পলেটগুলি পূরণ করার উদ্দেশ্যে নয়। সাবক্লাসগুলি কার্যকারিতা যুক্ত করার জন্য বোঝানো হয় । অবজেক্টটি টেমপ্লেটগুলি পূরণ করার জন্য বোঝানো হয়, এটি তাদের জন্য।

আপনার ডেটাগুলির প্রতিটি সংমিশ্রণের জন্য একটি নতুন শ্রেণি তৈরি করা উচিত নয়। (ঠিক Scaleযেমনগুলির প্রতিটি সম্ভাব্য সংমিশ্রণের জন্য আমার একটি নতুন সাবক্লাস তৈরি করা উচিত হয়নি Note)।

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

আশা করি এইটি কাজ করবে.


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

@ সোমোস খুশি আমি সহায়তা করতে পারে।
আভিভ কোহন

2

সামান্য চরম হলেও - এটি এখানে 'হওয়া উচিত উদাহরণগুলির' ব্যতিক্রম।

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


2

ডুপ্লিকেট কোড থাকা খারাপ অভ্যাস হিসাবে বিবেচিত ।

এটি কমপক্ষে আংশিক কারণ কোডের লাইন এবং অতএব কোডবেজের আকার রক্ষণাবেক্ষণ ব্যয় এবং ত্রুটিগুলির সাথে সম্পর্কিত

এই বিশেষ বিষয়ে আমার কাছে প্রাসঙ্গিক সাধারণ জ্ঞানের যুক্তি এখানে:

1) আমার যদি এটি পরিবর্তন করার দরকার হয় তবে আমার কয়টি জায়গায় যেতে হবে? কম এখানে ভাল।

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

3) এইভাবে বোঝা কি পরিষ্কার এবং সহজ? আবার এটি আপনার উদাহরণে নেই - তবে কিছু উত্তরাধিকারের ধরণ রয়েছে যা বিচ্ছিন্নতর শ্রেণিগুলি বজায় রাখা সহজতর হয় (কমান্ডের কিছু ব্যবহার বা কৌশল নিদর্শনগুলি মাথায় আসে) be


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

পয়েন্ট # 2 দেখুন। মাঝে মাঝে অবশ্যই এর কারণ রয়েছে। এজন্য কারও কোড বের করার আগে আপনাকে জিজ্ঞাসা করতে হবে।
ডিসিগ্রিগরিয়া

0

একটি ব্যবহারের কেস রয়েছে: নিয়মিত অবজেক্ট হিসাবে কোনও ফাংশন বা পদ্ধতিতে একটি রেফারেন্স গঠন।

আপনি এটি জাভা জিইউআই কোডটিতে দেখতে পারেন:

ActionListener a = new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {
        /* ... */
    }
};

সংকলক একটি নতুন বেনামে সাবক্লাস তৈরি করে এখানে আপনাকে সহায়তা করে।

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