এসআরপি বাস্তবায়নের ব্যবহারিক উপায়গুলি কী কী?


11

কেবল কোনও শ্রেণি একক দায়িত্বের নীতি লঙ্ঘন করে কিনা তা পরীক্ষা করার জন্য লোকেদের ব্যবহারিক কৌশলগুলি কী?

আমি জানি যে একটি শ্রেণীর পরিবর্তনের কেবল একটি কারণ থাকতে হবে, তবে সেই বাক্যটির সত্যিকার অর্থে এটি বাস্তবায়নের জন্য কিছুটা ব্যবহারিক উপায় নেই।

আমি খুঁজে পেলাম একমাত্র উপায়টি "দি ......... উচিত ......... নিজেই" বাক্যটি ব্যবহার করা। যেখানে প্রথম স্থানটি শ্রেণীর নাম এবং পরে পদ্ধতি (দায়িত্ব) নাম।

তবে, কখনও কখনও কোনও দায়িত্ব যদি এসআরপি লঙ্ঘন করে তবে তা নির্ধারণ করা শক্ত hard

এসআরপি চেক করার আরও কি উপায় আছে?

বিঃদ্রঃ:

প্রশ্নটি এসআরপি বলতে কী বোঝায় তা নয়, বরং একটি ব্যবহারিক পদ্ধতি বা এসআরপি যাচাই ও বাস্তবায়নের জন্য বিভিন্ন পদক্ষেপের একটি সিরিজ।

হালনাগাদ

রিপোর্ট ক্লাস

আমি একটি নমুনা শ্রেণি যুক্ত করেছি যা স্পষ্টভাবে এসআরপি লঙ্ঘন করে। লোকেরা কীভাবে একক দায়বদ্ধতার নীতিটি তারা গ্রহণ করে তা বোঝাতে উদাহরণ হিসাবে এটি ব্যবহার করতে পারলে দুর্দান্ত হবে।

উদাহরণ এখান থেকে ।


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

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

আপনি যদি সত্যই এসআরপি বুঝতে চান তবে আঙ্কেল বব মার্টিনের কিছু লেখা পড়ুন। তার কোডটি আমি দেখেছি এমন কিছু সুন্দর যা আমি দেখেছি এবং আমি বিশ্বাস করি যে তিনি এসআরপি সম্পর্কে যা কিছু বলেন তা কেবলমাত্র দৃ sound় পরামর্শই নয়, কেবল হাত-avingেউয়ের চেয়েও বেশি।
রবার্ট হার্ভে

এবং নীচের ভোটাররা দয়া করে কেন পোস্টটির উন্নতি করবেন তা ব্যাখ্যা করবেন ?!
সানগো

উত্তর:


7

এসআরপি কোনও অনিশ্চিত শর্তে বলেছে যে কোনও শ্রেণীর পরিবর্তনের একমাত্র কারণ থাকতে হবে।

প্রশ্নটিতে "প্রতিবেদন" শ্রেণিটি ডিকনস্ট্রাক্ট করে এর তিনটি পদ্ধতি রয়েছে:

  • 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 । আইওসি ধারক নিবন্ধনে প্রকৃত বাস্তবায়ন কেবল একবার ঘোষণা করা দরকার।Reportprint

কিছু লোক, যখন উপরোক্ত ডিজাইনের মুখোমুখি হয়, তখন এমন কিছু দিয়ে প্রতিক্রিয়া জানায়: "তবে এটি প্রক্রিয়াগত কোডের মতো দেখায়, এবং ওওপির পুরো পয়েন্টটি আমাদের - ডেটা এবং আচরণের পৃথকীকরণ থেকে পেতে হয়েছিল!" যা আমি বলি: ভুল

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

