source: https://www.udemy.com/course/solid-principles/

SOLID Principle (Part-1)

--

SOLID হচ্ছে Object Oriented Programming এর গুরুত্বপূর্ণ ৫টি individual design pattern এর কম্বিনেশন, যা Robert Cecil Martin (যিনি uncle bob নামে পরিচিত) ২০০০ সালে তার Design Principles and Design Patterns নামক পেপারে উপস্থাপন করেন।

এর মূল উদ্দেশ্য হলো understandable, reusable, easier to extend এবং well-maintainable সফটওয়্যার ডিজাইন করা। আমরা প্রতিনিয়ত এক্সিস্টিং প্রজেক্টে কাজ করি। আর তা করতে গিয়ে প্রচুর কোড পড়তে হয়, পড়ে বুঝতে হয় এবং নতুন রিকোয়ারমেন্ট অনুযায়ী এক্সটেন্ড করতে হয়। যদি SOLID এর মতো একটা কমন প্যাটার্ন ফলো করে কোড করা হয় তাহলে পরবর্তীতে এসব কোড সহজে বুঝা যাবে এবং দ্রুত এক্সটেন্ড করা যাবে।

SOLID এর ৫টি principle হচ্ছেঃ

  1. Single Responsibility Principle (SRP)
  2. Open-Closed Principle (OCP)
  3. Liskov Substitution Principle (LSP)
  4. Interface Segregation Principle (ISP)
  5. Dependency Inversion Principle (DIP)

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

এই আর্টিকেলে আমি SOLID এর প্রতিটি principle নিয়ে আলোচনা করবো। কিভাবে আমরা প্রতিটি principle কে violate করি এবং কিভাবে তা সমাধান করা যায় সেটা দেখানোর চেষ্টা করবো। সবগুলো উদাহরণ PHP তে দেয়া আছে, তবে যেকোনো OOP ল্যাংগুয়েজ এ ব্যবহার করা যাবে। এই আর্টিকেল এ SOLID এর প্রথম দুইটি principle নিয়ে আলোচনা করবো। বাকি ৩ টি নিয়ে পরবর্তী পর্বে লিখবো ইনশাআল্লাহ। চলুন শুরু করা যাকঃ

Single Responsibility Principle (SRP)

A class should have one, only one reason to change.

SOLID এর প্রথম principle হলো Single Responsibility Principle (SRP). এটা খুবই সহজ কনসেপ্ট। SRP এর শর্ত হলো একটা Class এর শুধুমাত্র একটাই কাজ/উদ্দেশ্য থাকবে। অর্থাৎ প্রতিটি ভিন্ন-ভিন্ন কাজের জন্য ভিন্ন-ভিন্ন Class থাকবে।

চলুন দেখা যাক কিভাবে SRP violate হচ্ছেঃ

উপরের UserInfo ক্লাসে দুটি মেথড আছে। একটা getUserName যেটা ইউজার এর নাম রিটার্ন করে, অন্যটা sendMailToUser যেটা দিয়ে ইউজারকে ইমেইল পাঠানো হয়। তারমানে এই ক্লাস এর জব দুইটা, ১) ইউজার এর নাম বা তথ্য দেয়া এবং ২) ইমেইল পাঠানো।

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

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

চলুন আমরা UserInfo ক্লাসে SRP refactor করিঃ

এখানে UserInfo ক্লাস এর ৩টি মেথড আছে। ৩টি মেথড-ই ইউজার এর তথ্য সরবরাহের কাজ করছে। অর্থ্যাৎ এই ক্লাস এর একটাই কাজ- ইউজার এর তথ্য সরবরাহ করা।

Open-Closed Principle (OCP)

You should be able to extend a classes behavior, without modifying it.

Robert C. Martin এই principle কে maintainable এবং reusable কোড এর ফাউন্ডেশন বলে উল্লেখ করেছেন।

OCP বলে যে, আমাদের সফটওয়্যার এর এনটিটি গুলো (class, function, module) এমনভাবে ডিজাইন করা উচিত যাতে ভবিষ্যতে নতুন রিকোয়ারমেন্ট এলেও এক্সিস্টিং কোড মোডিফাই না করে বরং এক্সিস্টিং কোডকে এক্সটেন্ড করেই এর behavior কে পরিবর্তন করা যায়। এখানে উল্লেখ্য, behavior বলতে সোর্স কোডের আচরণগত পরিবর্তনকেই বুঝায়। সোজা কোথায়, আমাদের সফ্টওয়ার এনটিটি গুলো হবে open for extension but closed for modification.

আমরা যদি যথাযথভাবে OCP প্রয়োগ করতে পারি তবে existing সোর্স কোড মোডিফাই না করেই নতুন ফিচার এড করা যাবে। OCP কনফার্ম করে যে, আমাদের ডিজাইন করা এনটিটি সমূহ ভবিষ্যতের রিকোয়ারমেন্ট এর চাহিদা পূরণে নতুন ও ভিন্ন উপায়ে আচরণ করতে পারবে। এবং সেটা এক্সিস্টিং সোর্স কোডের বড় কোনো পরিবর্তন ছাড়াই।

চলুন নিচের উদাহরণটি দেখিঃ

ধরা যাক, আমাদের সিস্টেমে পেমেন্টের জন্য একটি paymentController ক্লাস আছে, এখানে pay মেথড এর মাধ্যমে পেমেন্ট নেয়া হয়। আর paymentService নামক ক্লাস আছে এখানে বিভিন্ন ধরণের পেমেন্ট সার্ভিস এর জন্য আলাদা আলাদা function রয়েছে। pay মেথড এর পেমেন্ট টাইপ এর উপর ভিত্তি করে পেমেন্ট সার্ভিস এর ধরণ সিলেক্ট করা হয়।

এখন এখানে যদি নতুন কোনো পেমেন্ট গেটওয়ে যোগ করতে চাই তাহলে বিদ্যমান দুইটা ক্লাসই মোডিফাই করতে হবে। এখানেই OCP violation হয়েছে। যেহেতু OCP বলেছে বিদ্যমান সোর্স কোড হবে closed for modification, সেখানে আমাদের কোড মোডিফাই করতে হচ্ছে।

চলুন দেখি কিভাবে OCP violation দূর করতে পারিঃ

এখানে আমরা একটা interface করেছি paymentInterface নামে, যেখানে শুধুমাত্র pay মেথড আছে। যেসকল class এই interface কে ইমপ্লিমেন্ট করবে তাদেরকে অবশ্যই pay মেথডটি ডিফাইন করতে হবে।

এরপর আমরা বিভিন্ন ধরণের পেমেন্ট গেটওয়ের জন্য আলাদা-আলাদা class করেছি যারা সবাই paymentInterface কে ইমপ্লিমেন্ট করেছে। আর paymentService ক্লাসে initialize মেথড এর মাধ্যমে পেমেন্ট গেটওয়ে নির্বাচন করছি এবং paymentController ক্লাস এর pay মেথডও পরিবর্তন করেছি, এখানে পেমেন্ট টাইপ দিয়ে paymentService থেকে নির্দিষ্ট পেমেন্ট গেটওয়ে সিলেক্ট করা হয়।

যেহেতু সকল পেমেন্ট গেটওয়ের ক্লাসই paymentInterface কে ইমপ্লিমেন্ট করছে সেহেতু তারা অবশ্যই pay মেথড ও ডিফাইন করেছে। তারপর ওই মেথডে কল করে পেমেন্ট সম্পন্ন হবে।

এখন যদি আমাদেরকে নতুন পেমেন্ট গেটওয়ে এড করতে বলা হয় তাহলে খুব সহজেই সেটা করা যাবে। যা করতে হবেঃ

  • নতুন পেমেন্ট গেটওয়ের জন্য আলাদা ক্লাস হবে যেটা paymentInterface কে ইমপ্লিমেন্ট করবে।
  • paymentService ক্লাস এর initalize মেথডে নতুন পেমেন্ট গেটওয়ের জন্য কন্ডিশন এড হবে এবং নতুন ক্লাস এর অবজেক্ট রিটার্ন হবে।

অর্থাৎ, existing কোডে তেমন পরিবর্তন ছাড়াই আমরা নতুন পেমেন্ট গেটওয়ে এড করতে পেরেছি।

কিভাবে বুঝবো কোথায় OCP apply করতে হবেঃ

OCP’র মূল উদ্দেশ্য হলো কোনো class এর behavior কে বড় ধরনের মোডিফিকেশন ছাড়াই এক্সটেন্ড করতে পারা। তারমানে এই নয় যে আমরা সব ক্লাসে OCP এপ্লাই করবো। সিস্টেম এর যেসব behavior প্রতিনিয়ত পরিবর্তনের আশংকা আছে সেসব ক্ষেত্রেই OCP এপ্লাই করে ভালো ফল পাওয়া যায়। সিস্টেম এর ডোমেইন সম্পর্কে জানা থাকলে বুঝতে সহজ হয় যে কোথায় OCP ইমপ্লিমেন্ট করা প্রয়োজন।

আশা করি SOLID এর প্রথম দুইটি principle সম্পর্কে ব্যাসিক কিছু ধারণা দিতে পেরেছি। বাকি ৩ টি principle নিয়ে আরেক পর্বে লিখবো ইনশাআল্লাহ।

আমি মনে করি, আমার জানায় এবং লেখায় অনেক ভুল আছে। আপনাদের চো‍খে কোন ভুল ধরা পড়লে অবশ্যই অবশ্যই আমাকে জানাতে ভুলবেন না। এবং আপনাদের পরামর্শ জানালে কৃতজ্ঞ থাকবো।

ধন্যবাদ সবাইকে। আল্লাহ হাফেজ।

পরবর্তী পর্ব এখানে

--

--