Low Coupling & High Cohesion

সফটওয়্যার ডেভেলপমেন্টে তুমি যখন এমন কোনো কোড লিখতে চাও যা দীর্ঘমেয়াদে মেইনটেইনেবল (Maintainable), রিইউজেবল (Reusable) এবং স্কেলেবল (Scalable) হবে, তখন তোমাকে অবশ্যই দুটি অত্যন্ত গুরুত্বপূর্ণ ডিজাইন প্রিন্সিপাল মাথায় রাখতে হবে—Low Coupling এবং High Cohesion।

ভালো সফটওয়্যার আর্কিটেকচারের লক্ষ্যই হলো এমন সিস্টেম তৈরি করা, যেখানে Coupling থাকবে সর্বনিম্ন (Low) এবং Cohesion থাকবে সর্বোচ্চ (High)। এই দুটি কনসেপ্ট মূলত SOLID প্রিন্সিপালের Single Responsibility Principle (SRP) এবং Dependency Inversion Principle (DIP)-এর সাথে সরাসরি যুক্ত।

Coupling কী এবং Low Coupling কেন জরুরি?

Coupling (কাপলিং) মানে হলো একটি ক্লাস বা মডিউল অন্য আরেকটি ক্লাস বা মডিউলের ওপর কতটা নির্ভরশীল।

  • High Coupling (খারাপ ডিজাইন): যখন একটি মডিউলে কোনো ছোট পরিবর্তন করলে অন্য আরেকটি মডিউলেও প্রচুর পরিবর্তন করতে হয়, তখন তাকে High বা Tight Coupling বলে। এতে কোড রিইউজ করা কঠিন হয় এবং ইউনিট টেস্টিং (Unit Testing) প্রায় অসম্ভব হয়ে পড়ে। যাকে সফটওয়্যারের ভাষায় 'Ripple Effect' বলা হয়।

  • Low Coupling (ভালো ডিজাইন): যখন একটি মডিউল স্বাধীনভাবে কাজ করতে পারে এবং অন্য মডিউলের অভ্যন্তরীণ লজিকের ওপর খুব কম নির্ভরশীল থাকে, তখন তাকে Low বা Loose Coupling বলে।

লক্ষ্য: মডিউলগুলোকে একে অপরের থেকে যতটা সম্ভব স্বাধীন (Independent) রাখা।

Java Code Example: High Coupling (Bad Practice)

নিচের কোডে UserService সরাসরি MySQLDatabase ক্লাসের ওপর নির্ভরশীল। এটি Tight Coupling-এর একটি নিখুঁত উদাহরণ।

class MySQLDatabase {
    public void connect() {
        System.out.println("Connecting to MySQL Database...");
    }
}

class UserService {
    private MySQLDatabase db;

    public UserService() {
        // High Coupling: UserService is tightly coupled to MySQLDatabase
        this.db = new MySQLDatabase(); 
    }

    public void getUser() {
        this.db.connect();
        System.out.println("Fetching user details from database...");
    }
}

class Main {
    public static void main(String[] args) {
        UserService service = new UserService();
        service.getUser();
    }
}

সমস্যা: তুমি যদি ভবিষ্যতে MySQL বাদ দিয়ে MongoDB বা PostgreSQL ব্যবহার করতে চাও, তবে তোমাকে মূল UserService ক্লাসের ভেতরে ঢুকে কোড পরিবর্তন করতে হবে। এটি ওপেন/ক্লোজড প্রিন্সিপালকেও (OCP) ভঙ্গ করে।

Java Code Example: Low Coupling (Good Practice)

Low Coupling অর্জনের জন্য আমরা Dependency Injection (DI) এবং Interface ব্যবহার করব।

// Abstraction introduced
interface Database {
    void connect();
}

class MySQLDatabase implements Database {
    @Override
    public void connect() {
        System.out.println("Connecting to MySQL Database...");
    }
}

class MongoDBDatabase implements Database {
    @Override
    public void connect() {
        System.out.println("Connecting to MongoDB Database...");
    }
}

class UserService {
    private final Database db;

    // Low Coupling: UserService depends on Database interface, not a specific class
    public UserService(Database db) {
        this.db = db;
    }

    public void getUser() {
        this.db.connect();
        System.out.println("Fetching user details from database...");
    }
}

class Main {
    public static void main(String[] args) {
        // Easily switching between databases without changing UserService
        UserService mysqlService = new UserService(new MySQLDatabase());
        mysqlService.getUser();

        UserService mongoService = new UserService(new MongoDBDatabase());
        mongoService.getUser();
    }
}

