Kopya-paste (copy-paste) — ito ang pagsasanay ng pagkopya ng mga fragment ng code mula sa isang lugar patungo sa iba nang walang pag-aangkop sa bagong konteksto. Kadalasan, kinokopya ng developer ang isang bloke mula sa umiiral na modyul, gumagawa ng minimal na pagbabago, at idinidikit sa bago — kasama ang mga bug, lumang komento, at mga hindi kinakailangang dependency. Ayon sa pananaliksik na TIOBE Code Quality Survey (2025), ang mga proyektong may mataas na antas ng kopya-paste ay naglalaman ng tatlong beses na mas maraming depekto sa bawat libong linya ng code kaysa sa mga proyektong may iisang abstraksiyon. Pagdodoble ng code — pangunahing tagapagbigay ng teknikal na utang: bawat kopya ay nangangailangan ng hiwalay na pagpapanatili, at ang pag-aayos ng bug sa isang lugar ay hindi ginagarantiyahan ang pag-aayos nito sa iba.
Mga pangunahing punto
Kopya-paste (copy-paste programming) — ay ang paglipat ng umiiral na code sa isang bagong lugar na may maliit na pagbabago o walang pagbabago. Ang termino ay ginagamit sa isang nakakainsultong kahulugan: nagmumungkahi ito na ang developer ay hindi nagdidisenyo ng solusyon, kundi mekanikal na kinokopya ang isang handa na bloke, madalas nang hindi lubos na nauunawaan kung paano ito gumagana.
Ang kopya-paste ay may dalawang uri: makatwiran (intentional) at aksidental (accidental). Makatwiran — kapag sinadyang kinopya ng developer ang code na may plano para sa susunod na refactoring (ngunit madalas ang plano ay hindi naisasagawa). Aksidental — kapag ang pagdodoble ay nangyayari nang hindi napapansin, halimbawa, dalawang developer ang nagsusulat ng parehong lohika para sa magkaibang screen.
Ayon sa ulat ng SonarQube State of Clean Code (2025), ang nadobleng code ay bumubuo ng average na 12–18 porsiyento ng kabuuang dami ng code sa mga komersyal na proyekto. Kasabay nito, ang gastos sa pag-aayos ng bug sa nadobleng code ay 2.5 beses na mas mataas kaysa sa code na may iisang implementasyon, dahil kailangan ng developer na hanapin at ayusin ang lahat ng kopya.
Ang pangunahing kasangkapan sa paglaban sa kopya-paste ay ang prinsipyong DRY (Don't Repeat Yourself). Gayunpaman, ang pag-absoluto sa DRY ay mapanganib din: minsan ang pagkopya ay makatwiran kapag ang dalawang kopya ay kailangang mag-evolve nang independyente sa isa't isa. Mahalagang makilala ang “aksidental na pagdodoble” (na dapat alisin) at “ kinakailangang pagdodoble” (na dapat idokumento).
Ang una at pinakamahalagang panganib — pagdami ng mga bug. Kung may depekto sa source code, ito ay kinokopya sa lahat ng bagong lugar kasama ng code. Kapag natuklasan at naayos ang depekto sa source module, nananatiling hindi naayos ang mga kopya. Maaaring hindi man lang alam ng developer na ang bug ay umiiral sa limang magkakaibang file.
Ang pangalawang panganib — hindi pantay na ebolusyon. Dalawang kopya ng parehong algorithm sa paglipas ng panahon ay nagkakaroon ng magkaibang mga pagbabago. Sa isang kopya ay idinagdag ang validasyon ng boundary values, sa isa pa — binago ang format ng output. Pagkalipas ng ilang buwan, nagiging imposibleng matukoy kung aling bersyon ang “tama” at nawawalan ng konsistensiya ang proyekto.
Ang pangatlong panganib — paglaki ng volume ng test. Ang bawat kopya-paste ay nangangailangan ng sarili nitong mga test. Kung ang karaniwang lohika ay ie-extract sa isang function, maaari itong saklawin ng isang set ng test at magamit muli. Sa pagdodoble, ang bawat kopya ay kailangang i-test nang hiwalay — ito ay nagpaparami sa oras ng pagtakbo ng CI at sa dami ng pinapanatiling test base.
Ang pang-apat na panganib — ilusyon ng produktibidad. Ang kopya-paste ay lumilikha ng maling pakiramdam ng bilis: mabilis na naglalagay ng code ang developer at nakikitang gumagana ang screen. Ngunit ang “bilis” na ito ay nagiging teknikal na utang na kailangang bayaran nang may interes kapag may natagpuang bug sa nadobleng bloke o kinakailangan ang pagbabago sa business logic.
Ang pag-unawa sa mga dahilan ng kopya-paste ay tumutulong sa pagbuo ng tamang pag-iwas. Kadalasan, kinokopya ng mga developer ang code hindi dahil sa katamaran, kundi dahil sa pressure ng deadline, kakulangan ng kaalaman, o hindi magandang arkitektura.
Ang unang dahilan — mga deadline. Kapag kailangang gumawa ng screen sa loob ng dalawang araw, at mayroon nang katulad na screen, kinokopya ito ng developer nang buo at pinapalitan lamang ang nakikita ng user. Para sa refactoring na may pag-extract ng karaniwang component ay walang oras — inaasahan ng kliyente ang resulta. Bilang resulta, lumilitaw ang pangalawang screen na may 80 porsiyentong karaniwang code, ngunit may independiyenteng kasaysayan ng mga pagbabago.
Ang pangalawang dahilan — kawalan ng iisang abstraksiyon. Kung sa proyekto ay walang karaniwang component para sa tipikal na gawain (halimbawa, screen ng listahan na may pull-to-refresh), bawat developer ay susulat ng sarili niyang implementasyon o kokopya ng sa katabi. Ang mga desisyong arkitektural na ginawa sa simula ng proyekto ay direktang nakakaapekto sa dami ng kopya-paste sa hinaharap.
Ang pangatlong dahilan — takot na masira ang gumaganang code. Alam ng developer na gumagana ang umiiral na modyul. Ang refactoring na may pag-extract ng karaniwang code ay maaaring makaapekto sa umiiral na functionality. Kung mababa ang test coverage, ang panganib ng pagkasira ay lumalampas sa nakikitang benepisyo ng refactoring, at pinipili ng developer ang ligtas na landas — pagkopya.
Tanggalin ang mga sanhi, hindi ang mga sintomas. Ang pagpapaikli ng mga deadline at pagpapatupad ng code review ay hindi malulutas ang problema kung sa proyekto ay walang karaniwang arkitektural na base. Mamuhunan ng oras sa paggawa ng mga reusable component sa mga unang yugto — ito ang tanging paraan upang mabawasan ang tukso ng kopya-paste sa hinaharap.
Ang paghahanap ng kopya-paste ay ginagawa ng mga automatic analyzer na nagkukumpara ng mga fragment ng code at tumutukoy ng mga tugma sa itaas ng itinakdang threshold. Ang pinakamahusay na mga kasangkapan ay gumagana sa antas ng AST (abstract syntax tree) at hindi pinapansin ang pag-format, pangalan ng variable, at komento.
PMD CPD (Copy-Paste Detector) — ang pinakakaraniwang kasangkapan para sa Java, Kotlin, Swift, JavaScript, Python at C++. Sinusuri ng CPD ang mga token ng source code at hinahanap ang mga duplikado na mas mahaba kaysa sa itinakdang minimum na bilang ng token (default 100). Ang pagtatakda ng threshold ay susi sa kalidad ng resulta: masyadong mababang threshold ay nagbibigay ng maraming false positive (karaniwang pattern tulad ng import), masyadong mataas — nakakaligtaan ang tunay na duplikado.
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 ay naglalagay ng duplikadong detector nang direkta sa Quality Gate. Ang panuntunang Duplicated Blocks (%) ay nagpapakita ng bahagi ng nadobleng code. Ang threshold na 5 porsiyento ay itinuturing na malusog para sa mga komersyal na proyekto. Ang paglampas ay humaharang sa promosyon sa release branch. Pinapangkat din ng SonarQube ang mga duplikado ayon sa uri: eksaktong kopya (exact match) at istruktural na kopya (na may binagong pangalan).
Para sa JavaScript at TypeScript, ang mga duplikado ay hinahanap gamit ang ESLint at ang plugin na eslint-plugin-sonarjs (panuntunang no-duplicate-string) at ang utility na jscpd, na sumusuporta sa 150+ wika. Ang jscpd ay partikular na maginhawa para sa monorepo: nakakahanap ito ng mga duplikado sa pagitan ng mga pakete, hindi lamang sa loob ng isang modyul.
Ang refactoring ng kopya-paste ay bumaba sa isang prinsipyo: i-extract ang karaniwan at i-parametrize ang mga pagkakaiba. Ang tiyak na pamamaraan ay depende sa dami ng pagdodoble at konteksto.
Ang pinakasimpleng kaso — pagdodoble sa loob ng isang klase (halimbawa, dalawang pamamaraan na may parehong lohika ngunit magkaibang uri). Solusyon — gawing pangkalahatan sa pamamagitan ng generics o gamitin muli ang pamamaraan na may parameter ng uri. Kung ang pagdodoble ay sumasaklaw sa maraming klase — i-extract ang karaniwang code sa isang utility class o extension function.
Mas kumplikadong kaso — pagdodoble sa antas ng screen o modyul. Dito hindi nakakatulong ang simpleng pag-extract ng function, dahil ang istruktura ng UI, lohika ng lifecycle, at pagbubuklod ng data ay nadodoble. Solusyon — gumawa ng karaniwang base class ng screen o composite View component, at ipasa ang mga pagkakaiba sa pamamagitan ng mga parameter o protocol.
// bago - dalawang kopya ng parehong UITableViewController
class UserListController: UITableViewController {
private let viewModel = UserListViewModel()
// 40 linya ng code
}
class ProductListController: UITableViewController {
private let viewModel = ProductListViewModel()
// parehong 40 linya ngunit may Product sa halip na User
}
// pagkatapos - ibinahaging generic na base class
class ListViewController<T: ListViewModel>: UITableViewController {
let viewModel: T
// 40 linya ng code - isang beses lamang
init(viewModel: T) {
self.viewModel = viewModel
super.init(style: .plain)
}
}
Ang pinakakomplikadong kaso — pagdodoble sa pagitan ng microservice o library. Ang pag-extract ng karaniwang code ay maaaring humantong sa cyclic dependency o hindi makatarungang pagsasama. Sa ganitong mga kaso, ang kopya-paste ay maaaring isang malay na desisyon: dalawang koponan ang nagpapanatili ng independiyenteng serbisyo, at ang shared library ay lumilikha ng mas maraming problema kaysa nalulutas. Ang pinakamahalaga — idokumento ang gayong desisyon at regular na suriin kung ang mga kopya ay nagkahiwalay nang sapat na oras na para sa unipikasyon.
Ang pag-iwas sa kopya-paste ay mas epektibo kaysa refactoring ng nadobleng code. Ang mga pangunahing hakbang sa pag-iwas ay nasa organisasyon ng proseso ng pag-develop, hindi sa teknolohiya.
Ang unang hakbang — code review na may diin sa pagdodoble. Ang checklist ng review ay dapat magsama ng punto: “May code ba sa PR na ito na nasa proyekto na?”. Kung ang reviewer ay nakakakita ng kopya-paste — hinaharangan niya ang merge hanggang sa ma-extract ang karaniwang component. Ang pangangailangang ito ay dapat na nakasaad sa Definition of Done ng koponan.
Ang pangalawang hakbang — shared component library. Ang bawat pattern ng UI na lumilitaw sa dalawa o higit pang screen ay dapat i-extract sa isang karaniwang modyul. Gumawa ng shared module sa proyekto at gawin itong sapilitang entry point para sa lahat ng UI component. Kung wala ang component — gawin muna ito, bago gamitin sa screen.
Ang pangatlong hakbang — automation sa CI/CD. Magdagdag ng hakbang sa pipeline na may pagsusuri ng nadobleng code (PMD CPD, jscpd, SonarQube). Ang paglampas sa threshold — error sa build. Hindi ma-merge ng developer ang isang PR na nagpapataas ng bahagi ng kopya-paste nang higit sa pinapayagang antas. Ito ay naglilipat ng responsibilidad mula sa code review patungo sa automation at ginagarantiyang walang duplikado na makaligtaan.
Ipakilala ang kulturang “isang implementasyon — isang lugar”. Kung makakita ka ng posibilidad ng muling paggamit — huwag ipagpaliban ang refactoring. Bawat kopya-paste na iniwan “para sa susunod” ay dumarami at nagiging hindi makontrol na teknikal na utang.
Mga madalas itanong
Hindi, may mga senaryo ng malay na pagdodoble: iba't ibang microservice na kailangang mag-evolve nang independyente; code na kinopya para sa eksperimento na may planong pagtanggal; template DTO para sa iba't ibang bersyon ng API. Ang mahalaga ay idokumento ang dahilan at magtakda ng termino ng pagsusuri para sa refactoring.
Kopya-paste — kapag ang dalawang bahagi ng code ay gumagawa ng parehong bagay ngunit walang karaniwang abstraksiyon. Malusog na muling paggamit — kapag ang karaniwang code ay na-extract sa isang function, klase, o modyul, at ang mga pagkakaiba ay naka-parametrize. Kung ang pagbabago ng lohika ay nangangailangan ng pag-aayos sa tatlo o higit pa na lugar — ito ay kopya-paste.
PMD CPD ay sumusuporta sa Swift at Objective-C. Para sa Xcode may mga plugin tulad ng SwiftCop at built-in na duplikadong detector sa AppCode. Sinusuri din ng SonarQube ang Swift projects, na nagpapakita ng mga nadobleng bloke nang direkta sa pull request.
Gumawa ng technical ticket para sa refactoring ng bawat malaking kopya. Itakda ang priyoridad: mga screen na madalas magbago — una, stable — pangalawa. Para sa bawat bagong PR na tumatalakay sa nadobleng code, maglaan ng 15–20 porsiyento ng oras para sa unti-unting pagsasama-sama.
Oo, ang mga modernong AI assistant (GitHub Copilot, Codeium) ay maaaring mag-analisa ng konteksto at magmungkahi ng pag-extract ng karaniwang code kapag nakakita ng paulit-ulit na pattern. Gayunpaman, hindi nila pinapalitan ang mga automatic analyzer — gamitin ang Copilot para sa pag-iwas, at CPD / SonarQube para sa detection.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din