Code Smell sa mobile development: esensya, mga uri at prinsipyo ng pag-aayos

May-akda: IT Sectr Nai-publish: 2026-05-13 Oras ng pagbabasa: 9 min

Ang Code Smell ay isang mababaw na senyales sa code na nagpapahiwatig ng potensyal na problema sa disenyo o arkitektura ng aplikasyon. Ang terminong ito ay ipinakilala ni Kent Beck at pinasikat ni Martin Fowler sa aklat na “Refactoring: Improving the Design of Existing Code”. Ayon kay Martin Fowler, ang amoy ng code ay hindi nangangahulugang isang bug, ngunit halos palaging nagpapahiwatig ng pangangailangan para sa refactoring upang mapabuti ang pagpapanatili.

Mga Pangunahing

  • Code Smell — panlabas na senyales ng problema sa code na hindi error ngunit nagpapahirap sa pagpapanatili at pag-unlad
  • Mahabang metodo — pinakakaraniwang amoy: metodong gumagawa ng sobra at kailangang hatiin sa ilan
  • Malaking klase — klase na lumalabag sa Single Responsibility Principle at naglalaman ng lohika ng iba’t ibang domain
  • Duplicate code — mga paulit-ulit na fragment ng code na kailangang ayusin sa maraming lugar kapag binago
  • Feature envy — metodong mas gumagamit ng data ng ibang klase kaysa sa sarili nito

Ano ang Code Smell

Code Smell (amoy ng code) — ay isang metapora para sa mga sintomas sa source code na may mataas na posibilidad na nagpapahiwatig ng mas malalalim na problema. Ang termino mismo ay walang pormal na depinisyon — ito ay isang heuristik batay sa karanasan ng mga developer. Sina Martin Fowler at Kent Beck noong 1999 ay unang nagsistema ng 22 amoy sa aklat na “Refactoring”, at karamihan sa mga ito ay nananatiling may kaugnayan pagkatapos ng mga dekada.

Mahalagang maunawaan ang pagkakaiba sa pagitan ng Code Smell at bug. Ang amoy ay hindi error: nagko-compile ang code, gumagana at nagbibigay ng tamang resulta. Ang problema ay ang naturang code ay mahirap basahin, baguhin at subukan. Sa paglipas ng panahon, tumataas ang gastos ng bawat pagbabago at bumababa ang tiwala sa kawastuhan ng refactoring. Ang mga tool ng static analysis (SonarQube, Detekt, SwiftLint) ay awtomatikong nakakakita ng maraming amoy.

Ang heuristikong katangian ng Code Smell ay nangangahulugang hindi lahat ng mahabang metodo ay kailangang hatiin at hindi lahat ng malaking klase ay nangangailangan ng refactoring. Ang desisyon ay ginagawa ng developer, sinusuri ang konteksto: dalas ng mga pagbabago, kritikalidad ng modyul, mga plano sa pag-unlad. Nararamdaman ng mga bihasang inhinyero ang amoy nang intuitive — ang code ay “may hindi kanais-nais na amoy”, kahit na pormal na lahat ng mga patakaran ay sinusunod.

Mga pangunahing uri ng Code Smell

Si Fowler ay nagtalaga ng 22 amoy na nahahati sa ilang kategorya. Para sa mobile development, ang pinaka-kaugnay ay mga structural na amoy, object-oriented design na amoy, at mga spesipikong problema na may kaugnayan sa mga limitasyon ng platform. Tingnan natin ang bawat grupo na may mga halimbawa mula sa tunay na praktika.

Mga structural na amoy

Long Method (mahabang metodo) — pinakakaraniwang amoy sa mga mobile application. Ang screen na may registration form ay madalas na naglalaman ng isang setupUI na metodo na may 200+ linya na lumilikha ng lahat ng View, nag-aayos ng mga constraint, nag-subscribe sa mga event at humahawak ng mga error. Solusyon: hatiin sa mga metodo ayon sa lohikal na bloke — configureEmailField, configurePasswordField, setupConstraints, bindViewModel.

Large Class (malaking klase) — Activity o ViewController na responsable para sa pagpapakita, nabigasyon, lohika ng negosyo at komunikasyon sa network. Ang ganitong klase ay lumalabag sa Single Responsibility Principle at naglalaman ng dose-dosenang mga field at metodo. Sa Android, ito ay madalas na Fragment na may 1000+ linya na naglalaman ng lohika ng iba’t ibang screen. Solusyon: paghiwalayin ang presenter/ViewModel, ilipat ang network work sa repository, nabigasyon sa coordinator.

Duplicate Code (duplikasyon ng code) — pagkopya ng parehong bloke sa iba’t ibang bahagi ng aplikasyon. Tipikal na halimbawa: dalawang screen na nagpapakita ng card ng produkto — sa catalog at sa mga paborito. Kung ang lohika ng pagpapakita ay kinopya, ang pag-aayos ng bug sa isang lugar ay hindi ito aayusin sa iba. Solusyon: ilipat ang karaniwang lohika sa isang reusable na component o extension.

Mga amoy ng object-oriented na disenyo

Feature Envy (inggit sa ibang klase) — ang metodo ng isang klase ay masinsinang gumagamit ng data ng ibang klase. Sa Android, ito ay nagpapakita kapag ang ViewModel ay direktang pumupunta sa mga field ng User model sa halip na tumawag ng metodo ng model. Senyales: kung ang metodo ay maaaring ilipat sa klase na ang data ay ginagamit nito — ilipat ito. Switch Statements (mga chain ng kondisyon) — konstruksiyon ng switch o chain ng if-else na sumusuri sa uri ng object. Sa halip, dapat gamitin ang polymorphism o strategy pattern.

Data Class — klase na nag-iimbak lamang ng data ngunit walang pag-uugali. Ang data class (sa Kotlin) o mga istruktura (sa Swift) ay hindi amoy sa kanilang sarili. Ang problema ay lumilitaw kapag ang lohika ng negosyo na gumagana sa data na ito ay nakakalat sa buong code base sa halip na ma-encapsulate. Refused Bequest — ang tagapagmana ay hindi gumagamit ng karamihan sa mga metodo ng magulang at pinapalitan ang mga ito ng mga walang laman na implementasyon. Tanda ng maling pagmamana: palitan ang pamamana ng komposisyon.

Mga amoy sa mobile development

God Activity / God Fragment — Activity o Fragment na alam ang lahat: tungkol sa lifecycle, data, nabigasyon, mga pahintulot, DI. Ito ang pinakamahal na klase na panatilihin sa aplikasyon. Solusyon: mga pattern ng arkitektura na MVVM, MVI o Clean Architecture ay naghahati ng responsibilidad. Giant ViewController — analog para sa iOS, kung saan ang UIViewController ay naglalaman ng lahat ng lohika ng screen at madalas na lumalampas sa 500 linya.

Hardcoded Resources — mga string, kulay, sukat, URL ng API na direktang naka-embed sa code. Sa Android, ito ay lumalabag sa paggamit ng R resource system, sa iOS — NSLocalizedString at Asset Catalog. Pag-aayos: ilipat ang lahat ng string sa strings.xml o Localizable.strings, URL sa configuration file, mga sukat sa dimens. Leaking Context — pag-iingat ng reference sa Activity o ViewController nang mas mahaba kaysa sa buhay ng component mismo. Nagdudulot ng pagtagas ng memorya at mga crash. Solusyon: mahinang reference, Jetpack Lifecycle, RxSwift DisposeBag.

AmoySaan matatagpuanSolusyon
Long MethodAndroid/iOSExtract Method, paghahati
Large ClassActivity, ViewControllerMVVM, VIPER, Clean Arch
Duplicate CodeKahit anong screenShared Component, DRY
Feature EnvyViewModel, PresenterMove Method
Leaking ContextAndroidMga component na may kamalayan sa lifecycle

Paano mahanap ang Code Smell

Code review — pinakamaaasahang paraan ng pagtuklas ng mga amoy. Nakikita ng mata ng tao ang mga hindi natural na konstruksyon na hindi napapansin ng mga automatic analyzer. Ang bisa ng code review ay tumataas kapag ang koponan ay gumagamit ng checklist ng mga karaniwang amoy. Inirerekomenda na suriin ang hindi hihigit sa 200–400 linya ng code sa isang session — pagkatapos ng threshold na ito, bumababa ang atensyon at nagsisimulang makatakas ang mga amoy.

Static analysis ay nag-automate ng paghahanap ng mga structural na amoy. Para sa Android, ang karaniwang tool ay Detekt (Kotlin) at Android Lint, para sa iOS — SwiftLint at SonarQube. Ang mga tool na ito ay nakakahanap ng mahabang metodo, malalaking klase, duplikasyon ng code at marami pang ibang problema. Mahalagang i-configure ang mga patakaran para sa proyekto — ang mga default na configuration ay madalas na masyadong mahigpit o, kabaligtaran, hindi napapansin ang mga kritikal na amoy.

Mga metrik ng code ay nagbibigay ng mga obhetibong kriterya: Cyclomatic Complexity (threshold >10 ay nangangailangan ng atensyon), Lines of Code per Method (threshold >30), Depth of Inheritance (>3 — dahilan upang mag-isip). Ang mga tool tulad ng CodeMetrics (Xcode) at Gradle Metrics Plugin ay gumagawa ng mga graph ng pagbabago ng metrik sa paglipas ng panahon. Kung ang kompleksidad ng metodo ay tumaas mula 5 hanggang 15 pagkatapos ng huling commit — ito ay senyales para sa refactoring.

kotlin
// Halimbawa: metodo na may kompleksidad na Cyclomatic = 7 (higit sa threshold na 5)
fun processOrder(order: Order) {
    if (order.status == Status.NEW) { /* 10 linya */ }
    else if (order.status == Status.PAID) { /* 15 linya */ }
    else if (order.status == Status.SHIPPED) { /* 20 linya */ }
    else if (order.status == Status.DELIVERED) { /* 8 linya */ }
    else if (order.status == Status.CANCELLED) { /* 5 linya */ }
    else { throw IllegalStateException() }
}

// Pag-aayos: polymorphism sa halip na switch
interface OrderHandler {
    fun handle(order: Order)
}

Ang automatic na paghahanap ng amoy ay hindi pumapalit sa code review: ang mga static analyzer ay nakakahanap lamang ng mga structural na problema, ngunit hindi nakuha ang mga semantikong amoy (Feature Envy, Inappropriate Intimacy). Ang kombinasyon ng mga automatic na tool at kontrol ng tao ay nagbibigay ng pinakamahusay na resulta. I-configure ang CI/CD pipeline upang ang build ay mabigo kapag lumampas sa mga threshold ng kompleksidad o haba ng metodo.

Paano ayusin ang Code Smell

Refactoring — pangunahing paraan ng pag-alis ng mga amoy ng code. Inilalarawan ni Fowler ang dose-dosenang mga technique ng refactoring, bawat isa ay naaangkop sa isang partikular na amoy. Extract Method — para sa mahabang metodo, Extract Class — para sa malalaking klase, Move Method — para sa Feature Envy. Mahalagang isagawa ang refactoring sa maliliit na hakbang, na pinapanatili ang paggana ng code pagkatapos ng bawat pagbabago.

Mga pagsubok bago ang refactoring — isang sapilitang kondisyon. Kung ang code ay hindi sakop ng mga unit test, ang refactoring ay nagiging muling pagsulat na may hindi kilalang resulta. Para sa legacy code na walang mga pagsubok, gumamit ng Characterisation Tests — sumulat ng mga pagsubok na nagtatala ng kasalukuyang pag-uugali, pagkatapos ay mag-refactor. Ang pagsubok ay nagbibigay ng katiyakan na ang lohika ng negosyo ay hindi nasira pagkatapos ng refactoring.

Pagiging gradual — susi sa matagumpay na pag-aalis ng mga amoy sa mobile development. Huwag subukang muling isulat ang God Activity nang buo. Ihiwalay muna ang layer ng nabigasyon, pagkatapos ang layer ng data, pagkatapos ang lohika ng pagpapakita. Bawat hakbang ay samahan ng commit at pagpapatakbo ng mga pagsubok. Gumamit ng feature toggle upang i-activate ang refactoring para sa bahagi ng mga user at i-rollback kung may mga problema.

  • Extract Method — hatiin ang mahabang metodo sa ilang maiikli na may malinaw na mga pangalan
  • Extract Class — ihiwalay ang kaugnay na grupo ng mga field at metodo sa isang hiwalay na klase
  • Replace Conditional with Polymorphism — palitan ang switch ng hierarchy ng klase
  • Introduce Parameter Object — pagsamahin ang grupo ng mga parameter sa isang object
  • Replace Inheritance with Delegation — palitan ang extends ng komposisyon

Mga tool ng IDE ay nag-automate ng maraming technique ng refactoring. Ang Android Studio at IntelliJ IDEA ay nag-aalok ng built-in na refactoring: Extract Method, Extract Interface, Pull Members Up, Encapsulate Fields. Ang Xcode (simula sa bersyon 14) ay pinabuti ang suporta para sa refactoring sa Swift. Ang paggamit ng automatic na refactoring ay nagbabawas ng panganib ng mga error kumpara sa manu-manong pagkopya ng code.

Code Smell sa mobile development