সুবিধা: এখন UserService জানেই না যে ব্যাকএন্ডে কোন ডেটাবেস কাজ করছে। এটি শুধু Database ইন্টারফেসের ওপর নির্ভর করছে। এটাই হলো Low Coupling।

Cohesion কী এবং High Cohesion কেন জরুরি?

Cohesion (কোহেশন) মানে হলো একটি ক্লাস বা মডিউলের ভেতরের মেথড ও প্রপার্টিগুলো একে অপরের সাথে কতটা সম্পর্কিত বা একই উদ্দেশ্যের জন্য কাজ করছে।

  • Low Cohesion (খারাপ ডিজাইন): যখন একটি ক্লাস অনেকগুলো সম্পর্কহীন (Unrelated) কাজ করে, তখন তাকে Low Cohesion বলে। এই ধরনের ক্লাসগুলোকে সফটওয়্যার ইঞ্জিনিয়ারিংয়ে "God Object" বা "Swiss Army Knife" অ্যান্টি-প্যাটার্ন বলা হয়। এগুলো বোঝা ও মেইনটেইন করা চরম যন্ত্রণাদায়ক।

  • High Cohesion (ভালো ডিজাইন): যখন কোনো ক্লাস শুধু একটি নির্দিষ্ট উদ্দেশ্যেই কাজ করে এবং এর ভেতরের প্রতিটি মেথড সেই উদ্দেশ্যের সাথেই সরাসরি যুক্ত থাকে, তখন তাকে High Cohesion বলে।

লক্ষ্য: প্রতিটি ক্লাস বা মডিউল যেন শুধু একটিমাত্র দায়িত্ব (Focused Responsibility) বহন করে।

Java Code Example: Low Cohesion (Bad Practice)

নিচের Utility ক্লাসটি একই সাথে ডেটাবেস সেভ করা, রিপোর্ট বানানো এবং ইমেইল পাঠানোর মতো সম্পূর্ণ ভিন্ন ভিন্ন কাজ করছে।

class SystemUtility {
    // Handling database
    public void saveUser() {
        System.out.println("Saving user to database...");
    }

    // Handling file generation
    public void generateReport() {
        System.out.println("Generating monthly sales report...");
    }

    // Handling network/communication
    public void sendEmail() {
        System.out.println("Sending welcome email to user...");
    }
}

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

Java Code Example: High Cohesion (Good Practice)

High Cohesion অর্জনের জন্য আমরা কাজগুলোকে তাদের দায়িত্ব অনুযায়ী আলাদা ক্লাসে ভাগ করে দেব।

// Focused on Database operations
class UserRepository {
    public void saveUser() {
        System.out.println("Saving user to database...");
    }
}

// Focused on Report Generation
class ReportGenerator {
    public void generateReport() {
        System.out.println("Generating monthly sales report...");
    }
}

// Focused on Communication
class EmailService {
    public void sendEmail() {
        System.out.println("Sending welcome email to user...");
    }
}

সুবিধা: প্রতিটি ক্লাস এখন অত্যন্ত ফোকাসড। কোড পড়া (Readable), মেইনটেইন করা এবং স্কেল করা এখন অনেক সহজ। কোনো একটি ফিচারে সমস্যা হলে তুমি ঠিক জানো কোন ফাইলে গিয়ে বাগ ফিক্স করতে হবে।

মূল সারাংশ: Low Coupling এবং High Cohesion-এর পার্থক্য

  • Low Coupling: এটি নির্দেশ করে দুটি ভিন্ন মডিউলের মধ্যে সম্পর্ক। মডিউলগুলো একে অপরের ওপর যত কম নির্ভরশীল হবে, সফটওয়্যার তত বেশি স্বাধীন (Independent) ও ফ্লেক্সিবল হবে।

  • High Cohesion: এটি নির্দেশ করে একটি একক মডিউলের ভেতরের কাজের সম্পর্ক। মডিউলের ভেতরের লজিকগুলো যত বেশি ফোকাসড (Focused Responsibility) হবে, কোড তত বেশি অর্গানাইজড হবে।

সংক্ষেপে বলতে গেলে—ভালো কোডিং মানেই হলো এমন একটি আর্কিটেকচার দাঁড় করানো, যেখানে মডিউলগুলো নিজের কাজ নিজে খুব ভালোভাবে করবে (High Cohesion), কিন্তু অন্য মডিউলের কাজে নাক গলাবে না (Low Coupling)।