ওয়ার্কঅ্যারাউন্ড (ইংরেজি: workaround, kludge, hotfix) — কোডের একটি সমস্যার অস্থায়ী বা উপ-অনুকূল সমাধান যা কাজ করে কিন্তু ক্লিন আর্কিটেকচার, পঠনযোগ্যতা বা পারফরম্যান্সের নীতিমালা লঙ্ঘন করে। বাস্তব ডেভেলপমেন্টে ওয়ার্কঅ্যারাউন্ড অনিবার্য: সময়সীমা, সংস্করণ অসামঞ্জস্যতা, লিগ্যাসি কোড এবং ফ্রেমওয়ার্কের অডকুমেন্টেড আচরণ ডেভেলপারদের আপস করতে বাধ্য করে। Martin Fowler (2025) অনুসারে, একটি ন্যায্য ওয়ার্কঅ্যারাউন্ড এবং টেকনিক্যাল ডেটের মধ্যে মূল পার্থক্য — এটি অপসারণের পরিকল্পনা এবং কোডে স্পষ্ট চিহ্নিতকরণের উপস্থিতি।
মূল পয়েন্ট
ওয়ার্কঅ্যারাউন্ড — একটি সফ্টওয়্যার সমাধানের জন্য অপভাষা শব্দ যা কার্যকরীভাবে সঠিক কিন্তু প্রযুক্তিগতভাবে উপ-অনুকূল। এই জাতীয় কোড কাজ করে, পরীক্ষা পাস করে এবং এমনকি প্রোডাকশনেও পৌঁছে, কিন্তু এটি পড়লে সবকিছু স্ক্র্যাচ থেকে পুনরায় লেখার ইচ্ছা হয়। ইংরেজি ভাষাভাষী পরিবেশে, workaround, kludge (kluge), hack বা quick-and-dirty fix শব্দগুলি ব্যবহৃত হয়।
শব্দটি একটি গৃহস্থালী রূপক থেকে এসেছে: যদি চেয়ারের পা ভেঙে যায়, তবে তা টেপ দিয়ে বাঁধা যেতে পারে — চেয়ার আবার কাজ করে, কিন্তু সমাধান অস্থায়ী এবং কুৎসিত। প্রোগ্রামিংয়েও একই কথা প্রযোজ্য: একটি বাগ হার্ডকোড, টাইমআউট ওয়ার্কঅ্যারাউন্ড বা অডকুমেন্টেড API-র মাধ্যমে ঠিক করা হয়। কোড কম্পাইল হয়, অ্যাপ্লিকেশন ক্র্যাশ হয় না, কিন্তু সমাধানকে গুণগতমান বলা যায় না।
একটি গুরুত্বপূর্ণ পার্থক্য: বাগ — যখন কোড প্রত্যাশিতভাবে কাজ করে না। ওয়ার্কঅ্যারাউন্ড — যখন কোড কাজ করে কিন্তু খারাপভাবে ডিজাইন করা হয়েছে। ওয়ার্কঅ্যারাউন্ড সবসময় ডেভেলপারের সচেতন পছন্দ: “আমি জানি এটি কুৎসিত, কিন্তু এখন এটি সমস্যার সমাধান করে।”
Stripe (2024) অনুসারে, ডেভেলপাররা গড়ে সপ্তাহে 17 ঘন্টা টেকনিক্যাল ডেট এবং ওয়ার্কঅ্যারাউন্ড নিয়ে কাজ করতে ব্যয় করে — তাদের কাজের সময়ের প্রায় অর্ধেক। এটি দলের উৎপাদনশীলতার সরাসরি ক্ষতি।
প্রথম এবং প্রধান কারণ হল সময়সীমা। যখন রিলিজের আগে একদিন বাকি থাকে এবং একটি গুরুতর বাগ এখনও ঠিক হয়নি, দল সঠিক সমাধানের পরিবর্তে দ্রুত সমাধান বেছে নেয়। মান হার্ডকোড করা, চেক অক্ষম করা, sleep() যোগ করা — সময়সীমার ওয়ার্কঅ্যারাউন্ডের ক্লাসিক উদাহরণ। একজন অভিজ্ঞ ডেভেলপার সবসময় এমন জায়গাগুলি TODO বা FIXME দিয়ে চিহ্নিত করে।
দ্বিতীয় কারণ হল API অসামঞ্জস্যতা। কোনো তৃতীয়-পক্ষের লাইব্রেরি বা ফ্রেমওয়ার্ক ডকুমেন্টেড থেকে ভিন্ন আচরণ করে। ফ্রেমওয়ার্ক প্রয়োজনীয় ক্লাস এক্সপোর্ট করে না, কোনো মেথড depracated চিহ্নিত এবং কোনো বিকল্প নেই। ডেভেলপার রিফ্লেকশন, অভ্যন্তরীণ API বা বিকল্প সমাধান ব্যবহার করতে বাধ্য হয়। Java-তে, এটি setAccessible(true)-এর মাধ্যমে অ্যাক্সেস হতে পারে, Swift-এ — @objc এবং performSelector।
তৃতীয় কারণ হল লিগ্যাসি কোড। একজন ডেভেলপার 5-10 বছর আগে ফ্রেমওয়ার্কের পুরনো সংস্করণে লেখা প্রকল্প উত্তরাধিকার সূত্রে পায়। পুরো মডিউল পুনরায় লেখার সময় বা বাজেট নেই, তাই নতুন কার্যকারিতা ওয়ার্কঅ্যারাউন্ডের মাধ্যমে পুরনো কোডের সাথে “আটকে দেওয়া” হয়। ধীরে ধীরে এত স্তর জমা হয় যে মডিউলটি “কাদার বড় বল” (big ball of mud)-এ পরিণত হয়।
চতুর্থ কারণ হল পরীক্ষার অভাব। পরীক্ষা ছাড়া রিফ্যাক্টরিং বিপজ্জনক: আর্কিটেকচার পরিবর্তন করলে কাজ করা কার্যকারিতা ভেঙে যেতে পারে। যখন পরীক্ষা নেই, ডেভেলপার স্থিতিশীলতা ঝুঁকিতে ফেলার পরিবর্তে কাজ করা কোডের উপরে ওয়ার্কঅ্যারাউন্ড যোগ করতে পছন্দ করে। Google Testing Blog (2024) অনুসারে, পরীক্ষা ছাড়া দলগুলি 3 গুণ বেশি ওয়ার্কঅ্যারাউন্ড সমাধান ব্যবহার করে।
ওয়ার্কঅ্যারাউন্ডের শ্রেণীবিভাগ দলকে বুঝতে সাহায্য করে যে তারা কী ধরনের টেকনিক্যাল ডেট মোকাবেলা করছে এবং সঠিক অপসারণ কৌশল বেছে নিতে। আসুন প্রধান প্রকারগুলি দেখি।
হার্ডকোড — সবচেয়ে সাধারণ প্রকার। কনফিগারেশন, রিসোর্স বা প্যারামিটারের পরিবর্তে কোডে একটি নির্দিষ্ট মান ব্যবহার করা হয়। উদাহরণ: হার্ডকোডেড সার্ভার URL, 5 সেকেন্ডের টাইমআউট, 16pt ফন্ট সাইজ। হার্ডকোড কোডকে অস্কেলেবল করে এবং কোনো পরিবর্তনের জন্য পুনরায় কম্পাইলেশন প্রয়োজন।
কপি-পেস্ট — সাধারণ লজিক বের করার পরিবর্তে সামান্য পরিবর্তন সহ কোড স্নিপেট নকল করা। ক্লাসিক লক্ষণ: প্রকল্পে 3টি অনুরূপ মেথড রয়েছে যা এক লাইনে ভিন্ন। কপি-পেস্ট কাজের সময় কোড লেখার গতি বাড়ায় কিন্তু ভবিষ্যতে রক্ষণাবেক্ষণ 10 গুণ ধীর করে দেয় — সংশোধন একটির পরিবর্তে 3 জায়গায় প্রয়োগ করতে হয়।
খালি try-catch — একটি catch ব্লক যা কিছুই করে না বা শুধু ত্রুটি লগ করে কোনো হ্যান্ডলিং ছাড়াই। এই ধরনের ওয়ার্কঅ্যারাউন্ড ব্যতিক্রমকে “নীরব” করে কিন্তু তার কারণ ঠিক করে না। অ্যাপ্লিকেশন কাজ করতে থাকে, কিন্তু ডেটা দূষিত হতে পারে এবং ব্যবহারকারী প্রতিক্রিয়া নাও পেতে পারে।
কোডে স্লিপ (Sleep) — Thread.sleep(500) বা DispatchQueue.main.asyncAfter অপেক্ষার জন্য যখন কোনো ইভেন্ট বা কলব্যাক থাকা উচিত। এই কোড অবিশ্বস্ত: ধীর ডিভাইসে 500 ms যথেষ্ট নাও হতে পারে; দ্রুত ডিভাইসে, বিরতি অপ্রয়োজনীয় হবে। CountDownLatch, Semaphore বা সঠিক টাইমিং সহ async/await ব্যবহার করুন।
সামঞ্জস্যতা ফ্ল্যাগ — OS সংস্করণ, ডিভাইস মডেল বা ফিচার উপলব্ধতা পরীক্ষা করা if-else ক্যাসকেড। যখন 3-4টির বেশি ফ্ল্যাগ থাকে, কোড স্প্যাগেটিতে পরিণত হয়। সমাধান — Strategy প্যাটার্ন বা কনফিগারেশনের মাধ্যমে Feature Flags।
অনেক ডেভেলপার ওয়ার্কঅ্যারাউন্ড এবং টেকনিক্যাল ডেটকে গুলিয়ে ফেলেন। পার্থক্য স্কেল এবং সচেতনতায়। ওয়ার্কঅ্যারাউন্ড — একটি স্থানীয়, নির্দিষ্ট সমাধান (একটি মেথড, একটি ক্লাস)। টেকনিক্যাল ডেট — একটি পদ্ধতিগত সমস্যা যা মডিউল বা পুরো অ্যাপ্লিকেশনের আর্কিটেকচারকে প্রভাবিত করে।
Ward Cunningham-এর রূপক (টেকনিক্যাল ডেট শব্দের স্রষ্টা): টেকনিক্যাল ডেট ব্যাংক থেকে ঋণ নেওয়ার মতো। আপনি এখন টাকা নেন বাড়ি দ্রুত তৈরি করতে, কিন্তু পরে সুদ পরিশোধ করেন। ওয়ার্কঅ্যারাউন্ড — পেরেক বন্দুকের পরিবর্তে হাতুড়ি দিয়ে পেরেক ঠোকা: কাজ হয়, কিন্তু কম কার্যকরভাবে।
একটি ওয়ার্কঅ্যারাউন্ড টেকনিক্যাল ডেট তৈরি করে না। কিন্তু একটি মডিউলে 50টি ওয়ার্কঅ্যারাউন্ড = আর্কিটেকচারাল ডেট। তাই, দলের নিয়ম: প্রতিটি ওয়ার্কঅ্যারাউন্ড কোড রিভিউ বা টাস্ক ট্র্যাকারে রেকর্ড করা হয়, এবং দল নিয়মিতভাবে (প্রতি স্প্রিন্টে একবার) জমা হওয়া ওয়ার্কঅ্যারাউন্ড সমাধানগুলি পর্যালোচনা করে।
Spotify Engineering (2023) অনুসারে, যে দলগুলি কোডে ওয়ার্কঅ্যারাউন্ড ট্র্যাক করে (একটি বিশেষ TODO লেবেল বা কাস্টম অ্যানোটেশন মাধ্যমে), রিফ্যাক্টরিং সময় 30% কমায় — কারণ তারা সমস্যাযুক্ত স্থান খুঁজতে ঘন্টা ব্যয় করে না।
প্রথম ধাপ — ইনভেন্টরি। কোডবেসে কীওয়ার্ড খুঁজুন: TODO, FIXME, HACK, WORKAROUND, KLUDGE। আধুনিক IDE এগুলি আলাদা রঙে হাইলাইট করে। GitHub-ও Pull Request ইন্টারফেসে TODO প্রদর্শন করে। অগ্রাধিকার সহ সমস্ত ওয়ার্কঅ্যারাউন্ডের তালিকা তৈরি করুন।
দ্বিতীয় ধাপ — অগ্রাধিকার নির্ধারণ। সব ওয়ার্কঅ্যারাউন্ড অবিলম্বে ঠিক করার প্রয়োজন নেই। অগ্রাধিকার = ফাইলে পরিবর্তনের ফ্রিকোয়েন্সি × গুরুতরতা। যদি একটি ফাইল বছরে 2 বার পরিবর্তিত হয়, ওয়ার্কঅ্যারাউন্ড অপেক্ষা করতে পারে। যদি একটি মডিউল প্রতি স্প্রিন্টে স্পর্শ করা হয় — ওয়ার্কঅ্যারাউন্ডটি প্রথমে ঠিক করা উচিত।
তৃতীয় ধাপ — পরীক্ষা সহ রিফ্যাক্টরিং। পরীক্ষা ছাড়া কখনও ওয়ার্কঅ্যারাউন্ড রিফ্যাক্টর করবেন না। প্রথমে একটি পরীক্ষা লিখুন যা বর্তমান আচরণ (ওয়ার্কঅ্যারাউন্ড সহ) যাচাই করে, তারপর রিফ্যাক্টর করুন, তারপর নিশ্চিত করুন যে পরীক্ষা পাস হয়। এটি ছাড়া, ওয়ার্কঅ্যারাউন্ডের রিফ্যাক্টরিং সেই কার্যকারিতা ভেঙে দিতে পারে যার জন্য এটি লেখা হয়েছিল।
// Before: হার্ডকোডেড URL ওয়ার্কঅ্যারাউন্ড
fun getApiUrl(): String {
return "https://api.example.com/v2"
}
// After: BuildConfig-এর মাধ্যমে কনফিগারেশন
fun getApiUrl(): String {
return BuildConfig.API_BASE_URL
}
চতুর্থ ধাপ — অটোমেশন। একটি লিন্টার সেট আপ করুন যা নির্দিষ্ট ওয়ার্কঅ্যারাউন্ড প্যাটার্ন নিষিদ্ধ করে। উদাহরণস্বরূপ, Kotlin-এর জন্য Detekt প্রোডাকশন কোডে Thread.sleep()-এর অনুপস্থিতি পরীক্ষা করতে পারে, ESLint প্রকল্পে console.log নিষিদ্ধ করতে পারে। এটি একই ধরনের নতুন ওয়ার্কঅ্যারাউন্ড দেখা দেওয়া প্রতিরোধ করে।
শব্দটির নেতিবাচক অর্থ সত্ত্বেও, একটি ওয়ার্কঅ্যারাউন্ড ন্যায্য সমাধান হতে পারে। প্রধান শর্ত: ওয়ার্কঅ্যারাউন্ড অস্থায়ী, স্পষ্টভাবে চিহ্নিত এবং প্রতিস্থাপন পরিকল্পনা রয়েছে। প্রতিটি বড় প্রকল্পের প্রোডাকশন কোডে শত শত ন্যায্য ওয়ার্কঅ্যারাউন্ড থাকে।
পরিস্থিতি 1: প্রোডাকশনে হটফিক্স। একটি গুরুতর বাগ সমস্ত ব্যবহারকারীর জন্য ক্র্যাশ করছে। দলের এক ঘন্টার মধ্যে সংশোধন প্রয়োজন। সঠিক পদ্ধতি: যেকোনো উপায়ে বাগ ঠিক করুন, হটফিক্স ডিপ্লয় করুন। তারপর, পরের দিন, সঠিক সমাধান লিখুন এবং টিকিট বন্ধ করুন। একটি হটফিক্স একটি ন্যায্য ওয়ার্কঅ্যারাউন্ড যদি এটি 48 ঘন্টার বেশি বাঁচে না।
পরিস্থিতি 2: নতুন লাইব্রেরি সংস্করণের অপেক্ষা। একটি ফ্রেমওয়ার্কে বাগ রয়েছে যা master-এ ঠিক হয়েছে, কিন্তু রিলিজ 2 সপ্তাহে আসবে। জটিল বিকল্প কোড লেখার পরিবর্তে, দল একটি ওয়ার্কঅ্যারাউন্ড যোগ করে যাতে নোট থাকে “REMOVE after library 3.2.” যখন 3.2 রিলিজ হয়, ওয়ার্কঅ্যারাউন্ড সরিয়ে ফেলা হয়।
পরিস্থিতি 3: স্টার্টআপ বা MVP বন্ধ করা। MVP পর্যায়ে, গতি আর্কিটেকচারের চেয়ে গুরুত্বপূর্ণ। শুরুতে ওয়ার্কঅ্যারাউন্ড স্বাভাবিক। সমস্যা দেখা দেয় যখন স্টার্টআপ পণ্যে পরিণত হয় না, কিন্তু ওয়ার্কঅ্যারাউন্ড থেকে যায়। সুপারিশ: ফান্ডিং রাউন্ডের পরে, গুরুত্বপূর্ণ টেকনিক্যাল ডেট পরিশোধ করতে একটি স্প্রিন্ট বরাদ্দ করুন।
মূল নীতি: “লিগ্যাসি কোড পরীক্ষা ছাড়া কোড” (Michael Feathers)। যদি একটি ওয়ার্কঅ্যারাউন্ড পরীক্ষা দ্বারা আচ্ছাদিত এবং স্পষ্টভাবে ডকুমেন্টেড হয় — এটি পরিচালনাযোগ্য। যদি এটি 2 বছর ধরে মন্তব্য ছাড়া ভুলে যাওয়া মডিউলে ঝুলে থাকে — এটি আর ওয়ার্কঅ্যারাউন্ড নয়, একটি আর্কিটেকচারাল সমস্যা।
সচরাচর জিজ্ঞাসিত প্রশ্ন
বাগ — কোড প্রত্যাশিতভাবে কাজ করে না। ওয়ার্কঅ্যারাউন্ড — কোড কাজ করে কিন্তু উপ-অনুকূলভাবে লেখা। ওয়ার্কঅ্যারাউন্ড সর্বদা ডেভেলপারের সচেতন সিদ্ধান্ত; বাগ সাধারণত অচেতন ভুল।
// TODO: refactor — ... বা ফিল্ড সহ কাস্টম @Workaround অ্যানোটেশন ব্যবহার করুন: কারণ, তারিখ, দায়িত্বশীল ব্যক্তি, মুছে ফেলার সময়সীমা। ব্যাখ্যা ছাড়া খালি // HACK এড়িয়ে চলুন।
যদি মডিউল পরিবর্তন না হয় এবং ওয়ার্কঅ্যারাউন্ড স্থিতিশীল হয় — না। কারণ ছাড়া রিফ্যাক্টরিং রিগ্রেশন ঝুঁকি বাড়ায়। শুধু সেই ওয়ার্কঅ্যারাউন্ডগুলি ঠিক করুন যা নতুন কার্যকারিতা যোগ করতে বাধা দেয়।
সময় তুলনা করুন: “আমরা বর্তমানে এই ওয়ার্কঅ্যারাউন্ডগুলির কারণে ম্যানুয়াল টেস্টিংয়ে 4 ঘন্টা ব্যয় করি। রিফ্যাক্টরিং 8 ঘন্টা সময় নেবে এবং সময় 30 মিনিটে কমিয়ে দেবে। বিনিয়োগে ফেরত — 2 স্প্রিন্ট।” গতি এবং অর্থ-এর ভাষায় বলুন, ক্লিন আর্কিটেকচার নয়।
পুরো প্রকল্প জুড়ে grep-এর মাধ্যমে TODO, FIXME, HACK, WORKAROUND খুঁজুন। 100 লাইনের বেশি লম্বা মেথড এবং 5টির বেশি নির্ভরতা সহ ক্লাস বিশ্লেষণ করুন। স্বয়ংক্রিয় সনাক্তকরণের জন্য কাস্টম নিয়ম সহ লিন্টার ব্যবহার করুন।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন