যখনই আমি এমন কোনও পদ্ধতি দেখি যেখানে আচরণটি তার প্যারামিটারের ধরণের দিকে চলে যায়, আমি অবিলম্বে প্রথমে বিবেচনা করি যদি সেই পদ্ধতিটি আসলে পদ্ধতি প্যারামিটারের অন্তর্ভুক্ত হয়। উদাহরণস্বরূপ, এর পরিবর্তে কোনও পদ্ধতি থাকার পরিবর্তে:
public void sort(List values) {
if (values instanceof LinkedList) {
// do efficient linked list sort
} else { // ArrayList
// do efficient array list sort
}
}
আমি এটি করব:
values.sort();
// ...
class ArrayList {
public void sort() {
// do efficient array list sort
}
}
class LinkedList {
public void sort() {
// do efficient linked list sort
}
}
আমরা আচরণটি সেই জায়গায় স্থানান্তর করি যা জানে কখন এটি ব্যবহার করতে হয়। আমরা একটি বাস্তব বিমূর্ততা তৈরি করি যেখানে আপনাকে প্রয়োগের ধরণ বা বিশদ জানার দরকার নেই। আপনার পরিস্থিতির জন্য, এই পদ্ধতিটি O
টাইপ করে টাইপ করে A
ওভাররাইড করতে মূল ক্লাসটি (যা আমি ডাকব ) থেকে এই পদ্ধতিটি সরিয়ে নেওয়া আরও বুদ্ধিমান হতে পারে B
। পদ্ধতি বলা হয় তাহলে doIt
কিছু বস্তুর উপর সরানো doIt
থেকে A
বিভিন্ন আচরণ সঙ্গে এবং ওভাররাইড B
। doIt
মূলত যেখানে বলা হয় সেখান থেকে যদি ডেটা বিট থাকে বা পদ্ধতিটি যথেষ্ট জায়গায় ব্যবহার করা হয় তবে আপনি মূল পদ্ধতিটি ছেড়ে দিয়ে প্রতিনিধি দিতে পারেন:
class O {
int x;
int y;
public void doIt(A a) {
a.doIt(this.x, this.y);
}
}
যদিও আমরা কিছুটা গভীর ডুব দিতে পারি। এর পরিবর্তে বুলিয়ান প্যারামিটারটি ব্যবহার করার পরামর্শটি দেখুন এবং আমরা দেখুন যে আপনার সহকর্মী কীভাবে ভাবছেন সে সম্পর্কে আমরা কী শিখতে পারি। তাঁর প্রস্তাবটি হ'ল:
public void doIt(A a, boolean isTypeB) {
if (isTypeB) {
// do B stuff
} else {
// do A stuff
}
}
এটি instanceof
আমার প্রথম উদাহরণে আমি যেমন ব্যবহার করেছি এর মতো একটি ভয়াবহ দেখাচ্ছে , আমরা সেই চেকটিকে বহিরাগত করছি। এর অর্থ হ'ল আমাদের এটি দুটি উপায়ে একটিতে কল করতে হবে:
o.doIt(a, a instanceof B);
বা:
o.doIt(a, true); //or false
প্রথম উপায়ে, কল পয়েন্টে এটি কী ধরণের রয়েছে তার কোনও ধারণা নেই A
। সুতরাং, আমাদের কি সমস্তভাবে নীচে বুলিয়ানগুলি দিয়ে যাওয়া উচিত? আমরা কি কোড বেস জুড়েই এটি চাই একটি সত্যই? আমাদের যদি কোনও তৃতীয় ধরণের অ্যাকাউন্টের প্রয়োজন হয় তবে কী হবে? যদি এই পদ্ধতিটি এইভাবে বলা হয়, আমাদের উচিত এটি এটিকে টাইপের দিকে নিয়ে যাওয়া এবং সিস্টেমটি বহির্মুখীভাবে আমাদের জন্য প্রয়োগটি বেছে নিতে দিন।
দ্বিতীয় উপায়ে, আমাদের অবশ্যইa
কল পয়েন্টে এর প্রকারটি জানতে হবে । সাধারণত এর মানে হল আমরা হয় সেখানে উদাহরণ তৈরি করছি, বা পরামিতি হিসাবে সেই ধরণের একটি উদাহরণ নিচ্ছি। একটি পদ্ধতি তৈরি করা হচ্ছে O
একটি সময় লাগে B
কাজ করবে এখানে। সংকলকটি জানতে পারে কোন পদ্ধতিটি বেছে নিতে হবে। আমরা যখন এই জাতীয় পরিবর্তনের মধ্য দিয়ে গাড়ি চালাচ্ছি তখন ভুল বিমূর্ততা তৈরি করার চেয়ে সদৃশ হওয়া ভাল , যতক্ষণ না আমরা সত্যই কোথায় যাচ্ছি তা নির্ধারণ না করা পর্যন্ত। অবশ্যই, আমি পরামর্শ দিচ্ছি যে আমরা এই পর্যায়ে যা পরিবর্তন করেছি তা বিবেচনা করেই আমরা আসলেই করা হয়নি।
A
এবং এর মধ্যে সম্পর্কের দিকে আমাদের আরও নিবিড়ভাবে নজর দেওয়া দরকার B
। সাধারণত, আমাদের বলা হয় যে উত্তরাধিকারের তুলনায় আমাদের রচনাটির পক্ষে হওয়া উচিত । এটি প্রতিটি ক্ষেত্রেই সত্য নয়, তবে একবার খনন করার পরে অবাক করা সংখ্যক ক্ষেত্রে এটি সত্য B
inher উত্তরাধিকার সূত্রে প্রাপ্ত A
, যার অর্থ আমরা বিশ্বাস করি B
এটি একটি A
। এটি কিছুটা ভিন্নভাবে কাজ করে, B
ঠিক A
তেমন ব্যবহার করা উচিত । কিন্তু এই পার্থক্য কি? আমরা কি পার্থক্যগুলিকে আরও দৃ concrete় নাম দিতে পারি? এটি কি B
একটি নয় A
, তবে সত্যিই A
এটি X
হতে পারে A'
বা হতে পারে B'
? আমরা যদি তা করি তবে আমাদের কোডটি কেমন হবে?
আমরা সম্মুখের দিকে পদ্ধতি সরানো তাহলে A
যেমন তার আগে প্রস্তাবিত, আমরা একটি দৃষ্টান্ত উদ্বুদ্ধ পারে X
মধ্যে A
, এবং যে পদ্ধতি প্রতিনিধি X
:
class A {
X x;
A(X x) {
this.x = x;
}
public void doIt(int x, int y) {
x.doIt(x, y);
}
}
আমরা বাস্তবায়ন করতে পারে A'
এবং B'
এবং পরিত্রাণ পেতে B
। আমরা এমন ধারণাকে একটি নাম দিয়ে কোডটির উন্নতি করেছি যা সম্ভবত আরও অন্তর্নিহিত হতে পারে এবং সংকলনের পরিবর্তে রানটাইম এ আচরণটি সেট করার অনুমতি দিয়েছিল। A
আসলেও কম বিমূর্ত হয়ে উঠেছে। বর্ধিত উত্তরাধিকার সম্পর্কের পরিবর্তে, এটি কোনও প্রতিনিধিত্ব করা অবজেক্টের জন্য পদ্ধতিগুলি কল করছে। এই অবজেক্টটি বিমূর্ত, তবে কেবল বাস্তবায়নের পার্থক্যের উপর আরও বেশি কেন্দ্রীভূত।
যদিও দেখার জন্য একটি শেষ জিনিস আছে। আসুন আপনার সহকর্মীর প্রস্তাবটিতে ফিরে আসুন। যদি সমস্ত কল সাইটগুলিতে আমরা স্পষ্টভাবে আমাদের ধরণের প্রকারটি জানতে A
পারি তবে আমাদের উচিত এইরকম কল করা:
B b = new B();
o.doIt(b, true);
আমরা ধরে নিয়েছিলাম যখন এটি রচনা করার সময় A
এর একটি X
হয় A'
বা হয় B'
। তবে এমনকি এই অনুমানটিও সঠিক নয়। এই একমাত্র স্থান যেখানে এই পার্থক্য A
এবং B
বিষয়গুলির মধ্যে পার্থক্য রয়েছে ? যদি এটি হয়, তবে সম্ভবত আমরা কিছুটা ভিন্ন পদ্ধতির গ্রহণ করতে পারি। আমাদের এখনও একটি আছে X
যা হয় A'
বা হয় B'
তবে এটি এর সাথে সম্পর্কিত নয় A
। কেবল O.doIt
এটির জন্য যত্নশীল, সুতরাং আসুন কেবল এটির কাছে প্রেরণ করুন O.doIt
:
class O {
int x;
int y;
public void doIt(A a, X x) {
x.doIt(a, x, y);
}
}
এখন আমাদের কল সাইটটি দেখে মনে হচ্ছে:
A a = new A();
o.doIt(a, new B'());
আবার, B
অদৃশ্য হয়ে যায় এবং বিমূর্তি আরও বেশি কেন্দ্রীভূত হয় X
। এবার যদিও A
কম জেনেও সরল। এটি এমনকি কম বিমূর্ত।
একটি কোড বেসে সদৃশ হ্রাস করা গুরুত্বপূর্ণ, তবে কেন নকলটি প্রথম স্থানে ঘটে তা আমাদের অবশ্যই বিবেচনা করা উচিত। সদৃশ হ'ল গভীর বিমূর্তির লক্ষণ হতে পারে যা বেরিয়ে যাওয়ার চেষ্টা করছে।