উদাহরণস্বরূপ, একটি আসল আয়ের বিবরণীতে মোট আয় , মোট ব্যয় এবং নেট আয়ের লাইন রয়েছে। একটি সঠিকভাবে ডিজাইন করা আর্থিক ব্যবস্থা সম্ভবত এগুলি সংরক্ষণ করবে না কারণ এগুলি লেনদেনের ডেটা নয় - আসলে, নতুন ট্রানজেকশনাল ডেটা সংযোজনের ভিত্তিতে এগুলি পরিবর্তিত হয়। যাইহোক, এই লাইনের গণনা সর্বদা হুবহু একই হতে চলেছে, আপনি প্রতিবেদনটি মুদ্রণ, রেন্ডারিং বা রফতানি করছেন তা নির্বিশেষে। সুতরাং আপনার IncomeStatementবর্গ আকারে এটি আচরণের ন্যায্য পরিমাণ আছে যাচ্ছে getTotalRevenues(), getTotalExpenses()এবং getNetIncome()পদ্ধতি, এবং সম্ভবত কয়েক অন্যদের। এটি সত্যই অনেক কিছু "না" বলে মনে হয় না, এমনকি এটি তার নিজস্ব আচরণের সাথে একটি খাঁটি OOP- শৈলীযুক্ত বস্তু।

কিন্তু পদ্ধতি formatএবং printপদ্ধতিগুলির সাথে তাদের তথ্যের সাথে কোনও সম্পর্ক নেই। প্রকৃতপক্ষে, এটি খুব সম্ভবত সম্ভাবনা নেই যে আপনি এই পদ্ধতিগুলির বেশ কয়েকটি বাস্তবায়ন করতে চাইবেন , উদাহরণস্বরূপ ম্যানেজমেন্টের জন্য একটি বিশদ বিবৃতি এবং শেয়ারহোল্ডারদের জন্য একটি অত-বিবৃত বিবৃতি। এই স্বতন্ত্র ফাংশনগুলিকে বিভিন্ন শ্রেণিতে বিভক্ত করা আপনাকে রানটাইমের সময় এক-আকারের সমস্ত print(bool includeDetails, bool includeSubtotals, bool includeTotals, int columnWidth, CompanyLetterhead letterhead, ...)পদ্ধতির বোঝা ছাড়াই বিভিন্ন বাস্তবায়ন চয়ন করার ক্ষমতা দেয় gives ইশ!

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

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


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


+1 দুর্দান্ত উত্তর। তবে আমি ক্লাস নিয়ে শুধু বিভ্রান্ত IncomeStatement। আপনার প্রস্তাবিত নকশা গড় যে কি IncomeStatementদৃষ্টান্ত থাকবে IncomeStatementPrinter& IncomeStatementRendererযাতে যখন আমি কল print()উপর IncomeStatementএটি কল প্রতিনিধি হবে IncomeStatementPrinterপরিবর্তে?
সানগো

@ সাঙ্গো: একেবারে না! আপনি যদি সলিড অনুসরণ করছেন তবে আপনার চক্রীয় নির্ভরতা থাকা উচিত নয়। দৃশ্যত আমার উত্তর এটা স্পষ্ট যথেষ্ট যে করেননি IncomeStatementবর্গ নেই একটি printপদ্ধতি, অথবা একটি formatপদ্ধতি, বা অন্য কোন পদ্ধতি সরাসরি পরিদর্শন বা রিপোর্ট তথ্য নিজেই সাধিত সাথে মোকাবিলা করে না। এই অন্যান্য ক্লাসের জন্য কি। আপনি যদি একটি মুদ্রণ করতে চান, তবে আপনি IPrintable<IncomeStatement>ইন্টারফেসের উপর নির্ভরতা রাখবেন যা ধারকটিতে নিবন্ধিত রয়েছে।
অ্যারোনআট

আহ আমি আপনার বক্তব্য দেখতে তবে, আমি ক্লাসে কোনও উদাহরণ ইনজেকশন দিলে চক্র নির্ভরতা কোথায় ? আমি যখন কল করি তখন যেভাবে কল্পনা করি তা এটিকে এটি অর্পণ করে । এই পদ্ধতির সাথে কী ভুল? ... অন্য প্রশ্ন, আপনি উল্লেখ করেছেন যে ফর্ম্যাট প্রতিবেদনে উপস্থিত তথ্য থাকতে হবে যদি আমি এটি ডাটাবেস থেকে বা কোনও এক্সএমএল ফাইল থেকে পড়তে চাই, আমি কি সেই পদ্ধতিটি বের করব যা ডেটা লোড করে? একটি পৃথক শ্রেণীতে এবং ডেলিগেশন এটিতে ? PrinterIncomeStatementIncomeStatement.print()IncomeStatementPrinter.print(this, format)IncomeStatementIncomeStatement
সানগো

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

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

2

এসআরপি-র জন্য আমি যেভাবে যাচাই করি তা হল কোনও শ্রেণীর প্রতিটি পদ্ধতি (দায়িত্ব) পরীক্ষা করা এবং নিম্নলিখিত প্রশ্নটি জিজ্ঞাসা করা:

"এই ফাংশনটি বাস্তবায়নের পদ্ধতিটি কি আমাকে কখনও বদলাতে হবে?"

যদি আমি এমন কোনও ফাংশন পাই যা আমাকে বিভিন্ন উপায়ে প্রয়োগ করতে হবে (কোনও ধরণের কনফিগারেশন বা শর্তের উপর নির্ভর করে) তবে আমি নিশ্চিতভাবে জানি যে এই দায়িত্বটি পরিচালনার জন্য আমার অতিরিক্ত শ্রেণি প্রয়োজন।


1

অবজেক্ট ক্যালিস্টেনিক্সের বিধি 8 এর একটি উদ্ধৃতি এখানে :

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

এটি (কিছুটা আদর্শবাদী) দৃষ্টিতে আপনি বলতে পারেন যে যে কোনও শ্রেণিতে কেবল এক বা দুটি রাষ্ট্রীয় ভেরিয়েবল রয়েছে সেগুলি এসআরপি লঙ্ঘনের সম্ভাবনা কম। আপনি আরও বলতে পারেন যে যে কোনও শ্রেণিতে দুটিরও বেশি রাষ্ট্রীয় ভেরিয়েবল রয়েছে এসআরপি লঙ্ঘন করতে পারে


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

ওপিএসের প্রশ্নটি ছিল "এসআরপি চেক করার আরও কি উপায় আছে?" - এটি একটি সম্ভাব্য সূচক। হ্যাঁ এটি সরল, এবং এটি প্রতিটি ক্ষেত্রেই ধরে না, তবে এসআরপি লঙ্ঘিত হয়েছে তা যাচাই করার এটি একটি সম্ভাব্য উপায়।
ম্যাটডি ডেভী

1
আমি সন্দেহ করি যে পরিবর্তনীয় বনাম অপরিবর্তনীয় রাষ্ট্রটিও একটি গুরুত্বপূর্ণ বিবেচ্য বিষয়
জে কে।

বিধি 8 এ হাজার হাজার এবং হাজার হাজার ক্লাস রয়েছে এমন ডিজাইন তৈরির জন্য নিখুঁত প্রক্রিয়া বর্ণনা করে যা সিস্টেমটিকে আশাহীনভাবে জটিল, আপত্তিজনক এবং অবিস্মরণীয় করে তোলে। তবে প্লাস সাইডটি হ'ল আপনি এসআরপি অনুসরণ করতে পারেন।
ডঙ্ক

@ ডাঙ্ক আমি আপনার সাথে একমত নই, তবে এই আলোচনাটি পুরোপুরি প্রশ্নের বাইরে।
ম্যাটডি ডেভী

1

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

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

public class Report
{
    private ReportData data;
    private ReportDataDao dao;
    private ReportFormatter formatter;
    private ReportPrinter printer;


    /*
     *  Parameterized constructor for depndency injection, 
     *  there are better ways but this is explicit.
     */
    public Report(ReportDataDao dao, 
        ReportFormatter formatter, ReportPrinter printer)
    {
        super();
        this.dao = dao;
        this.formatter = formatter;
        this.printer = printer;
    }

    /*
     * Delegates to the injected printer.
     */
    public void printReport()
    {
        printer.print(formatReport());
    }


