Kotlin & Object Invariants – ব্রেইন-ফ্রেন্ডলি ব্যাখ্যা!

 

🧠 Kotlin & Object Invariants – ব্রেইন-ফ্রেন্ডলি ব্যাখ্যা!

🚀 Invariant মানে কি?

👉 Invariant হলো এমন নিয়ম বা শর্ত যা সবসময় একটি অবজেক্টের (Object) জন্য সত্য থাকতে হবে।
💡 অবজেক্ট নিজেই নিশ্চিত করবে যে, এটি কখনো ইনভ্যালিড অবস্থায় থাকবে না।

🎯 Invariant কিভাবে কাজ করে?

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


🛑 কেন Public Fields খারাপ?

👉 যদি একটি ফিল্ড public থাকে, তাহলে বাইরের কেউ সেটাকে পরিবর্তন করতে পারে যেকোনোভাবে!
এই কারণে অবজেক্টের invariant নষ্ট হয়ে যেতে পারে।

খারাপ ডিজাইন (Bad Design):

class BankAccount {
    var balance: Double = 0.0  // ❌ Public field! Invariant নষ্ট হতে পারে।
}

val account = BankAccount()
account.balance = -100.0  // ❌ ব্যালেন্স কখনো নেগেটিভ হওয়া উচিত না!

🔴 Problem:
এখন balance পরিবর্তন করে যে কেউ নেগেটিভ মান সেট করতে পারে, যা ব্যাংক অ্যাকাউন্টের লজিক অনুযায়ী ভুল!


ভালো ডিজাইন (Good Design) - Invariant বজায় রাখা!

💡 Invariant ধরে রাখার জন্য আমরা ফিল্ডগুলো private রাখব এবং মেথড ব্যবহার করে চেক করবো!

class BankAccount(private var balance: Double) {  
    init {
        require(balance >= 0) { "Balance cannot be negative!" }  // ✅ Invariant চেক (Construction Time)
    }

    fun deposit(amount: Double) {
        require(amount > 0) { "Deposit amount must be positive!" }
        balance += amount
    }

    fun withdraw(amount: Double) {
        require(amount > 0 && amount <= balance) { "Invalid withdraw amount!" }
        balance -= amount
    }

    fun getBalance(): Double = balance  // ✅ Only read access
}

val account = BankAccount(500.0)
account.deposit(200.0)
println(account.getBalance())  // ✅ Output: 700.0

// account.balance = -100.0  ❌ এটা সম্ভব না! কারণ balance private।

এখানে ব্যালেন্স কখনো নেগেটিভ হবে না! কারণ:

  • balance ফিল্ড private রাখা হয়েছে।
  • Constructor এবং মেথডে শর্ত চেক করা হয়েছে।
  • Withdraw করার সময় চেক করা হয়েছে ব্যালেন্সের চেয়ে বেশি তোলা যাবে না।

🎯 একটি ফিল্ড যদি Invariant এর অংশ না হয়, তাহলে সেটার এই ক্লাসে থাকা উচিত কি?

👉 যদি কোনো ফিল্ড এই ক্লাসের Invariant এর সাথে সম্পর্কিত না হয়, তাহলে সেটার অন্য কোনো জায়গায় থাকা উচিৎ।
👉 এটা খারাপ ডিজাইনের ইঙ্গিত দেয়, কারণ সেই ফিল্ড ক্লাসের মূল দায়িত্বের সাথে যায় না।

Example:
খারাপ ডিজাইন (Bad Design):

class Car(var model: String, var speed: Int) {  
    var ownerName: String = ""  // ❌ এটা Car ক্লাসের জন্য Invariant নয়!
}

🔴 Problem:

  • Car এর মূল কাজ হলো গাড়ির গতি, মডেল ইত্যাদি নিয়ে কাজ করা, কিন্তু "ownerName" তার অংশ নয়।
  • এটা আলাদা "Owner" ক্লাসে থাকা উচিত।

ভালো ডিজাইন (Good Design) - আলাদা ক্লাস ব্যবহার করা:

class Car(val model: String, var speed: Int)  
class Owner(val name: String, val car: Car)

🔹 এখন "Car" এবং "Owner" আলাদা হয়েছে, যা ভালো ডিজাইন!


🚀 সংক্ষেপে:

Invariant হলো অবজেক্টের জন্য একটি অপরিবর্তনীয় শর্ত, যা সবসময় মেনে চলতে হবে।
Private ফিল্ড ব্যবহার করুন এবং মেথডের মাধ্যমে পরিবর্তন করুন, যেন Invariant ঠিক থাকে।
Public ফিল্ড খারাপ, কারণ এটা সহজেই ভাঙতে পারে।
যদি কোনো ফিল্ড Invariant এ অংশ না নেয়, তাহলে সেটাকে আলাদা করা ভালো ডিজাইন।


🎯 এখন আপনি Invariant, Public Fields, এবং ভালো ডিজাইন বুঝে গেছেন! 🏆🔥

👉 এবার কোড প্র্যাকটিস শুরু করে দিন! 😎

Comments

Popular posts from this blog

AI (Artificial Intelligence) সহজভাবে বোঝার জন্য একদম মস্তিষ্ক-বান্ধব ব্যাখ্যা 🧠🤖

🧠 Regex কী?

Kotlin-এ ভেরিয়েবল ঘোষণা করার দুই উপায়