Meaningful Naming

তুমি যদি একটি কোডবেসকে একটি গল্পের বইয়ের মতো ভাবো, তবে কোডের নামগুলো (ভেরিয়েবল, ফাংশন, ক্লাস) হলো সেই গল্পের চরিত্র। গল্পের চরিত্রগুলো যদি নামহীন হয়, কিংবা তাদের নাম শুনে যদি তাদের ভূমিকা কিছুই বোঝা না যায়, তবে সেই গল্প পড়া যেমন বিরক্তিকর ও কষ্টকর হয়ে দাঁড়ায়, তেমনি অর্থহীন নামবিশিষ্ট কোডও পড়ে বোঝা অসম্ভব কঠিন হয়ে পড়ে।

তাই ভালো ও পরিচ্ছন্ন কোড (Clean Code) লেখার প্রথম এবং অন্যতম প্রধান শর্ত হলো- Meaningful Naming বা অর্থবহ নামকরণ।

Meaningful Naming বলতে কী বোঝায়?

Meaningful Naming বলতে বোঝায়— ভেরিয়েবল, ফাংশন, ক্লাস, কনস্ট্যান্ট বা যেকোনো আইডেন্টিফায়ারের এমনভাবে নামকরণ করা, যেন শুধুমাত্র নাম দেখেই তার উদ্দেশ্য, কাজ এবং ব্যবহারের প্রেক্ষাপট পুরোপুরি পরিষ্কার হয়ে যায়। এর জন্য কোড ঘেঁটে বা কমেন্ট পড়ে বোঝার দরকার পড়বে না।

"A good name is a short definition."

— Kent Beck (Creator of Extreme Programming)

নামকরণের গুরুত্ব এত বেশি কেন?

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

  • Readable Code (পঠনযোগ্য কোড) তৈরি হয়: কোড শুধু মেশিনের এক্সিকিউট করার জন্য নয়, মানুষের পড়ার জন্যও। নাম দেখেই কাজ বোঝা গেলে কোডের ফ্লো বুঝতে সময় লাগে না।

  • Maintainability (রক্ষণাবেক্ষণ) সহজ হয়: সময়ের সাথে প্রজেক্ট বড় হয় এবং কোডে পরিবর্তন আনতে হয়। অর্থপূর্ণ নাম থাকলে কয়েক মাস পর নিজের লেখা কোড দেখে আর কনফিউজড হতে হয় না।

  • Bug (বাগ) ধরতে সহায়তা করে: স্পষ্ট নাম থাকলে ডেটার ফ্লো ট্রেস করা সহজ হয়। ভুল ভ্যালু পাস হলে নাম দেখেই অনেক সময় লজিক্যাল এরর ধরা পড়ে যায়।

  • Searchability (সহজে খুঁজে পাওয়া): বড় কোডবেসে কাজ করার সময় নির্দিষ্ট কনটেক্সট খুঁজে বের করতে search করতে হয়। সিঙ্গেল লেটার বা অ্যাব্রেভিয়েশন (যেমন: e, t, usr) দিয়ে সার্চ করা কঠিন, কিন্তু elapsedTimeInDays দিয়ে সার্চ করলে সহজেই কাঙ্ক্ষিত জায়গা পাওয়া যায়।

খারাপ নাম বনাম ভালো নাম: বাস্তব উদাহরণ

নিচে পাইথন এবং জাভা ব্যবহার করে নামকরণের কিছু ভালো ও খারাপ উদাহরণ দেওয়া হলো:

১. ভেরিয়েবল নামকরণ (Java):

// Bad: What does 'd' mean? Is it distance? days? data?
int d = 5; 

// Good: Intention is completely clear
int elapsedTimeInDays = 5;

২. ফাংশনের নাম (Python):

# Bad: Too vague. Handle what?
def handle():
    pass

# Good: Clearly states the action and the entity
def process_user_registration():
    pass

৩. বুলিয়ান (Boolean) ভেরিয়েবল (Java):

// Bad: Does not sound like a true/false question
boolean flag = true;
boolean login = false;

// Good: Sounds like a question with a yes/no answer
boolean isUserAuthenticated = true;
boolean hasAdminPrivileges = false;

৪. ম্যাজিক নাম্বার ও সংক্ষেপণ পরিহার (Python):

# Bad: 'q' is meaningless. What is 86400?
q = get_data()
timeout = 86400

# Good: Descriptive name and meaningful constant
user_list = fetch_active_users()
SECONDS_IN_A_DAY = 86400