    /*
     * Lazy loading of data, delegates to the dao 
     * for the meat of the call.
     */
    public ReportData getReportData()
    {
        if (reportData == null)
        {
            reportData = dao.loadData();
        }
        return reportData;
    }

    /*
     * Delegate to the formatter for formatting 
     * (notice a pattern here).
     */
    public ReportData formatReport()
    {
        formatter.format(getReportData());
    }
}

বাস্তবায়নের জন্য ধন্যবাদ। আমার কাছে দুটি জিনিস রয়েছে, if (reportData == null)আমি মনে করি যে dataপরিবর্তে আপনার অর্থ বোঝাতে চাইছি line দ্বিতীয়ত, আমি আপনাকে এই বাস্তবায়নে কীভাবে পৌঁছেছি তা জানতে আশা করছিলাম। এর পরিবর্তে আপনি কেন অন্য কলগুলিতে সমস্ত কলকে অর্পণ করার সিদ্ধান্ত নিয়েছিলেন। আমি আরও একটি বিষয় যা সম্পর্কে সবসময় ভাবতাম, নিজেকে ছাপানো কি কোনও প্রতিবেদনের সত্যই দায়িত্ব ?! কেন আপনি একটি পৃথক printerশ্রেণি তৈরি করেন নি যা এর নির্মাতাকে গ্রহণ করে report?
সানগো

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

হুমমম ... সুতরাং আপনি যদি স্ক্র্যাচ থেকে সিস্টেমটি তৈরি করছিলেন তবে আপনি কোন বিকল্পটি গ্রহণ করবেন? একটি Printerক্লাস যা প্রতিবেদন নেয় বা Reportক্লাস যা একটি প্রিন্টার নেয়? আমি একটি প্রতিবেদন পার্স করার আগে যেখানে আমি একই ধরণের সমস্যার মুখোমুখি হয়েছি এবং আমি আমার টিএল এর সাথে তর্ক করেছিলাম যদি আমাদের একটি প্রতিবেদন তৈরি করে এমন একটি পার্সার তৈরি করা উচিত বা রিপোর্টটির ভিতরে কোনও পার্সার থাকা উচিত এবং parse()কলটি তার কাছে প্রেরণ করা হয়েছিল।
সানগো

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

0

আপনার উদাহরণে এটি স্পষ্ট নয় যে এসআরপি লঙ্ঘিত হচ্ছে। সম্ভবত প্রতিবেদনটি ফর্ম্যাট এবং মুদ্রণ করতে সক্ষম হবে, যদি তারা তুলনামূলকভাবে সহজ হয়:

class Report {
  void format() {
     text = text.trim();
  }

  void print() {
     new Printer().write(text);
  }
}

পদ্ধতিগুলি এত সহজ যে এটি ক্লাস করা ReportFormatterবা বোধগম্য নয় ReportPrinter। ইন্টারফেসের একমাত্র সুস্পষ্ট সমস্যা হ'ল getReportDataকারণ এটি লঙ্ঘন করে জিজ্ঞাসা করে অ-মানযুক্ত অবজেক্টের বিষয়ে বলবেন না।

অন্যদিকে, যদি পদ্ধতিগুলি খুব জটিল হয় বা ফর্ম্যাট বা মুদ্রণের অনেকগুলি উপায় থাকে Reportতবে দায়িত্ব অর্পণ করা বুদ্ধিমান হয় (আরও পরীক্ষামূলক):

class Report {
  void format(ReportFormatter formatter) {
     text = formatter.format(text);
  }

  void print(ReportPrinter printer) {
     printer.write(text);
  }
}

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

  • ক্লাসগুলি এত বড় যে আপনি সময় স্ক্রোলিংয়ে সময় নষ্ট করছেন বা সঠিক পদ্ধতিটি সন্ধান করছেন।
  • ক্লাসগুলি এত ছোট এবং অসংখ্য আপনি তাদের মধ্যে ঝাঁপিয়ে পড়া বা সঠিকটি খুঁজে পেতে সময় নষ্ট করেন।
  • যখন আপনাকে কোনও পরিবর্তন আনতে হবে এটি এতগুলি শ্রেণিতে প্রভাবিত করে এটি ট্র্যাক রাখা শক্ত।
  • যখন আপনাকে কোনও পরিবর্তন আনতে হবে তখন ক্লাসগুলি কী পরিবর্তন করতে হবে তা অস্পষ্ট।

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