Ang mobile development ay nagdaragdag ng sarili nitong mga spesipikong amoy na may kaugnayan sa mga limitasyon ng platform. Sa Android, ito ay pagtagas ng Context, hindi saradong Cursor, hindi tamang paggamit ng Lifecycle. Sa iOS — retain cycle sa pamamagitan ng closures, hindi tamang pagtatrabaho sa Auto Layout, mga higanteng ViewController. Ang mga amoy na ito ay hindi lamang nagpapalala ng pagpapanatili, kundi direktang nakakaapekto sa pagganap at katatagan ng aplikasyon.

Callback Hell — isang katangiang amoy para sa code na gumagana sa mga asynchronous na operasyon. Ang mga nested callback (callback inside callback) ay ginagawang hindi nababasa at mahirap i-debug ang code. Solusyon: coroutine (Kotlin), async/await (Swift 5.5+), RxJava/RxSwift o Combine. Ayon sa Google I/O 2023, ang mga proyektong lumipat mula sa callback style patungo sa coroutine ay nagbabawas ng bilang ng mga bug ng 30% at nagpapabilis ng pagdagdag ng mga bagong feature.

Platform Coupling — mahigpit na pag-uugnay ng lohika ng negosyo sa mga component ng platform. Ang pagsubok ng naturang lohika ay nangangailangan ng pagpapatakbo ng emulator, na nagpapabagal sa feedback loop. Pag-aayos: Hinahati ng Clean Architecture ang code sa mga layer na Domain (purong Kotlin/Swift na walang dependencies sa platform) at Data/UI (na may mga dependency sa platform). Ang lohika ng negosyo ay sinusubok sa JVM nang walang emulator.

Mga madalas itanong

Ang Code Smell ba ay pareho ng bug?

Hindi — ang Code Smell ay hindi error. Ang code na may amoy ay gumagana nang tama, ngunit mahirap panatilihin, baguhin at subukan. Ang bug ay hindi tamang pag-uugali, ang amoy ay babala tungkol sa mga potensyal na problema sa hinaharap.

Ilang amoy ang itinalaga ni Martin Fowler?

22 amoy sa ikalawang edisyon ng aklat na “Refactoring” (2019). Kabilang sa mga ito ang Long Method, Large Class, Primitive Obsession, Data Clumps, Switch Statements, Speculative Generality at iba pa. Ang komunidad ay nagdagdag ng dose-dosenang bagong amoy para sa mga modernong paradigma at platform.

Anong tool ang pinakamahusay na nakakahanap ng Code Smell?

Kombinasyon ang nagbibigay ng pinakamahusay na resulta: Detekt (Android/Kotlin), SwiftLint (iOS), SonarQube (pareho) para sa automatic analysis at code review para sa mga semantikong amoy. Walang tool na nakakahanap ng 100% ng mga problema — ang karanasan ng tao ay nananatiling mapagpasyahan.

Maaari bang balewalain ang Code Smell?

Maaari, kung ang code ay bihirang magbago o ganap na muling isusulat sa malapit na hinaharap. Gayunpaman, ang pag-iipon ng mga amoy ay nagiging teknikal na utang: ang bawat bagong pagbabago ay nagiging mas mahirap at ang gastos ng pag-aayos ay tumataas nang exponentially.

Mayroon bang mga amoy na spesipiko para sa SwiftUI at Jetpack Compose?

Oo — ang mga declarative framework ay lumikha ng mga bagong amoy: mga higanteng @State block, hindi tamang pagtatrabaho sa paulit-ulit na render, labis na recomposition, kawalan ng pag-extract sa mga hiwalay na View. Para sa SwiftUI, ang tipikal na amoy ay Massive View na may dose-dosenang @State variable.

Buod

  • Code Smell — mababaw na senyales ng malalim na problema sa code na hindi error ngunit nagbabawas ng pagpapanatili
  • Long Method at Large Class — pinakakaraniwang amoy sa mobile development, nangangailangan ng Extract Method at Extract Class
  • Duplicate Code — duplikasyon ng lohika na nagdodoble ng trabaho sa bawat pagbabago
  • Feature Envy at Switch Statements — mga tanda ng maling pamamahagi ng responsibilidad sa pagitan ng mga klase
  • Mga spesipikong amoy — God Activity, Giant ViewController, Leaking Context — natatangi para sa mga mobile platform
  • Refactoring nang walang pagsubok ay mapanganib: una Characterisation Tests, pagkatapos maliliit na hakbang na may mga commit
  • Static analysis (Detekt, SwiftLint) ay nag-automate ng paghahanap ngunit hindi pumapalit sa code review

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.

Pag-usapan ang proyekto

Basahin din