কোড লেখার সময় ভ্যারিয়েবল, ক্লাস, ফাংশন এর নাম যেন অর্থপূর্ণ হয় এটা খেয়াল রাখতে হবে। যাতে অন্য কেউ এই নাম দেখে বুঝতে পারে এইটার কাজ কি অথবা কি উদ্দেশে তৈরী করা। একটা অর্থপূর্ণ নাম বাছাই করতে গেলে কিছু বেশি সময়ের প্রয়োজন কিন্তু এটা আপনাকে ভবিষ্যতে ভাল ফল দিবে। কোন ভ্যারিয়েবল/ক্লাস/ফাংশন নামের পাশে যদি বুঝানোর জন্য আলাদা করে কমেন্ট লিখতে হয় তাহলে বুঝতে হবে আপনার নাম অর্থপূর্ণ হয় নি।
int d; // elapsed time in days
এখানে d দ্বারা কিছুই বোঝা যায় না, এই ভ্যারিয়েবল আসলে কি জন্য। এই ক্ষেত্রে ভ্যারিয়েবল লিখতে হবে আমি দিনের সংখ্যা রাখব সেটা কিসের এবং গণনা করার ইউনিট সহ।
int elapsedTimeInDays;
int daysSinceCreation;
int daysSinceModification;
int fileAgeInDays;
নাম অর্থপূর্ণ হলে সেটা বুঝতে এবং তা নিয়ে কাজ করতে সহজ হয়। নিচের কোডটা লক্ষ্য করুনঃ
public List<int[]> getThem() {
List<int[]> list1 = new ArrayList<int[]>();
for (int[] x : theList)
if (x[0] == 4)
list1.add(x);
return list1;
}
উপরের কোডটা কিন্তু খুবই সাধারণ, কোন জটিল ব্যপার নেই। লিস্ট এবং ফর লুপ আছে, সব কিছুই ঠিকঠাক বলে মনে হচ্ছে। কিন্তু সমস্যা হচ্ছে এখানে বোঝার কোন উপায় নেই এই কোডটা কেন করা এবং এই লিস্ট, ভ্যারিয়েবল এর কি তথ্য বহন করে। এখনে ০ তম ভ্যালুতে কি আছে এবং ৪ দিয়ে কি বোঝায়।
প্রোগ্রামারের উচিত সবসময় ভুল অর্থ প্রকাশ করে এমন নাম থেকে বিরত থাকা। সঠিকভাবে যেন বোঝা যায় এমন নাম দেওয়া উচিত। আপনি Bank Account এর ভ্যারিয়েবল যদি ছোট করে ba লিখেন এটা কারোর পক্ষে বোঝা কষ্টকর এর ভেতরে কিসের তথ্য আছে। কোন ভ্যারিয়েবল ব্যবহার করলে খেয়াল রাখবেন এটার বানান সব জায়গায় যেন একই রকম থাকে। ভ্যারিয়েবল হিসেবে 'O' ব্যবহার থেকে বিরত থাকবেন কারণ এটা শূন্য নাকি 'O' এটা বুঝতে সমস্যা হতে পারে।
প্রোগ্রামাররা তাদের জন্য সমস্যা তৈরি করে যখন তারা শুধুমাত্র একটি compiler বা interpreter কে সন্তুষ্ট করার জন্য কোড লিখে। যেমন আমরা একই নামের ভ্যরিয়েবল দিয়ে ২ টা আলাদা জিনিস রাখতে পারবো না একই scope এর মধ্যে। কিন্তু আমরা চাইলে ভ্যরিয়েবল এর বানান একটু পরিবর্তন করে কাজ চালিয়ে নিতে পারবো। অধিকাংশ সময় আমরা নাম্বার সিরিজ নাম দিয়ে ফেলি যেমন - (a1, a2, .. aN). এটা দিয়ে বোঝা যাবে না কোন কিছুই। নিচের কোডটা একটু খেয়াল করলে বুঝবেন।
public static void copyChars(char a1[], char a2[]) {
for (int i = 0; i < a1.length; i++) {
a2[i] = a1[i];
}
}
এখানে যদি ভ্যরিয়েবল নাম দিতেন source এবং destination তাহলে এটা পোরে আরও ভাল বোঝা যেত।
মানুষ স্বভাবজাতভাবেই শব্দের ব্যবহারে অভস্ত্য। যেকোন শব্দ বললে মানুষ সহজেই বুঝতে পারে সেটা কি। তাহলে আমাদের উচিত ভাষায় ব্যবহার করা হয় এমন শব্দ ব্যবহার করা। আপনি এমন কোন ভ্যরিয়েবল নেম দিলেন যেটা উচ্চারণ করা যায় না এটা একটা খারাপ প্রাকটিস। নিচে দুইটা কোডের উদাহরণ দিলে আমরা বুঝতে পারবো।
class DtaRcrd102 {
private Date genymdhms;
private Date modymdhms;
private final String pszqint = "102";
/* ... */
};
class Customer {
private Date generationTimestamp;
private Date modificationTimestamp;;
private final String recordId = "102";
/* ... */
};
প্রথম কোডে লক্ষ্য করে দেখা যায় ক্লাস এবং ভ্যারিয়েবল দেখে বোঝার উপায় নাই এইটা কি আসলে। এবং কারো সাথে শেয়ার করার সময় ও এটা বোঝানো কঠিন কারন এটা উচ্চারণযোগ্য নয়। কিন্তু দ্বিতীয় কোডটা দেখে কিন্তু সহজেই আপনি উচ্চারণ করে অন্যকে শেয়ার করতে পারবেন। অন্য ডেভেলপার দেখলে এটা বুঝতে পারবে তাকে ব্যাখ্যা করার ও প্রয়োজন নেই।
নাম দেওয়ার ক্ষেত্রে সবসময় এমনভাবে দেওয়া উচিত যাতে সেটা আমরা সার্চ দিয়ে খুঁজে বের করতে পারি খুব সহজেই। যদি একটা ভ্যারিয়েবলের নাম দেওয়া হয় একটা ডিজিট অথবা লেটার তাহলে এটা পরে খুঁজে বের করা কঠিন। লোকাল ভ্যারিয়েবলের নাম এভাবে দিলে সেটা সমস্যা খুব কম। যদি কোন ভ্যারিয়েবল নাম হয় 'MAX_CLASSES_PER_STUDENT' তাহলে এই নাম কিন্তু অনুসন্ধানযোগ্য। পরবর্তীতে অন্য ডেভেলপার সেটা খুব সহজেই খুঁজে পাবে ব্যবহারের জন্য।
for (int j=0; j<34; j++) {
s += (t[j]*4)/5;
}
int realDaysPerIdealDay = 4;
const int WORK_DAYS_PER_WEEK = 5;
int sum = 0;
for (int j=0; j < NUMBER_OF_TASKS; j++) {
int realTaskDays = taskEstimate[j] * realDaysPerIdealDay;
int realTaskWeeks = (realdays / WORK_DAYS_PER_WEEK);
sum += realTaskWeeks;
}
উপরের কোড দুইটা কিন্তু একই কাজ করে তবে নিচেরটা দেখলে বোঝা যায় এইটা বড় কোড বেজের ভেতরে খুব সহজেই খুঁজে সম্ভব।
ক্লাসের নাম সবসময় noun দেওয়া উচিত। যেমনঃ Customer, WikiPage, Account
ক্লাসের নাম সবসময় verb দেওয়া উচিত। যেমনঃ postPayment, deletePage, save
ফাংশন সব সময় ছোট হওয়া উচিত। কারন ছোট ফাংশনের অনেক সুবিধা আছে কারন এটা প্রোগ্রামারদের কোড সহজে বুঝতে সাহায্য করে। যখন একটি ফাংশন দেখি আমরা স্ক্রিনে তখন যদি এটা পুরো স্ক্রিনের ভেতরে থাকে তাহলে এটা পড়া আমাদের জন্য সহজ হয়। কিন্তু এটা যদি আমাদের স্ক্রল করে পড়তে হয় তাহলে এটা বিরক্তিকর এবং সময় সাপেক্ষ। বর্তমানে মনিটর গুলোতে এক লাইনে ১৫০ ক্যারেক্টার ধরে যায় আর লাইন ধরে ১০০ এর বেশি। কিন্তু তারপর ও ফাংশনে ১৫০ ক্যারেক্টার এবং ১০০ লাইন হওয়া উচিত নয়। ফাংশনের লাইন সংখ্যা হওয়া উচিত সর্বোচ্চ ২০ তাও খুব কম জায়গায় যেখানে না হলে নয়। এখন একটা প্রশ্ন মনে হতে পারে, ফাংশন কত ছোট হতে পারে। এটা ২ ৩ লাইন ও হতে পারে।
ফাংশন সবসময় একটা কাজের জন্য বানানো উচিত। ধরুন, আপনি একটা মেথড লিখছেন যেখানে আপনি একজন ইউজারের ব্যাক্তিগত তথ্য এবং ব্যাংকিং তথ্য সেভ করতে চান। কিন্তু এখানে একটা সমস্যা হল আপনি এই ফাংশনকে শুধু ব্যাক্তিগত তথ্য অথবা ব্যাংকিং তথ্য সেভ করতে পারবেন না। এই জন্য কখনোই বিভিন্ন ধরনের কাজ একই ফাংশনে লেখা পরিহার করা উচিত।
ফাংশনের নাম হবে এমন যেন দেখলেই বোঝা যায় এই ফাংশনের কি কাজ করে। নাম বড় হলেও সমস্যা নাই যদি কিনা নামটা ভাল বর্ণনামূলক হয়। ভাল নাম যদি দেওয়া যায় তাহলে এটা ভবিষ্যতের জন্য অনেক ভাল maintainable হবে।
ফাংশন আর্গুমেন্ট অথবা প্যারামিটারের কয়েক ধরন আছে। যেমনঃ niladic(শূন্য আর্গুমেন্ট), monadic(একটা আর্গুমেন্ট), dyadic(দুইটা আর্গুমেন্ট), triadic(তিনটা আর্গুমেন্ট)। তিন আর্গুমেন্ট বিশিষ্ট ফাংশন লেখা থেকে বিরত থাকা উচিত।
আমাদেরকে কোড করার সময় খেয়াল রাখতে হবে ভাল এবং ক্লিন কোড লেখার। আমরা যদি ভাবি আমাদের খারাপ কোডকে কমেন্ট দিয়ে মেক আপ দিব তাহলে এটা স্ট্যান্ডার্ড না।
অনেক সময় কোডের ভেতরে কিছু তথ্য রাখা দরকার হয়। যেমনঃ কে কোড লিখছে, কোন সালে লেখা, লাইসেন্স বিষয়ক তথ্য ইত্যাদি।
// Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved.
// Released under the terms of the GNU General Public License version 2 or later.
কোন কাজ যদি ভবিষ্যতে করার প্লান করা হয় তাহলে সেটা কোডের সাথে নোট করে রাখা হয়।
//TODO-MdM these are not needed
// We expect this to go away when we do the checkout model
protected VersionInfo makeVersion() throws Exception
{
return null;
}
অনেক সময় কোডের উপরে এমন কমেন্ট লেখা হয় যেটা সম্পূর্ণ অপ্রয়োজনীয়। কোড কি কাজ করে সেটা বর্ণনা দেওয়ার জন্য অনেকে লিখে থাকে, সেটা কোড দেখেই বুঝতে পারা উচিত।
// Utility method that returns when this.closed is true. Throws an exception // if the timeout is reached.
public synchronized void waitForClose(final long timeoutMillis) throws Exception {
if(!closed) {
wait(timeoutMillis);
if(!closed)
throw new Exception("MockResponseSender could not be closed");
}
}
কিছু কমেন্টে গুরুত্বপূর্ণ কিছু থাকে না, শুধু গোলমাল মন্তব্য থাকে।
/**
* Default constructor. */
protected AnnualDateRule() { }