আপনি কি পোস্টের সাথে সংযুক্ত উদাহরণটি পরীক্ষা করে দেখতে পারেন এবং এর উপর ভিত্তি করে আপনার উত্তরটি বিস্তৃত করতে পারেন?
সানগো

আপডেট করা হয়েছে। এসআরপি প্রসঙ্গে নির্ভর করে, আপনি যদি একটি সম্পূর্ণ ক্লাস পোস্ট করেন (একটি পৃথক প্রশ্নে) তবে এটি ব্যাখ্যা করা সহজ।
গ্যারেট হল

আপডেটের জন্য ধন্যবাদ. যদিও একটি প্রশ্ন, নিজেই কোনও প্রতিবেদন ছাপানো দায় ?! আপনি কেন একটি পৃথক মুদ্রক শ্রেণি তৈরি করেন নি যা এর নির্মাতায় একটি প্রতিবেদন নেয়?
সানগো

আমি কেবল বলছি এসআরপি কোডের উপর নির্ভর করে আপনার এটি কুকুরের মাধ্যমে প্রয়োগ করা উচিত নয়।
গ্যারেট হল

হ্যাঁ আমি আপনার বক্তব্য পেয়েছি আপনি যদি স্ক্র্যাচ থেকে সিস্টেমটি তৈরি করছিলেন তবে আপনি কোন বিকল্পটি গ্রহণ করবেন? একটি Printerক্লাস যা প্রতিবেদন নেয় বা Reportক্লাস যা একটি প্রিন্টার নেয়? কোডটি জটিল প্রমাণিত হবে কিনা তা নির্ধারণ করার আগে অনেক সময় আমি এই জাতীয় নকশার প্রশ্নের মুখোমুখি হয়েছি।
সানগো

0

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

এছাড়াও, এসআরপি ভালভাবে প্রয়োগ করার জন্য আপনি ব্যবসায়িক লজিক ডোমেনটি ভালভাবে বুঝতে পারেন; প্রতিটি বিমূর্ততা কি করা উচিত তা জানতে। স্তরযুক্ত আর্কিটেকচারটি এসআরপির সাথেও সম্পর্কিত, প্রতিটি স্তরকে একটি নির্দিষ্ট কাজ করার মাধ্যমে (ডেটা উত্স স্তরকে ডেটা সরবরাহ করা উচিত)।

আপনার পদ্ধতিগুলি সমস্ত ভেরিয়েবল ব্যবহার না করে এমনকি সংহতিতে ফিরে আসা, সেগুলি সংযুক্ত করা উচিত:

public class MyClass {
    private Type1 var1;
    private Type2 var2;
    private Type3 var3;

    public Type3 method1() {
        //use var1 and var3
    }  

    public void method2() {
        //use var1 and var2
    }

    public Type1 method3() {
        //use var2 and var3
    }
}

কোড বেলো এর মতো আপনার কিছু না থাকা উচিত, যেখানে উদাহরণের ভেরিয়েবলগুলির একটি অংশ পদ্ধতিগুলির একটি অংশে ব্যবহৃত হয়, এবং ভেরিয়েবলগুলির অন্য অংশগুলি পদ্ধতিগুলির অন্য অংশে ব্যবহৃত হয় (এখানে আপনার দুটি শ্রেণি হওয়া উচিত ভেরিয়েবলের প্রতিটি অংশ)।

public class MyClass {
    private Type1 var1;
    private Type2 var2;
    private Type3 var3;
    private TypeA varA;
    private TypeB varB;

    public Type3 method1() {
        //use var1 and var3
    }  

    public void method2() {
        //use var1 and var2
    }

    public TypeA methodA() {
        //use varA and varB
    }

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