SOLID নীতি প্রয়োগ করা


13

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

অ্যাপ্লিকেশনটিতে নিম্নলিখিত কাজটি রয়েছে (আসলে এর চেয়ে অনেক বেশি তবে আসুন এটি সহজ রাখুন): এটি একটি এক্সএমএল ফাইলটি পড়তে হবে যাতে ডেটাবেস টেবিল / কলাম / ভিউ ইত্যাদি সংজ্ঞা রয়েছে এবং একটি এসকিউএল ফাইল তৈরি করতে হবে যা তৈরির জন্য ব্যবহার করা যেতে পারে একটি ORACLE ডাটাবেস স্কিমা।

(দ্রষ্টব্য: কেন আমার এটি প্রয়োজন বা কেন আমি এক্সএসএলটি ব্যবহার করি না ইত্যাদি কারণগুলি নিয়ে আলোচনা থেকে বিরত থাকুন, কারণ রয়েছে তবে সেগুলি অফ-টপিক))

শুরু হিসাবে, আমি কেবল সারণী এবং সীমাবদ্ধতার দিকে নজর দেওয়া বেছে নিয়েছি। আপনি যদি কলামগুলি উপেক্ষা করেন তবে আপনি এটি নিম্নলিখিত উপায়ে বর্ণনা করতে পারেন:

সীমাবদ্ধতা একটি টেবিলের অংশ (বা আরও সুনির্দিষ্টভাবে, একটি তৈরি টেবিল বিবৃতি অংশ), এবং একটি সীমাবদ্ধতা অন্য সারণিকেও উল্লেখ করতে পারে।

প্রথমত, আমি এখনই অ্যাপ্লিকেশনটি কেমন দেখাচ্ছে তা ব্যাখ্যা করব (সোলিড প্রয়োগ না করে):

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

স্পষ্টতই, এটি মোটেও সলিডের জন্য প্রযোজ্য নয়। উদাহরণস্বরূপ, বিজ্ঞপ্তি নির্ভরতা রয়েছে, যা "অ্যাড" / "অপসারণ" পদ্ধতিগুলির প্রয়োজনীয়তা এবং কিছু বড় অবজেক্ট ডেস্ট্রাক্টরগুলির ক্ষেত্রে কোডটি স্ফূতিত করে।

সুতরাং প্রশ্ন দুটি আছে:

  1. Dependency Injection ব্যবহার করে বৃত্তাকার নির্ভরতাগুলি সমাধান করা উচিত? যদি তা হয়, তবে আমি মনে করি যে এই সীমাবদ্ধতার মালিক তার নির্মাণকারীর (এবং বিকল্পভাবে রেফারেন্সযুক্ত) সারণীটি গ্রহণ করবেন। তবে আমি কীভাবে একক টেবিলের জন্য সীমাবদ্ধতার তালিকার উপরে চলে যেতে পারি?
  2. যদি টেবিল শ্রেণি উভয়ই নিজের রাজ্য সংরক্ষণ করে (যেমন টেবিলের নাম, টেবিলের মন্তব্য ইত্যাদি) এবং সীমাবদ্ধতার লিঙ্কগুলি, তবে কি এই এক বা দুটি "দায়িত্ব", একক দায়িত্বের নীতিটির কথা চিন্তা করে?
  3. ক্ষেত্রে ২. যদি ঠিক হয় তবে লজিক্যাল বিজনেস লেয়ারে লিংকগুলি পরিচালনা করে আমি কি নতুন ক্লাস তৈরি করব? যদি তা হয় তবে, 1. অবশ্যই প্রাসঙ্গিক হবে না।
  4. "ক্রিয়েস্টেটমেন্ট" পদ্ধতিগুলি কি ছক / সীমাবদ্ধ শ্রেণির অংশ হওয়া উচিত বা আমিও সেগুলি সরিয়ে নিয়ে যেতে পারি? যদি তাই হয় তবে কোথায়? প্রতিটি ডেটা স্টোরেজ ক্লাসে একজন ম্যানেজার ক্লাস (যেমন টেবিল, সীমাবদ্ধ, ...)? অথবা বরং প্রতি লিঙ্কে একটি পরিচালক শ্রেণি তৈরি করুন (৩. এর মতো)?

যখনই আমি এই প্রশ্নের একটির উত্তর দেওয়ার চেষ্টা করি আমি নিজেকে কোথাও কোথাও চেনাশোনাগুলিতে দৌড়াতে দেখি।

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


3
আপনি কোন ভাষা ব্যবহার করছেন? আপনি কি কমপক্ষে কিছু কঙ্কালের কোড পোস্ট করতে পারেন? প্রকৃত কোড না দেখে কোডের মান এবং সম্ভাব্য রিফ্যাক্টেরিংগুলি নিয়ে আলোচনা করা খুব কঠিন।
প্যাটার তুরিক