Meaningful Naming এর Best Practices

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

  • প্রকৃত কাজ ও উদ্দেশ্য বোঝাতে নাম দাও (Reveal Intention): নাম এমন হওয়া উচিত যা ফাংশন বা ভেরিয়েবলের উদ্দেশ্য পরিষ্কার করে। যেমন: temp এর বদলে loggedInUser বা temporaryFileRef ব্যবহার করো।

  • Boolean ভেরিয়েবলের ক্ষেত্রে প্রিফিক্স (Prefix) ব্যবহার করো: বুলিয়ান ভ্যালুগুলো সবসময় is, has, can, should দিয়ে শুরু করা উচিত। যেমন: isActive, hasPermission, canDelete ইত্যাদি।

  • অস্পষ্ট শব্দ (Vague words) এড়িয়ে চলো: data, value, info, thing, stuff, manager, processor—এই শব্দগুলো খুব সাধারণ এবং এদের নিজস্ব কোনো নির্দিষ্ট অর্থ নেই। যেমন: userInfo এর চেয়ে userFullName বা userAddress অনেক বেশি সুনির্দিষ্ট।

  • উচ্চারণযোগ্য নাম ব্যবহার করো (Pronounceable Names): কোড নিয়ে টিমের সাথে কথা বলার সময় নামগুলো উচ্চারণ করতে হয়। genymdhms (Generation year, month, day, hour, minute, second) এর মতো নাম না দিয়ে generationTimestamp ব্যবহার করা ভালো।

কিছু সাধারণ ভুল ও তার সঠিক রূপ

ভুল (Bad Naming)

সঠিক (Good Naming)

কারণ (Reason)

handle()

handleFormSubmit()

নির্দিষ্ট করে বলা হয়েছে কী হ্যান্ডেল করা হচ্ছে।

data

orderList, userData

কনটেক্সট ক্লিয়ার করা হয়েছে।

temp

swappedValue, tempFilePath

টেম্পোরারি ভ্যারিয়েবলটি কীসের জন্য তা বোঝানো হয়েছে।

doTask()

generateInvoicePdf()

মেথডটি ঠিক কী কাজ (Action) করছে তা স্পষ্ট।

get()

getUserDetails()

কী আনা হচ্ছে তা নির্দিষ্ট করা হয়েছে।

নামকরণে Consistency বা ধারাবাহিকতা

পুরো কোডবেস জুড়ে "One Word per Concept" নিয়ম মেনে চলা উচিত।

ধরো, তুমি ইউজারের ডেটা আনার জন্য getUserDetails() লিখলে। এরপর প্রোডাক্টের ডেটা আনার জন্য যদি fetchProductInfo() লেখো এবং অর্ডারের জন্য retrieveOrders() লেখো, তবে তা কনফিউশন তৈরি করবে। একই ধরনের কাজের জন্য (ডেটা আনা) পুরো প্রজেক্টে যেকোনো একটি স্টাইল (get, fetch বা retrieve) ফিক্স করে নাও এবং সব জায়গায় সেটাই ব্যবহার করো।

টিমে কাজ করার ক্ষেত্রে কিছু কার্যকরী টিপস

  • Naming Convention Guide: টিমের সবার জন্য একটি গাইডলাইন তৈরি করো। ক্লাস, মডেল, সার্ভিস, ইউটিলিটি ফাইল—এগুলোর নামকরণ কীভাবে হবে তা আগে থেকেই ঠিক করে নাও। (যেমন: ইন্টারফেসের নামের শেষে Interface বা শুরুতে I থাকবে কি না)।

  • Code Review: কোড রিভিউর সময় লজিকের পাশাপাশি নামকরণের দিকেও কড়া নজর রাখো। নাম অস্পষ্ট হলে তা রিফ্যাক্টর করতে বলো।

  • Domain Driven Naming: যে ডোমেইনে কাজ করছো (যেমন: ই-কমার্স, হেলথকেয়ার, ফিন্যান্স), সেই ডোমেইনের পরিচিত টার্মগুলো (Business terms) কোডে ব্যবহার করো, যাতে নন-টেকনিক্যাল মানুষের সাথেও কথা বলতে সুবিধা হয়।

ক্লিন কোডের ভিত্তি: একটি পরিচ্ছন্ন কোডবেস

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

সবশেষে বিখ্যাত প্রোগ্রামার John Woods এর সেই অমর উক্তিটি সবসময় মাথায় রেখো:

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."

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