কেবল একটি সিস্টেম জটিল হওয়ার অর্থ এই নয় যে আপনাকে এটিকে জটিল করে তুলতে হবে । আপনার যদি এমন কোনও শ্রেণি থাকে যা এর মতো অনেক বেশি নির্ভরশীলতা (বা সহযোগী) থাকে:
public class MyAwesomeClass {
public class MyAwesomeClass(IDependency1 _d1, IDependency2 _d2, ... , IDependency20 _d20) {
// Assign it all
}
}
... তাহলে এটি খুব জটিল হয়ে গেল এবং আপনি সত্যই এসআরপি অনুসরণ করছেন না , আপনি কি? আমি বাজি ধরতাম যদি আপনি সিআরসি কার্ডে যা লিখে MyAwesomeClass
থাকেন তা এটি কোনও সূচক কার্ডের সাথে খাপ খায় না বা আপনাকে সত্যিই ছোট ছোট অযৌক্তিক অক্ষরে লিখতে হয়।
আপনার এখানে যা আছে তা হ'ল আপনার ছেলেরা কেবল তার পরিবর্তে কেবল ইন্টারফেস বিভাজন নীতি অনুসরণ করেছিল এবং এটিকে চূড়ান্তভাবে নিয়ে গেছে তবে এটি সম্পূর্ণ অন্য গল্প। আপনি যুক্তি দিতে পারেন যে নির্ভরতাগুলি হ'ল ডোমেন অবজেক্ট (যা ঘটে) তবে এমন একটি ক্লাস থাকা যা একই সাথে 20 ডোমেন অবজেক্ট পরিচালনা করে এটি কিছুটা দূরে প্রসারিত করে।
টিডিডি আপনাকে ক্লাস কতটা করে দেয় তার একটি ভাল সূচক সরবরাহ করবে। কথায় কথায় রাখি; যদি কোনও পরীক্ষার পদ্ধতিতে সেটআপ কোড থাকে যা চিরকালের জন্য লিখতে লাগে (আপনি যদি পরীক্ষাগুলি পুনরায় সংশোধন করেও যান) তবে আপনার MyAwesomeClass
সম্ভবত খুব বেশি কিছু করার দরকার আছে।
সুতরাং আপনি এই ধাঁধাটি কীভাবে সমাধান করবেন? আপনি অন্যান্য ক্লাসে দায়িত্ব স্থানান্তর। এই শ্রেণীর ক্লাসে আপনি নিতে পারেন এমন কিছু পদক্ষেপ রয়েছে:
- আপনার শ্রেণি নির্ভরতাগুলির সাথে করে এমন সমস্ত ক্রিয়া (বা দায়িত্ব) সনাক্ত করুন)
- ঘনিষ্ঠভাবে সম্পর্কিত নির্ভরতা অনুযায়ী ক্রিয়াগুলি গ্রুপ করুন।
- Redelegate! অর্থ্যাপি নতুন বা (আরও গুরুত্বপূর্ণভাবে) অন্য শ্রেণিতে প্রতিটি চিহ্নিত ক্রিয়াকলাপের রিফ্যাক্টর।
রিফ্যাক্টরিংয়ের দায়িত্বগুলির একটি বিমূর্ত উদাহরণ
যাক C
একটি বর্গ বিভিন্ন নির্ভরতা যে হতে D1
, D2
, D3
, D4
আপনি কম ব্যবহার করতে refactor করা প্রয়োজন। যখন আমরা সনাক্ত করি যে কোন পদ্ধতিগুলি C
নির্ভরতাগুলিতে কল করে আমরা এটির একটি সহজ তালিকা তৈরি করতে পারি:
D1
- performA(D2)
,performB()
D2
- performD(D1)
D3
- performE()
D4
- performF(D3)
তালিকার দিকে তাকিয়ে আমরা দেখতে পাচ্ছি D1
এবং D2
একে অপরের সাথে সম্পর্কিত কারণ শ্রেণিটির একরকম তাদের একসাথে প্রয়োজন। আমরা সেই D4
প্রয়োজনগুলিও দেখতে পারি D3
। সুতরাং আমাদের দুটি গ্রুপিং রয়েছে:
Group 1
- D1
<->D2
Group 2
- D4
->D3
গ্রুপিংগুলি এমন একটি সূচক যা ক্লাসে এখন দুটি দায়িত্ব রয়েছে।
Group 1
- কলিং দুটি অবজেক্টের একে অপরের প্রয়োজন হ্যান্ডলিংয়ের জন্য একটি। হতে পারে আপনি আপনার শ্রেণিকে C
উভয় নির্ভরতা হ্যান্ডেল করার প্রয়োজনটিকে দূর করতে এবং তার পরিবর্তে সেই কলগুলি পরিচালনা করার মধ্যে একটিতে ছেড়ে যেতে পারেন। এই গোষ্ঠীকরণের ক্ষেত্রে এটি স্পষ্টতই D1
উল্লেখ করা যেতে পারে D2
।
Group 2
- অন্য দায়বদ্ধতার জন্য অন্যকে কল করার জন্য একটি বিষয় প্রয়োজন। আপনার ক্লাসের পরিবর্তে D4
হ্যান্ডেল করতে পারবেন না D3
? তারপরে আমরা সম্ভবত কলগুলি না করে D3
ক্লাস থেকে বাদ C
দিতে D4
পারি।
আমার উত্তরটিকে প্রস্তর হিসাবে সেট করবেন না কারণ উদাহরণটি খুব বিমূর্ত এবং প্রচুর অনুমান করে। আমি দৃ sure়ভাবে নিশ্চিত যে এর রিফ্যাক্টর করার আরও অনেক উপায় রয়েছে তবে কমপক্ষে পদক্ষেপগুলি আপনাকে ক্লাস বিভক্ত করার পরিবর্তে দায়িত্বগুলি সরিয়ে নেওয়ার জন্য কোনও প্রক্রিয়া পেতে সহায়তা করতে পারে।
সম্পাদনা:
@ ইমাদ কারেমের মন্তব্যগুলির মধ্যে রয়েছে :
"যদি আপনার শ্রেণীর কনস্ট্রাক্টরে 20 টি প্যারামিটার থাকে তবে এটি আপনার শোনায় না যে আপনার দলটি এসআরপি কী তা বেশ ভাল জানে। গ্রাহক শ্রেণি রয়েছে, কনস্ট্রাক্টরে 20 টি পরামিতি থাকা আশ্চর্যজনক নয়।
এটি সত্য যে ডিএও অবজেক্টগুলির প্রচুর পরিমাণ প্যারামিটার থাকে, যা আপনাকে আপনার নির্মাত্রে সেট করতে হবে এবং পরামিতিগুলি সাধারণত স্ট্রিংয়ের মতো সাধারণ ধরণের। তবে কোনও Customer
শ্রেণীর উদাহরণে , আপনি বিষয়গুলি আরও সহজ করে তুলতে এখনও অন্যান্য শ্রেণীর মধ্যে এর বৈশিষ্ট্যগুলি গোষ্ঠীভুক্ত করতে পারেন। যেমন Address
রাস্তাগুলির সাথে একটি ক্লাস এবং একটি Zipcode
ক্লাস থাকা যাতে জিপকোড থাকে এবং ব্যবসার যুক্তি যেমন ডেটা বৈধকরণকেও পরিচালনা করবে:
public class Address {
private String street1;
//...
private Zipcode zipcode;
// easy to extend
public bool isValid() {
return zipcode.isValid();
}
}
public class Zipcode {
private string zipcode;
public bool isValid() {
// return regex match that zipcode contains numbers
}
}
এই জিনিসটি ব্লগ পোস্টে আরও আলোচনা করা হয়েছে "জাভাতে কখনও কখনও না, কখনও স্ট্রিং ব্যবহার করবেন না (বা প্রায়শই কমপক্ষে)" । সাব-অবজেক্টগুলি তৈরি করা সহজ করার জন্য কনস্ট্রাক্টর বা স্ট্যাটিক পদ্ধতি ব্যবহারের বিকল্প হিসাবে আপনি একটি তরল নির্মাতা প্যাটার্ন ব্যবহার করতে পারেন ।