আমি সি ++ ব্যবহার করছি তবে আপনি যে কোনও ভাষায় এই সমস্যা হতে পারে বলে আমি এটিকে আলোচনার বাইরে রাখার চেষ্টা করছিলাম
টিম মেয়ার

হ্যাঁ, তবে নিদর্শন এবং রিফ্যাক্টরিংগুলির প্রয়োগ ভাষা নির্ভর। উদাহরণস্বরূপ @ back2dos নীচে তার উত্তরে এওপি প্রস্তাব করেছে, যা অবশ্যই সি ++ এর জন্য প্রযোজ্য নয়।
প্যাটার তারেক

SOLID নীতিগুলি সম্পর্কে আরও জানতে দয়া করে প্রোগ্রামার.সটাকেক্সচেঞ্জ
প্রশ্নগুলি

উত্তর:


8

আপনি এখানে "একক দায়িত্বের নীতিমালা" প্রয়োগ করতে ভিন্ন দৃষ্টিকোণ থেকে শুরু করতে পারেন। আপনি আমাদের যা দেখিয়েছেন তা হ'ল আপনার অ্যাপ্লিকেশনটির কেবলমাত্র ডেটা মডেল। এখানে এসআরপি অর্থ: আপনার ডেটা মডেলটি কেবল ডেটা রাখার জন্য দায়ী - তা কম, আর বেশি নয় তা নিশ্চিত করুন।

সুতরাং আপনি যখন আপনার এক্সএমএল ফাইলটি পড়তে যাচ্ছেন, তখন এটি থেকে একটি ডেটা মডেল তৈরি করুন এবং এসকিউএল লিখুন, আপনার যা করা উচিত নয় তা আপনার Tableক্লাসে এমন কোনও কিছু প্রয়োগ করা যা এক্সএমএল বা এসকিউএল নির্দিষ্ট। আপনার ডেটা প্রবাহটি দেখতে দেখতে এমনটি চান:

[XML] -> ("Read XML") -> [Data model of DB definition] -> ("Write SQL") -> [SQL]

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

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

সলিড সম্পর্কে আরও কিছু: এখানে একটি নিবন্ধ ভাল

http://cre8ivethought.com/blog/2011/08/23/software-development-is-not-a-jenga-game

একটি ছোট উদাহরণ দ্বারা SOLID ব্যাখ্যা। আপনার ক্ষেত্রে এটি প্রয়োগ করার চেষ্টা করা যাক:

  • আপনি না শুধুমাত্র শ্রেণীর করতে হবে Read_XMLএবং Write_SQL, এছাড়াও একটি থার্ড ক্লাস, যার সুসংবাদ 2 ক্লাস মিথষ্ক্রিয়া পরিচালনা করে। একে ডাকি ConversionManager

  • ডিআই নীতি প্রয়োগের অর্থ এখানে হতে পারে: রূপান্তরকরণের নিজেই Read_XMLএবং এর উদাহরণ তৈরি করা উচিত নয় Write_SQL। পরিবর্তে, objects বস্তুগুলি কনস্ট্রাক্টরের মাধ্যমে ইনজেকশন দেওয়া যায়। এবং কনস্ট্রাক্টরের এর মতো স্বাক্ষর থাকা উচিত

    ConversionManager(IDataModelReader reader, IDataModelWriter writer)

IDataModelReaderএকটি ইন্টারফেস যেখানে থেকে Read_XMLউত্তরাধিকার সূত্রে আসে এবং IDataModelWriterএকই জন্য Write_SQL। এটি ConversionManagerপরিবর্তন না করেই এক্সটেনশনের জন্য উন্মুক্ত করে তোলে (আপনি খুব সহজেই বিভিন্ন পাঠক বা লেখক সরবরাহ করেন) - সুতরাং আমাদের কাছে মুক্ত / বন্ধ নীতিটির একটি উদাহরণ রয়েছে। আপনি যখন অন্য কোনও ডাটাবেস বিক্রেতাকে সমর্থন করতে চান - তখন আপনাকে কী পরিবর্তন করতে হবে তা ভেবে দেখুন, আপনাকে আপনার ডেটামোডেলে কোনও পরিবর্তন করতে হবে না, কেবল অন্য কোনও এসকিউএল-রাইটার সরবরাহ করুন।


যদিও এটি সলিডের একটি খুব যুক্তিসঙ্গত অনুশীলন, (আপোভোটেড) নোট করুন যে এটি "পুরাতন স্কুল কায় / হলব ওওপি" লঙ্ঘন করে মোটামুটি রক্তাল্পতার ডেটা মডেলের জন্য গেটার এবং সেটটার প্রয়োজন requ এটি আমাকে কুখ্যাত স্টিভ ইয়েজ অভিজাতর কথা মনে করিয়ে দেয় ।
ব্যবহারকারী949300

2

