ইতিমধ্যে অনেক লোক উত্তর দিয়েছে। ভেবেছিলাম আমি নিজের ব্যক্তিগত দৃষ্টিভঙ্গি দেব।
একসময় আমি এমন একটি অ্যাপে কাজ করেছি (এবং এখনও করি) যা সংগীত তৈরি করে।
অ্যাপ্লিকেশন একটি বিমূর্ত ছিল 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
)।
তার একটি গাইডলাইন: আপনি যখনই একটি নতুন সাবক্লাস তৈরি করবেন তখন বিবেচনা করুন যে এটি কোনও নতুন কার্যকারিতা যুক্ত করেছে যা সুপারক্লাসে বিদ্যমান নেই। যদি এই প্রশ্নের উত্তর "না" হয় তবে আপনি সুপারক্লাসের 'টেমপ্লেটটি পূরণ' করার চেষ্টা করছেন, সেই ক্ষেত্রে কেবল একটি অবজেক্ট তৈরি করুন। (এবং সম্ভবত 'প্রিসেটগুলি' সহ একটি কারখানা, জীবনকে সহজ করার জন্য)।
আশা করি এইটি কাজ করবে.