এসআরপি কোনও অনিশ্চিত শর্তে বলেছে যে কোনও শ্রেণীর পরিবর্তনের একমাত্র কারণ থাকতে হবে।
প্রশ্নটিতে "প্রতিবেদন" শ্রেণিটি ডিকনস্ট্রাক্ট করে এর তিনটি পদ্ধতি রয়েছে:
printReport
getReportData
formatReport
অপ্রয়োজনীয় Report
প্রতিটি পদ্ধতিতে ব্যবহৃত হচ্ছে তা উপেক্ষা করে এটি এসআরপি লঙ্ঘন করে তা সহজেই দেখা যায়:
"মুদ্রণ" শব্দটি কোনও ধরণের ইউআই বা প্রকৃত মুদ্রক বোঝায়। এই শ্রেণিতে তাই কিছু পরিমাণে ইউআই বা উপস্থাপনা যুক্তি রয়েছে। ইউআই প্রয়োজনীয়তাগুলিতে পরিবর্তনের জন্য Report
শ্রেণিতে পরিবর্তন প্রয়োজন ।
"ডেটা" শব্দটি কোনও ধরণের ডেটা স্ট্রাকচারকে বোঝায়, তবে আসলে কী (এক্সএমএল? জেএসএন? সিএসভি?) নির্দিষ্ট করে না। নির্বিশেষে, যদি প্রতিবেদনের "বিষয়বস্তু" কখনও পরিবর্তন হয়, তবে এই পদ্ধতিটিও তাই ঘটবে। একটি ডেটাবেস বা একটি ডোমেন জুড়ে আছে।
formatReport
সাধারণভাবে একটি পদ্ধতির জন্য কেবল একটি ভয়ঙ্কর নাম, তবে আমি এটি দেখে এটি ধরে নিয়ে অনুমান করি যে এটির আবারও ইউআইয়ের সাথে কিছু করার আছে, এবং সম্ভবত ইউআইর একটি ভিন্ন দিক রয়েছে printReport
। সুতরাং, অন্য, পরিবর্তন সম্পর্কিত সম্পর্কহীন কারণ।
সুতরাং এই এক বর্গটি সম্ভবত কোনও লগ, ফাইল স্ক্রিন / প্রিন্টার ডিভাইস এবং লগ বা ফাইল আউটপুট বা হোয়াট নোটের জন্য কিছু অভ্যন্তরীণ ফর্ম্যাট যুক্ত যুক্তিযুক্ত led একটি শ্রেণিতে তিনটি ক্রিয়াকলাপ করে, আপনি নির্ভরতার সংখ্যাকে গুণ করে এবং কোনও নির্ভরতা বা প্রয়োজনীয় পরিবর্তন এই শ্রেণিটি (বা এর উপর নির্ভর করে এমন কিছু) ভেঙে ফেলার সম্ভাবনা ত্রিগুণ করে দিচ্ছে।
এখানে সমস্যার একটি অংশ হ'ল আপনি একটি বিশেষভাবে কাঁটাযুক্ত উদাহরণ বেছে নিয়েছেন। আপনার সম্ভবত একটি ক্লাস বলা উচিত নয় Report
, এমনকি যদি এটি কেবল একটি জিনিস করে , কারণ ... কী রিপোর্ট? সমস্ত ডেটা এবং বিভিন্ন প্রয়োজনীয়তার উপর ভিত্তি করে সমস্ত "প্রতিবেদনগুলি" সম্পূর্ণ আলাদা জন্তু নয়? এবং প্রতিবেদনটি এমন কিছু নয় যা ইতিমধ্যে ফর্ম্যাট হয়েছে, না হয় পর্দার জন্য বা মুদ্রণের জন্য?
তবে, IncomeStatement
অতীতটি দেখুন, এবং একটি অনুমানের কংক্রিটের নামটি তৈরি করুন - আসুন একে কল করুন (একটি খুব সাধারণ প্রতিবেদন) - একটি যথাযথ "এসআরপিড" আর্কিটেকচারের তিন প্রকার থাকবে:
IncomeStatement
- ডোমেন এবং / অথবা মডেল শ্রেণিতে ফর্ম্যাট প্রতিবেদনে প্রদর্শিত তথ্য এবং / অথবা গণনা করে ।
IncomeStatementPrinter
, যা সম্ভবত কিছু মানক ইন্টারফেস বাস্তবায়ন করবে IPrintable<T>
। একটি কী পদ্ধতি আছে Print(IncomeStatement)
এবং মুদ্রণ-নির্দিষ্ট সেটিংস কনফিগার করার জন্য হয়ত কিছু অন্যান্য পদ্ধতি বা বৈশিষ্ট্য রয়েছে।
IncomeStatementRenderer
, যা স্ক্রিন রেন্ডারিং পরিচালনা করে এবং প্রিন্টার শ্রেণীর সাথে খুব মিল।
আপনি শেষ পর্যন্ত আরও বৈশিষ্ট্য-নির্দিষ্ট ক্লাস যুক্ত করতে পারেন IncomeStatementExporter
/ IExportable<TReport, TFormat>
।
জেনেরিকস এবং আইওসি পাত্রে প্রবর্তন করে এটি আধুনিক ভাষাগুলিতে উল্লেখযোগ্যভাবে সহজ হয়েছে। আপনার বেশিরভাগ অ্যাপ্লিকেশন কোডের নির্দিষ্ট IncomeStatementPrinter
শ্রেণীর উপর নির্ভর করার দরকার নেই , এটি কোনও প্রকারের মুদ্রণযোগ্য প্রতিবেদন ব্যবহার করে IPrintable<T>
এবং পরিচালনা করতে পারে , যা আপনাকে কোনও পদ্ধতির সাথে বেস ক্লাসের সমস্ত উপলব্ধ সুবিধা দেয় এবং সাধারণ এসআরপি লঙ্ঘনের কোনও কিছুই দেয় না gives । আইওসি ধারক নিবন্ধনে প্রকৃত বাস্তবায়ন কেবল একবার ঘোষণা করা দরকার।Report
print
কিছু লোক, যখন উপরোক্ত ডিজাইনের মুখোমুখি হয়, তখন এমন কিছু দিয়ে প্রতিক্রিয়া জানায়: "তবে এটি প্রক্রিয়াগত কোডের মতো দেখায়, এবং ওওপির পুরো পয়েন্টটি আমাদের - ডেটা এবং আচরণের পৃথকীকরণ থেকে পেতে হয়েছিল!" যা আমি বলি: ভুল ।
IncomeStatement
হয় না শুধু "তথ্য", এবং উপরোক্ত ভুল কি তারা একটি "স্বচ্ছ" শ্রেণী তৈরি করে কিছু ভুল করছেন এবং পরবর্তীকালে মধ্যে সম্পর্কহীন কার্যকারিতা সব ধরণের জ্যামিং শুরু অনুভব করতে গলি লোকেরা অনেক ঘটে IncomeStatement
, (ভাল যে এবং সাধারণ অলসতা)। এই শ্রেণিটি কেবল ডেটা হিসাবে শুরু হতে পারে তবে সময়ের সাথে সাথে গ্যারান্টিযুক্ত এটি আরও একটি মডেল হিসাবে শেষ হবে ।
উদাহরণস্বরূপ, একটি আসল আয়ের বিবরণীতে মোট আয় , মোট ব্যয় এবং নেট আয়ের লাইন রয়েছে। একটি সঠিকভাবে ডিজাইন করা আর্থিক ব্যবস্থা সম্ভবত এগুলি সংরক্ষণ করবে না কারণ এগুলি লেনদেনের ডেটা নয় - আসলে, নতুন ট্রানজেকশনাল ডেটা সংযোজনের ভিত্তিতে এগুলি পরিবর্তিত হয়। যাইহোক, এই লাইনের গণনা সর্বদা হুবহু একই হতে চলেছে, আপনি প্রতিবেদনটি মুদ্রণ, রেন্ডারিং বা রফতানি করছেন তা নির্বিশেষে। সুতরাং আপনার IncomeStatement
বর্গ আকারে এটি আচরণের ন্যায্য পরিমাণ আছে যাচ্ছে getTotalRevenues()
, getTotalExpenses()
এবং getNetIncome()
পদ্ধতি, এবং সম্ভবত কয়েক অন্যদের। এটি সত্যই অনেক কিছু "না" বলে মনে হয় না, এমনকি এটি তার নিজস্ব আচরণের সাথে একটি খাঁটি OOP- শৈলীযুক্ত বস্তু।
কিন্তু পদ্ধতি format
এবং print
পদ্ধতিগুলির সাথে তাদের তথ্যের সাথে কোনও সম্পর্ক নেই। প্রকৃতপক্ষে, এটি খুব সম্ভবত সম্ভাবনা নেই যে আপনি এই পদ্ধতিগুলির বেশ কয়েকটি বাস্তবায়ন করতে চাইবেন , উদাহরণস্বরূপ ম্যানেজমেন্টের জন্য একটি বিশদ বিবৃতি এবং শেয়ারহোল্ডারদের জন্য একটি অত-বিবৃত বিবৃতি। এই স্বতন্ত্র ফাংশনগুলিকে বিভিন্ন শ্রেণিতে বিভক্ত করা আপনাকে রানটাইমের সময় এক-আকারের সমস্ত print(bool includeDetails, bool includeSubtotals, bool includeTotals, int columnWidth, CompanyLetterhead letterhead, ...)
পদ্ধতির বোঝা ছাড়াই বিভিন্ন বাস্তবায়ন চয়ন করার ক্ষমতা দেয় gives ইশ!
আশা করি আপনি দেখতে পাচ্ছেন উপরোক্ত, বৃহত্তর-পরামিতি পদ্ধতিটি কোথায় ভুল হয়েছে এবং যেখানে পৃথক বাস্তবায়ন সঠিকভাবে চলেছে; একক-অবজেক্টের ক্ষেত্রে, প্রতিবার মুদ্রণ যুক্তিতে আপনি একটি নতুন কুঁচকে যুক্ত করার সময় আপনাকে নিজের ডোমেন মডেলটি পরিবর্তন করতে হবে ( ফিন ইন ইন ফিনান্স পৃষ্ঠা নম্বর চায় তবে কেবলমাত্র অভ্যন্তরীণ প্রতিবেদনে, আপনি কি এটি যুক্ত করতে পারেন? ) পরিবর্তে এক বা দুটি স্যাটেলাইট ক্লাসে একটি কনফিগারেশন সম্পত্তি যুক্ত করুন।
এসআরপি যথাযথভাবে প্রয়োগ করা নির্ভরতা পরিচালনার বিষয়ে । এক কথায়, যদি একটি বর্গ ইতিমধ্যে কিছু দরকারী যায় আর তা আপনাকে অন্য পদ্ধতি (যেমন একটি UI 'তে, একটি প্রিন্টার, একটি নেটওয়ার্ক, একটি ফাইল যাই হোক না কেন হিসাবে) একটি নতুন নির্ভরতা পরিচয় করিয়ে দিতে হবে যোগ বিবেচনা করা হয়, না । পরিবর্তে নতুন ক্লাসে আপনি এই কার্যকারিতাটি কীভাবে যুক্ত করতে পারেন এবং কীভাবে আপনি এই সামগ্রিক আর্কিটেকচারে এই নতুন বর্গটি ফিট করতে পারেন তা চিন্তা করুন (আপনি নির্ভরতা ইনজেকশনের আশেপাশে যখন নকশা করেন তখন এটি বেশ সহজ)। এটাই হ'ল সাধারণ নীতি / প্রক্রিয়া।
পার্শ্ব দ্রষ্টব্য: রবার্টের মতো আমিও স্পষ্টতই এই ধারণাটি প্রত্যাখ্যান করি যে কোনও এসআরপি-কমপ্লায়েন্ট শ্রেণিতে কেবল একটি বা দুটি রাষ্ট্রীয় ভেরিয়েবল থাকা উচিত। এই ধরনের একটি পাতলা মোড়ক খুব কমই সত্যিকারের দরকারী কিছু আশা করা যেতে পারে। সুতরাং এটি দিয়ে ওভারবোর্ডে যাবেন না।