ভাল, আপনার এক্ষেত্রে এস এস এস আই এস আই এস প্রয়োগ করতে হবে।

একটি সারণী এটিতে সংজ্ঞায়িত সমস্ত প্রতিবন্ধকতা ধারণ করে। একটি সীমাবদ্ধতা সমস্ত টেবিলকে রেফারেন্স করে। সরল এবং সাধারণ মডেল।

আপনি এটিতে কী আটকে থাকেন তা হ'ল বিপরীত অনুসন্ধানগুলি সম্পাদন করার ক্ষমতা, অর্থাত্ কোনও সারণি রেফারেন্সযুক্ত বাধা দ্বারা এটি নির্ধারণ করা।
সুতরাং আপনি আসলে যা চান তা হ'ল একটি সূচক পরিষেবা service এটি একটি সম্পূর্ণ আলাদা কাজ এবং তাই অন্য কোনও বস্তুর দ্বারা চালিত হওয়া উচিত।

এটিকে খুব সরল সংস্করণে ভাঙ্গতে:

class Table {
      void addConstraint(Constraint constraint) { ... }
      bool removeConstraint(Constraint constraint) { ... }
      Iterator<Constraint> getConstraints() { ... }
}
class Constraint {
      //actually I am not so sure these two should be exposed directly at all
      void addReference(Table to) { ... }
      bool removeReference(Table to) { ... }
      Iterator<Table> getReferencedTables() { ... }
}
class Database {
      void addTable(Table table) { ... }
      bool removeTable(Table table) { ... }
      Iterator<Table> getTables() { ... }
}
class Index {
      Iterator<Constraint> getConstraintsReferencing(Table target) { ... }
}

সূচকটি বাস্তবায়নের জন্য 3 উপায় আছে:

  • getContraintsReferencingপদ্ধতি সত্যিই শুধু পুরো হামাগুড়ি পারে Databaseজন্য Tableদৃষ্টান্ত এবং তাদের হামাগুড়ি Constraintগুলি ফলাফলের জন্য। এটি কতটা ব্যয়বহুল এবং আপনার কতবার প্রয়োজন তা নির্ভর করে এটি একটি বিকল্প হতে পারে।
  • এটি একটি ক্যাশে ব্যবহার করতে পারে। যদি আপনার ডাটাবেস মডেলটি একবার সংজ্ঞায়িত হয়ে পরিবর্তন করতে পারে তবে আপনি যখন পরিবর্তন করেন তখন সংশ্লিষ্ট Tableএবং Constraintদৃষ্টান্তের কাছ থেকে আগুনের সংকেত দিয়ে ক্যাশে বজায় রাখতে পারেন । একটি সামান্য সরল সমাধানটি হ'ল পুরোটির Indexএকটি "স্ন্যাপশট সূচক" তৈরির Databaseসাথে কাজ করার জন্য, যা আপনি তখন বাতিল করে দিন। এটি অবশ্যই সম্ভব, যদি আপনার অ্যাপ্লিকেশনটি "মডেলিংয়ের সময়" এবং "অনুসন্ধানের সময়" এর মধ্যে বড় পার্থক্য করে। যদি এটি একই সাথে এই দুটি করার সম্ভাবনা থাকে তবে এটি কার্যকর হবে না is
  • অন্য বিকল্পটি হ'ল এওপি ব্যবহার করে পুরো ক্রিয়েশন কলগুলি বন্ধ করতে হবে এবং সেই অনুসারে সূচি বজায় রাখতে হবে।

খুব বিস্তারিত উত্তর, আমি আপনার সমাধানটি এতদূর পছন্দ করি! যদি আমি টেবিল বর্গের জন্য ডিআই করতাম, নির্মাণের সময় বাধাগুলির তালিকা দিয়ে থাকি তবে আপনি কী ভাববেন? আমার যাইহোক একটি টেবিলপার্সার ক্লাস রয়েছে, যা কারখানা হিসাবে কাজ করতে পারে বা সেই ক্ষেত্রে কারখানার সাথে একসাথে কাজ করতে পারে।
টিম মায়ার

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

1

বিজ্ঞপ্তি নির্ভরতার জন্য নিরাময় হ'ল মানত করা যে আপনি কখনই এগুলি তৈরি করবেন না। আমি দেখতে পেয়েছি যে কোডিং টেস্ট-প্রথমটি একটি শক্তিশালী প্রতিরোধক।

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

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


এটি যেখানে "(আসলে এটির চেয়ে অনেক বেশি তবে আসল এটি সহজ রাখুন)" খেলতে আসে। উদাহরণস্বরূপ, এমন কেস রয়েছে যেখানে আমার একটি টেবিল মুছতে হবে, সুতরাং এই সারণীতে রেফারেন্স দিচ্ছে কিনা তা আমাকে খতিয়ে দেখা উচিত।
টিম মায়ার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.