রিফ্যাক্টর করা একটি IT স্ল্যাং শব্দ যার অর্থ কোডের বাইরের আচরণ পরিবর্তন না করে এর অভ্যন্তরীণ কাঠামো পরিবর্তন করা। রিফ্যাক্টরিংয়ের লক্ষ্য কোড পরিষ্কার, বোধগম্য এবং রক্ষণাবেক্ষণ করা সহজ করা। Martin Fowler-এর বই “Refactoring: Improving the Design of Existing Code” (Addison-Wesley, 2019) অনুসারে, রিফ্যাক্টরিং কোড বেসের স্বাস্থ্য বজায় রাখার জন্য একটি বাধ্যতামূলক অনুশীলন, এবং এর নিয়মিত প্রয়োগ প্রকল্পের মোট মালিকানা খরচ 20-30% কমিয়ে দেয়।
মূল বিষয়
রিফ্যাক্টর করা হল সফটওয়্যার কোডের অভ্যন্তরীণ কাঠামো পরিবর্তনের প্রক্রিয়া যার পর্যবেক্ষণযোগ্য আচরণ পরিবর্তন না করে এর গুণগত বৈশিষ্ট্যের উন্নতি করা। শব্দটি Martin Fowler 1999 সালে ব্যাপক ব্যবহারে প্রবর্তন করেন, এবং অনুশীলনটি নিজেই এজাইল ডেভেলপমেন্ট এবং এক্সট্রিম প্রোগ্রামিংয়ের ভিত্তিগুলোর একটি হয়ে ওঠে।
রিফ্যাক্টরিংয়ের মূল বৈশিষ্ট্য হল কার্যকারিতা সংরক্ষণ। রিফ্যাক্টরিংয়ের পরে, প্রোগ্রামটিকে অবশ্যই পরিবর্তনের আগের মতোই একই কাজ সম্পাদন করতে হবে এবং একই ফলাফল ফেরত দিতে হবে। এর নিশ্চয়তা হল স্বয়ংক্রিয় পরীক্ষা, যা রিফ্যাক্টরিংয়ের প্রতিটি মাইক্রো-পদক্ষেপের পরে চালানো হয়। যদি পরীক্ষা সবুজ হয় — আচরণ সংরক্ষিত। যদি লাল হয় — রিফ্যাক্টরিং ভুলভাবে করা হয়েছে বা আচরণ পরিবর্তন হয়েছে, যার অর্থ এটি আর রিফ্যাক্টরিং নয় বরং কার্যকারিতার পরিবর্তন।
শিল্পে একটি ভুল ধারণা রয়েছে: যেকোনো কোড মেরামতকে রিফ্যাক্টরিং বলা হয়। বাস্তবে, আচরণ পরিবর্তনের সাথে কোড পুনর্লিখন হল “রিরাইট” বা “রিওয়ার্ক”, রিফ্যাক্টরিং নয়। পার্থক্য মৌলিক: রিফ্যাক্টরিং একটি নিয়ন্ত্রিত, নিরাপদ প্রক্রিয়া, যেখানে যুক্তি পরিবর্তনের সাথে পুনর্লিখন হল সম্পূর্ণ নতুন উন্নয়ন সব সংশ্লিষ্ট ঝুঁকি সহ।
রিফ্যাক্টরিং সম্পর্কে জ্ঞানের মূলধন বাংলাভাষী পরিবেশে অন্যান্য IT শব্দের মতো একই পদ্ধতিতে ঘটে: ইংরেজি “refactor”-এর অনুসরণে বাংলা ক্রিয়া প্রত্যয় যোগ করে। সফটওয়্যার ইঞ্জিনিয়ারিংয়ে শিক্ষামূলক প্রোগ্রাম এবং বইয়ের অনুবাদ পেশাদার শব্দভাণ্ডারে এই শব্দটি প্রতিষ্ঠিত করেছে।
রিফ্যাক্টরিংকে সম্পূর্ণ কোড পুনর্লিখন (rewrite) থেকে আলাদা করা গুরুত্বপূর্ণ। রিফ্যাক্টরিং হল ছোট, নিরাপদ রূপান্তরের একটি সিরিজ, যার প্রতিটি আচরণ সংরক্ষণ করে। পুনর্লিখন হল শুরু থেকে একটি নতুন বাস্তবায়ন তৈরি করা, প্রায়শই আর্কিটেকচার, প্রযুক্তি এবং আচরণের পরিবর্তনের সাথে। Standish Group (2023)-এর গবেষণা দেখায় যে সম্পূর্ণ পুনর্লিখন বেছে নেওয়া প্রকল্পগুলি 40% ক্ষেত্রে ব্যর্থ হয়, যেখানে নিয়মিত রিফ্যাক্টরিং অনুশীলনকারী প্রকল্পগুলিতে 25% কম প্রযুক্তিগত ঋণ থাকে।
রিফ্যাক্টরিং বেশ কয়েকটি মূল কাজ সমাধান করে, যার প্রতিটি সরাসরি উন্নয়নের গতি এবং ব্যয়কে প্রভাবিত করে। এই লক্ষ্যগুলি বোঝা দলকে সঠিকভাবে অগ্রাধিকার নির্ধারণ করতে এবং স্টেকহোল্ডারদের কাছে রিফ্যাক্টরিংয়ে ব্যয় করা সময়কে ন্যায়সঙ্গত করতে সহায়তা করে।
কোড একবার লেখা হয় কিন্তু ডজন ডজন এবং শত শত বার পড়া হয়। যদি একজন ডেভেলপার একটি ফাংশন কী করে তা বুঝতে 30 মিনিট ব্যয় করে — এটি উৎপাদনশীলতার সরাসরি ক্ষতি। পঠনযোগ্য কোড জ্ঞানীয় লোড হ্রাস করে এবং দলের নতুন সদস্যদের অনবোর্ডিং ত্বরান্বিত করে। Rename Method, Extract Variable এবং Introduce Explaining Variable-এর মতো কৌশলগুলি কোড স্পষ্টতা উন্নত করার লক্ষ্যে। Developer Productivity (Microsoft Research, 2023)-এর গবেষণা অনুসারে, ডেভেলপাররা তাদের 60% সময় কোড লেখার পরিবর্তে পড়তে ব্যয় করে, যা পঠনযোগ্যতাকে উৎপাদনশীলতার প্রধান কারণগুলির একটি করে তোলে।
DRY (Don’t Repeat Yourself) নীতি প্রোগ্রামিংয়ের মৌলিক বিষয়গুলির একটি। কোড ডুপ্লিকেশন একই পরিবর্তন একাধিক জায়গায় করতে বাধ্য করে, যা ত্রুটি এবং ভুলে যাওয়া সম্পাদনার ঝুঁকি বাড়ায়। Extract Method এবং Pull Up Method কৌশল সহ রিফ্যাক্টরিং ডুপ্লিকেশন দূর করে এবং যুক্তিকে কেন্দ্রীভূত করে।
চক্রীয় জটিলতা এবং নেস্টিং গভীরতার মেট্রিকগুলি সরাসরি কোডে ত্রুটির সংখ্যার সাথে সম্পর্কযুক্ত। যদি একটি ফাংশনের চক্রীয় জটিলতা 10-15-এর উপরে হয়, তবে এটি পরীক্ষা করা কঠিন এবং ভাঙ্গা সহজ। Replace Conditional with Polymorphism, Decompose Conditional এবং Extract Method ব্যবহার করে রিফ্যাক্টরিং জটিলতা নিয়ন্ত্রণযোগ্য স্তরে হ্রাস করে। NIST (2024)-এর গবেষণা দেখায় যে উচ্চ জটিলতার মডিউলগুলিতে প্রতি হাজার লাইন কোডে 2-3 গুণ বেশি ত্রুটি থাকে।
রিফ্যাক্টরিংয়ের একটি প্রধান কারণ হল নতুন কার্যকারিতা যোগ করার প্রয়োজন। যদি বর্তমান কোড কাঠামো বিদ্যমান আচরণ না ভেঙে পরিবর্তন করতে না দেয়, তবে রিফ্যাক্টরিং ভূমি প্রস্তুত করতে সাহায্য করে। “ক্যাম্পিং নিয়ম” (কোড আপনি যেভাবে পেয়েছেন তার চেয়ে পরিষ্কার রেখে যান) Martin Fowler-এর একটি সুপারিশ যা রিফ্যাক্টরিংকে মাঝে মাঝে কার্যকলাপ থেকে ধ্রুবক অনুশীলনে রূপান্তরিত করে।
GitHub-এ 500 ওপেন-সোর্স প্রকল্পের বিশ্লেষণের ডেটা (IEEE Transactions on Software Engineering, 2024) দেখায় যে নিয়মিত রিফ্যাক্টরিংযুক্ত প্রকল্পগুলিতে 30% কম “কোড স্মেল” (code smells) এবং 15% কম প্রযুক্তিগত ঋণ সূচক থাকে যেখানে রিফ্যাক্টরিং মাঝে মাঝে করা হয় তার তুলনায়।
Martin Fowler তাঁর বইতে 70টিরও বেশি রিফ্যাক্টরিং কৌশল তালিকাভুক্ত করেছেন। বাস্তবে, বেশিরভাগ দল নিয়মিতভাবে 10-15টি ব্যবহার করে। আসুন মূল কৌশলগুলি দেখি যা প্রতিটি ডেভেলপারের জানা উচিত।
সবচেয়ে বেশি ব্যবহৃত কৌশল। যদি কোডের একটি অংশকে অর্থগতভাবে আলাদা ফাংশনে নিষ্কাশন করা যায় — তবে তা করা উচিত। Extract Method পঠনযোগ্যতা উন্নত করে, অপারেশনকে একটি নাম দেওয়ার অনুমতি দেয় এবং পরীক্ষা সহজ করে। নিয়ম: যদি আপনি একটি মন্তব্য দেখেন যা ব্যাখ্যা করে কোডের একটি ব্লক কী করে — সেই ব্লকটি একটি আলাদা মেথডে নিষ্কাশন করা যেতে পারে।
// রিফ্যাক্টরিংয়ের আগে
double total = amount * price;
double discounted = total * (1 - discountRate);
double tax = discounted * taxRate;
// রিফ্যাক্টরিংয়ের পরে
double total = calculateTotal(amount, price);
double finalPrice = applyDiscountAndTax(total);
নামটি সারাংশ প্রতিফলিত করা উচিত। যদি একটি ভেরিয়েবল বা মেথডের নাম প্রশ্নের উত্তর না দেয় “এখানে কী সংরক্ষিত/করা হয়” — তবে এটির নাম পরিবর্তন করা প্রয়োজন। আধুনিক IDE এই অপারেশনটি তুচ্ছ করে তোলে। পরিষ্কার নাম কোড উন্নত করার সবচেয়ে সস্তা এবং কার্যকর উপায়।
যখন শর্তসাপেক্ষ যুক্তি বেড়ে গেছে এবং বিভ্রান্তিকর হয়ে গেছে, পলিমরফিজম একটি পরিষ্কার বিকল্প প্রস্তাব করে। টাইপ অনুসারে switch-case-এর পরিবর্তে — একটি ওভাররাইড মেথড সহ ক্লাস হায়ারার্কি তৈরি করুন। পলিমরফিজম কোডকে প্রসারণযোগ্য করে: একটি নতুন টাইপ যোগ করার জন্য বিদ্যমান শর্ত পরিবর্তনের প্রয়োজন হয় না, শুধুমাত্র একটি নতুন সাবক্লাস তৈরি করা।
// রিফ্যাক্টরিংয়ের আগে (শর্তসাপেক্ষ)
if (type.equals("email")) {
sendEmail(message);
} else if (type.equals("sms")) {
sendSms(message);
}
// রিফ্যাক্টরিংয়ের পরে (পলিমরফিজম)
Notifier notifier = new EmailNotifier();
notifier.send(message);
যখন একটি ফাংশন অনেক বেশি প্যারামিটার নেয় (3-4-এর বেশি), সেগুলি পড়া এবং পাস করা কঠিন। সম্পর্কিত প্যারামিটারগুলিকে একটি প্যারামিটার অবজেক্টে গ্রুপ করা সিগনেচার ছোট করে, পঠনযোগ্যতা উন্নত করে এবং ভবিষ্যতের পরিবর্তন সহজ করে।
| কৌশল | উদ্দেশ্য | কখন প্রয়োগ করবেন |
|---|---|---|
| Extract Method | যুক্তি আলাদা ফাংশনে নিষ্কাশন | কোড ব্লক এক বাক্যে বর্ণনা করা যায় |
| Rename Variable | ভেরিয়েবল/মেথডের নাম স্পষ্ট করা | নাম সারাংশ প্রতিফলিত করে না |
| Replace Conditional | switch-case-কে পলিমরফিজম দিয়ে প্রতিস্থাপন | অবজেক্ট টাইপের উপর ভিত্তি করে শর্ত |
| Extract Interface | ক্লাস থেকে চুক্তি নিষ্কাশন | ঢিলেঢালা কাপলিং প্রয়োজন |
রিফ্যাক্টর করার সিদ্ধান্ত প্রযুক্তিগত নয় বরং ব্যবস্থাপনাগত। এটির জন্য বর্তমান উৎপাদনশীলতা এবং দীর্ঘমেয়াদী কোড বেস স্বাস্থ্যের মধ্যে ভারসাম্য প্রয়োজন। আসুন সাধারণ পরিস্থিতিগুলি পরীক্ষা করি যখন রিফ্যাক্টরিং ন্যায়সঙ্গত এবং কখন বিরত থাকা ভাল।
প্রথম পরিস্থিতি — আপনি যে কোড পরিবর্তন করতে হবে তা বুঝতে পারেন না। যদি বিদ্যমান কোড বুঝতে নতুন কার্যকারিতা বাস্তবায়নের চেয়ে বেশি সময় লাগে — এটি প্রথমে রিফ্যাক্টর করার সংকেত। দ্বিতীয় পরিস্থিতি — আপনি ডুপ্লিকেশন পেয়েছেন যা উন্নয়ন ধীর করে এবং ত্রুটির ঝুঁকি বাড়ায়। তৃতীয় — বিদ্যমান কাঠামো ব্যাহত না করে নতুন কার্যকারিতা যোগ করা অসম্ভব।
এছাড়াও রিফ্যাক্টর করা উচিত যখন কোড বেসে “কোড স্মেল” (code smells) থাকে: লম্বা মেথড, বড় ক্লাস, অত্যধিক মন্তব্য, কল চেইন, সমান্তরাল ইনহেরিটেন্স হায়ারার্কি। Fowler-এর বই থেকে কোড স্মেল ক্যাটালগে 20টিরও বেশি সাধারণ সমস্যা সূচক রয়েছে, প্রতিটির জন্য একটি সংশ্লিষ্ট রিফ্যাক্টরিং কৌশল রয়েছে।
রিফ্যাক্টরিং প্রয়োজন নয় যদি কোড স্থিরভাবে কাজ করে এবং এটি পরিবর্তনের পরিকল্পনা না থাকে। নীতি “যদি এটি ভাঙ্গা না হয় তবে এটি ঠিক করবেন না” (if it ain’t broke, don’t fix it) বিশেষ করে সেই কোডের জন্য প্রাসঙ্গিক যা খুব কমই পরিবর্তিত হয়। রিফ্যাক্টরিংয়ের জন্য রিফ্যাক্টরিং ইঞ্জিনিয়ারিং পারফেকশনিজমের একটি রূপ যা ভালোর চেয়ে বেশি ক্ষতি করে।
এছাড়াও, সেই কোড রিফ্যাক্টর করবেন না যা নিকট ভবিষ্যতে সম্পূর্ণরূপে প্রতিস্থাপিত হবে। যদি দল অন্য ভাষা বা আর্কিটেকচারে মডিউল পুনর্লিখনের পরিকল্পনা করে, বর্তমান সংস্করণ রিফ্যাক্টর করা সময়ের অপচয়। এবং শেষ পর্যন্ত, পরীক্ষা ছাড়া রিফ্যাক্টরিং একটি দুঃসাহসিক কাজ, বিশেষ করে যদি কোড বেস বড় এবং জটিল হয়। ব্যতিক্রম হল IDE ব্যবহার করে সহজ রূপান্তর যা পূর্বাবস্থায় ফিরিয়ে আনা যায়।
নিরাপদ রিফ্যাক্টরিং একটি শৃঙ্খলা। এমন বেশ কয়েকটি নীতি রয়েছে যার পালন ঝুঁকি হ্রাস করে এবং প্রক্রিয়াকে পূর্বানুমানযোগ্য করে তোলে। প্রথম এবং সবচেয়ে গুরুত্বপূর্ণ — শুধুমাত্র পরীক্ষার অধীনে রিফ্যাক্টরিং। যদি আপনার কাছে পরিবর্তন করা কোড কভার করে এমন পরীক্ষা না থাকে — তবে প্রথমে সেগুলি লিখুন।
দ্বিতীয় নীতি — ছোট পদক্ষেপ। প্রতিটি রিফ্যাক্টরিং অপারেশন ন্যূনতম হওয়া উচিত: একটি ভেরিয়েবলের নাম পরিবর্তন, একটি মেথড নিষ্কাশন, একটি ক্লাস নিষ্কাশন। প্রতিটি পদক্ষেপের পরে — কম্পাইল এবং পরীক্ষা চালান। মাইক্রো-পদক্ষেপে বিভাজন তাত্ক্ষণিকভাবে ত্রুটি সনাক্ত এবং শেষ পরিবর্তন পূর্বাবস্থায় ফিরিয়ে আনার অনুমতি দেয়। Martin Fowler-এর মতে, মাইক্রো-পদক্ষেপগুলি রিফ্যাক্টরিংকে বড় পরিবর্তনের তুলনায় 3-4 গুণ বেশি নিরাপদ করে।
তৃতীয় নীতি — সরঞ্জাম ব্যবহার। আধুনিক IDE (IntelliJ IDEA, VS Code, Eclipse) স্বয়ংক্রিয় রিফ্যাক্টরিং প্রদান করে: rename, extract method, extract variable, move class এবং ডজন ডজন অন্যান্য। সরঞ্জাম-ভিত্তিক রিফ্যাক্টরিং রূপান্তরের সঠিকতা নিশ্চিত করে এবং যেখানে কোড পরিবর্তন করতে হবে সেই সমস্ত স্থান ম্যানুয়ালি অনুসন্ধানের প্রয়োজন হয় না।
চতুর্থ নীতি — রিফ্যাক্টরিংকে কার্যকারিতা পরিবর্তনের সাথে মিশ্রিত করবেন না। যদি আপনি একসাথে রিফ্যাক্টর এবং নতুন যুক্তি যোগ করেন, তবে কোন পরিবর্তনটি ত্রুটি সৃষ্টি করেছে তা নির্ধারণ করা অসম্ভব। কমিট পৃথকীকরণ “রিফ্যাক্টর” এবং “ফিচার”-এ একটি শিল্প মান যা কোড পর্যালোচনা এবং পরিবর্তন প্রত্যাবর্তন সহজ করে। প্রস্তাবিত কাঠামো: প্রথমে রিফ্যাক্টরিং কমিট (শুধুমাত্র কাঠামোগত পরিবর্তন, আচরণ সংরক্ষিত), তারপর নতুন কার্যকারিতা সহ কমিট।
রিফ্যাক্টরিংয়ের জন্য Git ফ্লো: একটি আলাদা ব্রাঞ্চ তৈরি করুন, রিফ্যাক্টরিং সম্পাদন করুন, সবুজ পরীক্ষা অর্জন করুন, কমিট করুন, তারপর একই ব্রাঞ্চে নতুন কার্যকারিতা যোগ করুন। যদি কিছু ভুল হয় — রিফ্যাক্টরিং পরিবর্তন সর্বদা git revert-এর মাধ্যমে প্রত্যাবর্তন করা যেতে পারে।
# Git-এ রিফ্যাক্টরিং মাইক্রো-পদক্ষেপ
git checkout -b refactor/extract-payment
# ধাপ 1: গণনা পদ্ধতি নিষ্কাশন
# ...পরিবর্তন... → কম্পাইল → পরীক্ষা
git commit -m "refactor: extract calculatePayment method"
# ধাপ 2: ভেরিয়েবলের নাম পরিবর্তন
# ...পরিবর্তন... → কম্পাইল → পরীক্ষা
git commit -m "refactor: rename amount to grossAmount"
সচরাচর জিজ্ঞাসা
না, এগুলি ভিন্ন প্রক্রিয়া। রিফ্যাক্টর করা হল তার আচরণ পরিবর্তন না করে বিদ্যমান কোড উন্নত করা। পুনর্লিখন (rewrite) হল শুরু থেকে একটি নতুন বাস্তবায়ন তৈরি করা, প্রায়শই আর্কিটেকচার এবং প্রযুক্তির পরিবর্তনের সাথে। রিফ্যাক্টরিং বেশি নিরাপদ, সস্তা এবং পূর্বানুমানযোগ্য।
প্রস্তাবিত নিয়ম হল স্প্রিন্ট সময়ের 20% প্রযুক্তিগত উন্নতি এবং রিফ্যাক্টরিংয়ের জন্য। এটি ব্যবসায়িক কার্যকারিতা সরবরাহ ধীর না করে প্রযুক্তিগত ঋণ নিয়ন্ত্রণে রাখার অনুমতি দেয়।
যাওয়া যায়, কিন্তু ঝুঁকিপূর্ণ। IDE-র মাধ্যমে সহজ রূপান্তরের (নাম পরিবর্তন, ধ্রুবক নিষ্কাশন) জন্য পরীক্ষা বাধ্যতামূলক নয়। জটিল পরিবর্তনের জন্য — পরীক্ষা বাধ্যতামূলক। যদি পরীক্ষা না থাকে — প্রথমে ক্যারেক্টারাইজেশন পরীক্ষা লিখুন যা বর্তমান আচরণ ক্যাপচার করে।
পরিবর্তনের খরচের মাধ্যমে যুক্তি দিন। যদি জটিল কোডের কারণে একটি সাধারণ ফিচার যোগ করতে এক সপ্তাহ লাগে — দেখান যে রিফ্যাক্টরিং ভবিষ্যতের পরিবর্তনের জন্য সময় কমিয়ে দেবে। মেট্রিক ব্যবহার করুন: CR সময়, বাগ সংখ্যা, চক্রীয় জটিলতা।
শেষ পরিবর্তনটি পূর্বাবস্থায় ফিরিয়ে আনুন। যদি Git ব্যবহার করেন — শেষ কমিটের git revert করুন। যদি মাইক্রো-পদক্ষেপগুলি যথেষ্ট ছোট ছিল, তবে হারানো পরিবর্তনের পরিমাণ ন্যূনতম হবে। এই কারণেই বড় রিফ্যাক্টরিং সর্বদা মাইক্রো-পদক্ষেপের সিরিজে বিভক্ত করা হয়।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন