কপিপেস্ট (কপি-পেস্ট) হলো নতুন প্রসঙ্গে খাপ খাওয়ানো ছাড়া কোডের টুকরো এক জায়গা থেকে অন্য জায়গায় কপি করার অভ্যাস। বেশিরভাগ ক্ষেত্রে, ডেভেলপার একটি বিদ্যমান মডিউল থেকে ব্লক কপি করে, ন্যূনতম সম্পাদনা করে এবং বাগ, পুরনো মন্তব্য এবং অপ্রয়োজনীয় নির্ভরতা সহ নতুনটিতে পেস্ট করে। TIOBE Code Quality Survey (2025) অনুসারে, উচ্চ মাত্রার কপিপেস্টযুক্ত প্রজেক্টে একীভূত অ্যাবস্ট্র্যাকশনযুক্ত প্রজেক্টের তুলনায় প্রতি হাজার লাইন কোডে তিনগুণ বেশি ত্রুটি থাকে। কোড ডুপ্লিকেশন টেকনিক্যাল ডেটের প্রধান উৎস: প্রতিটি কপির আলাদা রক্ষণাবেক্ষণ প্রয়োজন, এবং এক জায়গায় বাগ ফিক্স করলে অন্যগুলিতে ফিক্স হওয়ার গ্যারান্টি নেই।
মূল বিষয়
কপিপেস্ট (কপি-পেস্ট প্রোগ্রামিং) হলো বিদ্যমান কোড সামান্য বা কোন পরিবর্তন ছাড়া নতুন জায়গায় সরানো। শব্দটি নিন্দাসূচকভাবে ব্যবহৃত হয়: এটি বোঝায় যে ডেভেলপার কোনো সমাধান ডিজাইন করছে না, বরং যান্ত্রিকভাবে একটি তৈরি ব্লক কপি করছে, প্রায়শই এটি কীভাবে কাজ করে তা পুরোপুরি বুঝে না।
কপিপেস্ট দুই ধরনের হয়: ইচ্ছাকৃত (intentional) এবং আকস্মিক (accidental)। ইচ্ছাকৃত — যখন ডেভেলপার পরে রিফ্যাক্টর করার পরিকল্পনা নিয়ে ইচ্ছাকৃতভাবে কোড কপি করে (কিন্তু পরিকল্পনা প্রায়ই পরিত্যক্ত হয়)। আকস্মিক — যখন ডুপ্লিকেশন অলক্ষ্যে উদ্ভূত হয়, উদাহরণস্বরূপ, দুজন ডেভেলপার স্বাধীনভাবে বিভিন্ন স্ক্রিনের জন্য একই লজিক লেখে।
SonarQube State of Clean Code (2025) রিপোর্ট অনুসারে, বাণিজ্যিক প্রজেক্টে ডুপ্লিকেটেড কোড মোট কোড ভলিউমের গড়ে ১২–১৮ শতাংশ। একই সময়ে, ডুপ্লিকেটেড কোডে বাগ ফিক্স করার খরচ একক বাস্তবায়নযুক্ত কোডের তুলনায় ২.৫ গুণ বেশি, কারণ ডেভেলপারকে সমস্ত কপি খুঁজে বের করে ফিক্স করতে হয়।
কপিপেস্টের বিরুদ্ধে প্রাথমিক হাতিয়ার হলো DRY (Don't Repeat Yourself) নীতি। তবে, DRY-কে চরমে নেওয়াও বিপজ্জনক: কখনও কখনও কপি করা ন্যায্য যখন দুটি কপির একে অপরের থেকে স্বাধীনভাবে বিবর্তিত হওয়া প্রয়োজন। “আকস্মিক ডুপ্লিকেশন” (যা দূর করতে হবে) এবং “প্রয়োজনীয় ডুপ্লিকেশন” (যা নথিভুক্ত করতে হবে) এর মধ্যে পার্থক্য করা গুরুত্বপূর্ণ।
প্রথম এবং সবচেয়ে গুরুত্বপূর্ণ বিপদ হলো বাগের বিস্তার। যদি মূল কোডে কোনো ত্রুটি থাকে, তবে তা কোডের সাথে সমস্ত নতুন স্থানে কপি হয়। যখন ত্রুটিটি আবিষ্কৃত হয় এবং মূল মডিউলে ফিক্স করা হয়, কপিগুলি অপরিবর্তিত থাকে। ডেভেলপার জানতেও পারে না যে বাগটি পাঁচটি ভিন্ন ফাইলে বিদ্যমান।
দ্বিতীয় বিপদ হলো অসম বিবর্তন। একই অ্যালগরিদমের দুটি কপি সময়ের সাথে সাথে বিভিন্ন পরিবর্তন জমা করে। একটি কপি সীমানা মান যাচাই যোগ করে, অন্যটি আউটপুট ফরম্যাট পরিবর্তন করে। কয়েক মাস পরে, কোন সংস্করণটি “সঠিক” তা বলা অসম্ভব হয়ে যায় এবং প্রজেক্ট আচরণগত ধারাবাহিকতা হারায়।
তৃতীয় বিপদ হলো বর্ধিত টেস্ট ভলিউম। প্রতিটি কপিপেস্ট ইনস্ট্যান্সের নিজস্ব টেস্ট প্রয়োজন। যদি সাধারণ লজিকটি একটি ফাংশনে নিষ্কাশিত হয়, তবে এটি একটি টেস্ট সেট দিয়ে কভার করা এবং পুনরায় ব্যবহার করা যেতে পারে। ডুপ্লিকেশনের সাথে, প্রতিটি কপি আলাদাভাবে পরীক্ষা করতে হয় — এটি CI রান টাইম এবং রক্ষণাবেক্ষণযোগ্য টেস্ট বেসের আকার কয়েকগুণ বাড়িয়ে দেয়।
চতুর্থ বিপদ হলো উৎপাদনশীলতার ভ্রম। কপিপেস্ট গতির একটি মিথ্যা অনুভূতি তৈরি করে: ডেভেলপার দ্রুত কোড পেস্ট করে এবং দেখে যে স্ক্রিন কাজ করছে। কিন্তু এই “দ্রুততা” টেকনিক্যাল ডেটে পরিণত হয় যা সুদে-মূলে পরিশোধ করতে হবে যখন ডুপ্লিকেটেড ব্লকে বাগ পাওয়া যায় বা বিজনেস লজিক পরিবর্তনের প্রয়োজন হয়।
কপিপেস্টের কারণ বোঝা সঠিক প্রতিরোধ স্থাপনে সহায়তা করে। বেশিরভাগ ক্ষেত্রে, ডেভেলপাররা অলসতার কারণে নয়, বরং সময়সীমার চাপ, জ্ঞানের অভাব বা অসুবিধাজনক আর্কিটেকচারের কারণে কোড কপি করে।
প্রথম কারণ হলো সময়সীমা। যখন দুই দিনের মধ্যে একটি স্ক্রিন তৈরি করতে হয় এবং অনুরূপ স্ক্রিন ইতিমধ্যে বিদ্যমান, ডেভেলপার এটি সম্পূর্ণ কপি করে এবং শুধু ব্যবহারকারী যা দেখে তা পরিবর্তন করে। একটি শেয়ার্ড কম্পোনেন্ট বের করে রিফ্যাক্টর করার সময় নেই — ক্লায়েন্ট ফলাফল চায়। ফলস্বরূপ, ৮০ শতাংশ শেয়ার্ড কোড কিন্তু পরিবর্তনের স্বাধীন ইতিহাস সহ একটি দ্বিতীয় স্ক্রিন দেখা দেয়।
দ্বিতীয় কারণ হলো একীভূত অ্যাবস্ট্র্যাকশনের অভাব। যদি প্রজেক্টে একটি সাধারণ কাজের জন্য কোনো শেয়ার্ড কম্পোনেন্ট না থাকে (যেমন, পুল-টু-রিফ্রেশ সহ তালিকা স্ক্রিন), প্রতিটি ডেভেলপার নিজস্ব বাস্তবায়ন লিখবে বা পাশেরটি কপি করবে। প্রজেক্টের শুরুতে নেওয়া আর্কিটেকচারাল সিদ্ধান্তগুলি ভবিষ্যতের কপিপেস্টের পরিমাণকে সরাসরি প্রভাবিত করে।
তৃতীয় কারণ হলো কাজ করা কোড ভাঙ্গার ভয়। ডেভেলপার জানে যে বিদ্যমান মডিউল কাজ করে। শেয়ার্ড কোড বের করতে রিফ্যাক্টরিং বিদ্যমান কার্যকারিতাকে প্রভাবিত করতে পারে। যদি টেস্ট কভারেজ কম হয়, তবে ভাঙ্গার ঝুঁকি রিফ্যাক্টরিংয়ের অনুভূত সুবিধাকে ছাড়িয়ে যায় এবং ডেভেলপার নিরাপদ পথ বেছে নেয় — কপি করা।
লক্ষণ নয়, কারণগুলি সমাধান করুন। সময়সীমা কমানো এবং কোড রিভিউ চালু করা সমস্যার সমাধান করবে না যদি প্রজেক্টের একটি শক্ত আর্কিটেকচারাল ভিত্তি না থাকে। প্রাথমিক পর্যায়ে পুনর্ব্যবহারযোগ্য কম্পোনেন্ট তৈরি করতে সময় বিনিয়োগ করুন — ভবিষ্যতে কপিপেস্টের প্রলোভন কমানোর এটাই একমাত্র উপায়।
কপিপেস্ট শনাক্তকরণ স্বয়ংক্রিয় বিশ্লেষক দ্বারা সম্পাদিত হয় যা কোড টুকরো তুলনা করে এবং একটি নির্দিষ্ট থ্রেশহোল্ডের উপরে মিল চিহ্নিত করে। সেরা টুলগুলি AST (অ্যাবস্ট্র্যাক্ট সিনট্যাক্স ট্রি) স্তরে কাজ করে এবং ফরম্যাটিং, ভেরিয়েবল নাম এবং মন্তব্য উপেক্ষা করে।
PMD CPD (Copy-Paste Detector) Java, Kotlin, Swift, JavaScript, Python এবং C++ এর জন্য সবচেয়ে সাধারণ টুল। CPD সোর্স কোড টোকেন বিশ্লেষণ করে এবং একটি নির্দিষ্ট ন্যূনতম টোকেন সংখ্যা (ডিফল্ট ১০০) থেকে দীর্ঘ ডুপ্লিকেট খুঁজে পায়। মানসম্পন্ন ফলাফলের জন্য থ্রেশহোল্ড কনফিগার করা গুরুত্বপূর্ণ: খুব কম থ্রেশহোল্ড অনেক মিথ্যা পজিটিভ দেয় (সাধারণ প্যাটার্ন যেমন ইম্পোর্ট), খুব বেশি থ্রেশহোল্ড প্রকৃত ডুপ্লিকেট মিস করে।
plugins {
id 'pmd'
}
pmd {
toolVersion = '7.0.0'
ruleSetFiles = files("pmd-rules.xml")
}
tasks.register('cpd') {
doLast {
exec {
workingDir = projectDir
commandLine 'cpd',
'--minimum-tokens', '75',
'--language', 'kotlin',
'--files', 'src/main/kotlin',
'--format', 'xml',
'--failOnViolation', 'true'
}
}
}
SonarQube সরাসরি Quality Gate-এ একটি ডুপ্লিকেট ডিটেক্টর এম্বেড করে। Duplicated Blocks (%) নিয়ম ডুপ্লিকেটেড কোডের শতাংশ দেখায়। বাণিজ্যিক প্রজেক্টের জন্য ৫ শতাংশ থ্রেশহোল্ড স্বাস্থ্যকর বলে বিবেচিত হয়। এটি অতিক্রম করলে রিলিজ ব্রাঞ্চে প্রমোশন ব্লক হয়। SonarQube অতিরিক্তভাবে ডুপ্লিকেটগুলিকে প্রকার অনুসারে গ্রুপ করে: সঠিক মিল এবং কাঠামোগত কপি (পুনঃনামকৃত শনাক্তকারী সহ)।
JavaScript এবং TypeScript এর জন্য, ডুপ্লিকেট সনাক্ত করা হয় ESLint এর eslint-plugin-sonarjs প্লাগইন (no-duplicate-string নিয়ম) এবং jscpd ইউটিলিটি ব্যবহার করে, যা ১৫০+ ভাষা সমর্থন করে। jscpd বিশেষ করে মনোরেপোর জন্য সুবিধাজনক: এটি শুধুমাত্র একটি মডিউলের মধ্যে নয়, প্যাকেজগুলির মধ্যেও ডুপ্লিকেট খুঁজে পায়।
কপিপেস্ট রিফ্যাক্টরিং একটি নীতিতে ফুটে ওঠে: সাধারণ অংশ বের করা এবং পার্থক্যগুলিকে প্যারামিটারাইজ করা। নির্দিষ্ট কৌশল ডুপ্লিকেশনের ব্যাপ্তি এবং প্রসঙ্গের উপর নির্ভর করে।
সবচেয়ে সহজ ক্ষেত্রে হলো একই ক্লাসের মধ্যে ডুপ্লিকেশন (যেমন, একই লজিক কিন্তু ভিন্ন টাইপের দুটি মেথড)। সমাধান হলো জেনেরিক দিয়ে সাধারণীকরণ করা বা টাইপ প্যারামিটার সহ একটি মেথড পুনরায় ব্যবহার করা। যদি ডুপ্লিকেশন একাধিক ক্লাস জুড়ে বিস্তৃত হয় — সাধারণ কোড একটি ইউটিলিটি ক্লাস বা এক্সটেনশন ফাংশনে বের করুন।
আরও জটিল ক্ষেত্রে হলো স্ক্রিন বা মডিউল স্তরে ডুপ্লিকেশন। এখানে, শুধু একটি ফাংশন বের করা সাহায্য করে না, কারণ UI কাঠামো, লাইফসাইকেল লজিক এবং ডেটা বাইন্ডিং সবই ডুপ্লিকেট। সমাধান হলো একটি সাধারণ বেস স্ক্রিন ক্লাস বা একটি কম্পোজিট ভিউ কম্পোনেন্ট তৈরি করা এবং প্যারামিটার বা প্রোটোকলের মাধ্যমে পার্থক্যগুলি পাস করা।
// before - two copies of the same UITableViewController
class UserListController: UITableViewController {
private let viewModel = UserListViewModel()
// 40 lines of code
}
class ProductListController: UITableViewController {
private let viewModel = ProductListViewModel()
// same 40 lines but with Product instead of User
}
// after - generic base class shared
class ListViewController<T: ListViewModel>: UITableViewController {
let viewModel: T
// 40 lines of code - once only
init(viewModel: T) {
self.viewModel = viewModel
super.init(style: .plain)
}
}
সবচেয়ে জটিল ক্ষেত্রে হলো মাইক্রোসার্ভিস বা লাইব্রেরির মধ্যে ডুপ্লিকেশন। শেয়ার্ড কোড বের করলে চক্রীয় নির্ভরতা বা অযৌক্তিক সংযুক্তি হতে পারে। এই ধরনের ক্ষেত্রে, কপিপেস্ট একটি সচেতন সিদ্ধান্ত হতে পারে: দুটি টিম স্বাধীন সার্ভিস রক্ষণাবেক্ষণ করে এবং একটি শেয়ার্ড লাইব্রেরি সমাধানের চেয়ে বেশি সমস্যা তৈরি করে। মূল বিষয় হলো এই ধরনের সিদ্ধান্ত নথিভুক্ত করা এবং নিয়মিত পরীক্ষা করা যে কপিগুলি একীকরণের ন্যায্যতা দেওয়ার জন্য যথেষ্ট আলাদা হয়েছে কিনা।
কপিপেস্ট প্রতিরোধ করা ইতিমধ্যে ডুপ্লিকেটেড কোড রিফ্যাক্টর করার চেয়ে বেশি কার্যকর। প্রধান প্রতিরোধমূলক ব্যবস্থা প্রযুক্তিতে নয়, উন্নয়ন প্রক্রিয়া সংগঠিত করার মধ্যে নিহিত।
প্রথম ব্যবস্থা হলো ডুপ্লিকেশনের উপর ফোকাস সহ কোড রিভিউ। রিভিউ চেকলিস্টে আইটেমটি অন্তর্ভুক্ত করা উচিত: “এই PR-এ কি কোড আছে যা ইতিমধ্যে প্রজেক্টে বিদ্যমান?” যদি রিভিউয়ার কপিপেস্ট দেখে — তবে শেয়ার্ড কম্পোনেন্ট বের না করা পর্যন্ত সে মার্জ ব্লক করে। এই প্রয়োজনীয়তা টিমের Definition of Done-এর অংশ হওয়া উচিত।
দ্বিতীয় ব্যবস্থা হলো একটি শেয়ার্ড কম্পোনেন্ট লাইব্রেরি। প্রতিটি UI প্যাটার্ন যা দুই বা ততোধিক স্ক্রিনে দেখা যায়, একটি সাধারণ মডিউলে বের করা উচিত। প্রজেক্টে একটি শেয়ার্ড মডিউল তৈরি করুন এবং এটি সমস্ত UI কম্পোনেন্টের জন্য বাধ্যতামূলক এন্ট্রি পয়েন্ট করুন। যদি কোনো কম্পোনেন্ট না থাকে — এটি প্রথমে তৈরি করা হয়, তারপর স্ক্রিনে ব্যবহার করা হয়।
তৃতীয় ব্যবস্থা হলো CI/CD-তে অটোমেশন। পাইপলাইনে একটি ডুপ্লিকেটেড কোড চেক স্টেপ যোগ করুন (PMD CPD, jscpd, SonarQube)। থ্রেশহোল্ড অতিক্রম করলে বিল্ড ব্যর্থ হয়। ডেভেলপার একটি PR মার্জ করতে পারে না যা অনুমোদিত স্তরের উপরে কপিপেস্ট অনুপাত বাড়ায়। এটি কোড রিভিউ থেকে অটোমেশনে দায়িত্ব স্থানান্তর করে এবং নিশ্চিত করে যে কোনো ডুপ্লিকেট অলক্ষিত না হয়।
“একটি বাস্তবায়ন — একটি স্থান” এর সংস্কৃতি গড়ে তুলুন। যদি আপনি পুনরায় ব্যবহারের সুযোগ দেখেন — রিফ্যাক্টরিং পরে না রেখে এখনই করুন। প্রতিটি কপিপেস্ট যা “পরে” রেখে দেওয়া হয়, বহুগুণ বেড়ে যায় এবং অনিয়ন্ত্রিত টেকনিক্যাল ডেটে পরিণত হয়।
সচরাচর জিজ্ঞাসা
না, সচেতন ডুপ্লিকেশনের পরিস্থিতি রয়েছে: ভিন্ন মাইক্রোসার্ভিস যা স্বাধীনভাবে বিবর্তিত হওয়া প্রয়োজন; মুছে ফেলার পরিকল্পনা সহ পরীক্ষার জন্য কপি করা কোড; বিভিন্ন API সংস্করণের জন্য টেমপ্লেট DTO। মূল বিষয় হলো কারণ নথিভুক্ত করা এবং রিফ্যাক্টরিংয়ের জন্য একটি পরীক্ষার সময়সীমা নির্ধারণ করা।
কপিপেস্ট হলো যখন কোডের দুটি অংশ একই কাজ করে কিন্তু তাদের কোনো শেয়ার্ড অ্যাবস্ট্র্যাকশন নেই। স্বাস্থ্যকর পুনঃব্যবহার হলো যখন সাধারণ কোড একটি ফাংশন, ক্লাস বা মডিউলে বের করা হয় এবং পার্থক্যগুলি প্যারামিটারাইজ করা হয়। যদি লজিক পরিবর্তনের জন্য তিন বা ততোধিক স্থানে সম্পাদনার প্রয়োজন হয় — সেটি কপিপেস্ট।
PMD CPD Swift এবং Objective-C সমর্থন করে। Xcode-এর জন্য, SwiftCop এর মতো প্লাগইন এবং AppCode-এ একটি অন্তর্নির্মিত ডুপ্লিকেট ডিটেক্টর রয়েছে। SonarQube Swift প্রজেক্টও বিশ্লেষণ করে, পুল রিকোয়েস্টে সরাসরি ডুপ্লিকেটেড ব্লক দেখায়।
প্রতিটি বড় কপির রিফ্যাক্টরিংয়ের জন্য একটি টেকনিক্যাল টিকিট তৈরি করুন। অগ্রাধিকার নির্ধারণ করুন: যে স্ক্রিনগুলি ঘন ঘন পরিবর্তিত হয় সেগুলি প্রথমে, স্থিতিশীলগুলি পরে। ডুপ্লিকেটেড কোড স্পর্শকারী প্রতিটি নতুন PR-এর জন্য, ধীরে ধীরে একত্রীকরণের জন্য ১৫–২০ শতাংশ সময় বরাদ্দ করুন।
হ্যাঁ, আধুনিক AI সহায়ক (GitHub Copilot, Codeium) প্রসঙ্গ বিশ্লেষণ করতে পারে এবং পুনরাবৃত্ত প্যাটার্ন শনাক্ত করার সময় শেয়ার্ড কোড বের করার পরামর্শ দিতে পারে। তবে, তারা স্বয়ংক্রিয় বিশ্লেষক প্রতিস্থাপন করে না — Copilot প্রতিরোধ এর জন্য এবং CPD / SonarQube শনাক্তকরণের জন্য ব্যবহার করুন।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন