মিউটেবল (mutable) এবং ইমিউটেবল (immutable)

মিউটেশন (mutation) শব্দটার সাথে আমাদের প্রথম পরিচয় সম্ভবত biology তে। যেখানে আমরা জেনেছি জীনে (gene) মিউটেশন হয়। অর্থাৎ ডি এন এ সিকোয়েন্স পরিবর্তিত হয়ে যায়। মূলকথা হচ্ছে কোনো একটা জিনিস তার আগের অবস্থা থেকে পরিবর্তিত হয়ে গেলে সেটাকে আমরা মিউটেশন বলতে পারি। যেমন আমাদের রাজনীতিবিদদের কথা সম্পূর্ণরূপে মিউটেবল (mutable), কারণ এটা নিয়ত পরিবর্তনশীল।

মজার ব্যাপার হচ্ছে এই কনসেপ্টটা প্রোগ্রামিংয়েও ব্যবহার হয়। আপনি নিজেও হয়তো কাজটা করেছেন কিন্তু জানেন না জিনিসটা আসলে কি বা এটা আসলে কি বোঝায়।

Mutability মূলত অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিংয়ের সাথে রিলেটেড। কোনো একটা অবজেক্ট আমরা তৈরি করার পর সেটাকে যদি আর পরিবর্তন করা না যায় তাহলে সেই অবজেক্টটাকে আমরা বলি ‘ইমিউটেবল (immutable) অবজেক্ট’। খেয়াল করে দেখুন তো এরকম কিছু আপনি আগে কোথাও দেখেছেন কিনা? আপনি যদি Java প্রোগ্রামার হন তাহলে আপনি নিশ্চয়ই জাভার String এবং StringBuffer সম্পর্কে জানেন। যেখানে String হচ্ছে Immutable অর্থাৎ আপনি একটা String অবজেক্ট বানানোর পর সেটাকে আর পরিবর্তন করতে পারবেন না (কিন্তু নতুন আরেকটা String আবার assign করতে পারবেন), কিন্তু StringBuffer এর কোনো একটা অবজেক্টকে আপনি ঠিকই পরিবর্তন করতে পারবেন কারণ এটা Mutable. একইরকম C# এও আছে String এবং StringBuilder. আবার যেমন Python এর List একটা mutable ডাটা স্ট্রাকচার, কিন্তু Tuple হচ্ছে immutable ডাটা স্ট্রাকচার. মোটামুটি সব প্রোগ্রামিং ল্যাংগুয়েজেই mutable, immutable এর ব্যাপারটা কাজে লাগে।

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

আমরা Java তে খুব সিম্পল একটা ক্লাস বানাবো নীচের মত করেঃ

import java.io.*;
class Test
{
public int data;

public Test()
{
this.data = 0;
}

public Test(int init_data)
{
this.data = init_data;
}

public void printData()
{
System.out.println(this.data);
}
}

public class Main
{
public static void main (String[] args)
{
Test myObj = new Test(10);
myObj.printData();

myObj.data = 5;
myObj.printData();
}
}

এখানে খেয়াল করে দেখুন আমরা Test নামে যেই ক্লাস বানিয়েছি সেটার data প্রপারটিটা public. আমরা এই ক্লাস এর অবজেক্ট তৈরি করার পর সেই data প্রপারটিটা আমরা আবার পরিবর্তন করতে পারছি। তারমানে আমরা Test ক্লাসের যেই অবজেক্টই বানাই না কেনো সেটা একটা Mutable অবজেক্ট হবে। আমরা যদি একই ক্লাস আরেকটু ভিন্নভাবে লিখি নীচের মত করেঃ

class Test
{
private int data;

public Test()
{
this.data = 0;
}

public Test(int init_data)
{
this.data = init_data;
}

public void setData(int newData)
{
this.data = newData;
}

public void printData()
{
System.out.println(this.data);
}
}

এখানে আমরা আমাদের data প্রপারটিটাকে private করে দিয়েছি, তারমানে সরাসরি এটাকে চেঞ্জ করা যাবে না। কিন্তু আমরা আবার ঠিকই একটা method দিয়ে দিয়েছি setData() নামে যেটা দিয়ে ঐ প্রপারটিতে ডাটা চেঞ্জ করা যাবে। তারমানে এখনো আমাদের এই ক্লাসের অবজেক্ট Mutable ই হবে। কিন্তু আমরা যদি setData() টা বাদ দিয়ে দেই তাহলেই কিন্তু আমাদের এই অবজেক্টটা Immutable হয়ে যাবে। কারণ initialize করার পরে এই অবজেক্টের প্রপার্টি চেঞ্জ করার আর কোনো সুযোগ থাকছে না।

আশা করি এখন পুরো বিষয়টা বোঝা গেছে।

সুবিধা ও অসুবিধাঃ

ইমিউটেবল অবজেক্টের সবচেয়ে বড় সুবিধা হলো এটা Thread-safe. মানে multi-threaded/concurrent সিস্টেমে আলাদা আলাদা Thread এ এই অবজেক্ট যেহেতু পরিবর্তন হওয়ার সম্ভাবনা নেই সেক্ষেত্রে এই অবজেক্টের state নিয়ে খুব একটা টেনশনে থাকা লাগে না। আবার অন্যদিকে Mutable অবজেক্টের পারফরমেন্স Immutable অবজেক্টের থেকে ভালো। কারণ immutable অবজেক্ট re-use করতে হলে প্রতিবার নতুন করে তৈরি করা লাগে।

আপনি যেই প্রোগ্রামিং ল্যাংগুয়েজই ব্যবহার করেন না কেনো, সেটার নিজস্ব data structure বা library র কোনটা mutable আর কোনটা immutable সেটা জানা না থাকলে আপনি অনেক ক্ষেত্রেই ঝামেলায় পড়বেন। কোড আপনার হিসেব মত কাজ করবে না, অথচ আপনি বুঝতেই পারবেন না সমস্যাটা কোথায়। এজন্য আপনি যেই ল্যাংগুয়েজে কাজ করেন সেটার কোনটা mutable, কোনটা immutable সেটা অবশ্যই জেনে নিন।

mutable এবং immutable অবজেক্ট কখন কোথায় কার্যকর তা Stackoverflow এর এই উত্তরে খুব সুন্দর করে আলোচনা করা হয়েছে।

আজকে এই পর্যন্তই। :)

--

--