Code Smell a mobilfejlesztésben: lényeg, típusok és a javítás elvei

Szerző: IT Sectr Megjelenés: 2026-05-13 Olvasási idő: 9 perc

A Code Smell egy felszínes jel a kódban, amely potenciális problémára utal az alkalmazás tervezésében vagy architektúrájában. A kifejezést Kent Beck vezette be és Martin Fowler népszerűsítette a „Refactoring: Improving the Design of Existing Code“ című könyvében. Martin Fowler szerint a kódszag nem feltétlenül jelent hibát, de szinte mindig a refaktorálás szükségességére utal a karbantarthatóság javítása érdekében.

Főbb pontok

  • Code Smell — a probléma külső jele a kódban, ami nem hiba, de megnehezíti a karbantartást és fejlesztést
  • Hosszú metódus — a leggyakoribb szag: túl sokat csináló metódus, amelyet többre kell bontani
  • Nagy osztály — az Single Responsibility Principle-t megsértő osztály, amely különböző domainek logikáját tartalmazza
  • Duplicate code — ismétlődő kódrészletek, amelyeket változtatáskor több helyen kell javítani
  • Feature envy — metódus, amely többet használ más osztály adataiból, mint a sajátjából

Mi az a Code Smell

Code Smell (kódszag) — metafora a forráskódban megjelenő tünetekre, amelyek nagy valószínűséggel mélyebb problémákra utalnak. Maga a kifejezés nem rendelkezik formális meghatározással — ez egy heurisztika, amely a fejlesztők tapasztalatán alapul. Martin Fowler és Kent Beck 1999-ben először rendszerezte 22 szagot a „Refactoring“ könyvben, és többségük évtizedekkel később is aktuális.

Fontos megérteni a különbséget a Code Smell és a hiba között. A szag nem hiba: a kód lefordul, működik és helyes eredményt ad. A probléma az, hogy az ilyen kódot nehéz olvasni, módosítani és tesztelni. Idővel minden változtatás költsége nő, a refaktorálás helyességébe vetett bizalom pedig csökken. A statikus elemző eszközök (SonarQube, Detekt, SwiftLint) számos szagot automatikusan észlelnek.

A Code Smell heurisztikus jellege azt jelenti, hogy nem minden hosszú metódust kell szétbontani és nem minden nagy osztály igényel refaktorálást. A döntést a fejlesztő hozza meg, értékelve a kontextust: a változtatások gyakoriságát, a modul kritikusságát, a fejlesztési terveket. A tapasztalt mérnökök ösztönösen érzik a szagot — a kód „kellemetlen szagú“, annak ellenére, hogy formálisan minden szabályt betartanak.

A Code Smell fő típusai

Fowler 22 szagot különböztetett meg, amelyek több kategóriába sorolhatók. A mobilfejlesztés szempontjából a legrelevánsabbak a strukturális szagok, az objektumorientált tervezési szagok és a platformkorlátokhoz kapcsolódó specifikus problémák. Vizsgáljuk meg az egyes csoportokat valós gyakorlatból vett példákkal.

Strukturális szagok

Long Method (hosszú metódus) — a legelterjedtebb szag a mobilalkalmazásokban. A regisztrációs űrlappal rendelkező képernyő gyakran tartalmaz egyetlen 200+ soros setupUI metódust, amely létrehozza az összes View-t, beállítja a megszorításokat, feliratkozik az eseményekre és kezeli a hibákat. Megoldás: logikai blokkok szerinti metódusokra bontás — configureEmailField, configurePasswordField, setupConstraints, bindViewModel.

Large Class (nagy osztály) — Activity vagy ViewController, amely felelős a megjelenítésért, navigációért, üzleti logikáért és hálózati kommunikációért. Az ilyen osztály megsérti az Single Responsibility Principle-t és tucatnyi mezőt és metódust tartalmaz. Androidban ez gyakran egy 1000+ soros Fragment, amely különböző képernyők logikáját tartalmazza. Megoldás: presenter/ViewModel szétválasztása, a hálózati munka áthelyezése a repository-ba, a navigáció áthelyezése a koordinátorba.

Duplicate Code (kódduplikáció) — azonos blokkok másolása az alkalmazás különböző részein. Tipikus példa: két képernyő, amely a termékkártyát jeleníti meg — a katalógusban és a kedvencekben. Ha a megjelenítési logika másolva van, egy hiba javítása az egyik helyen nem fogja azt a másik helyen is kijavítani. Megoldás: a közös logika áthelyezése újrafelhasználható komponensbe vagy kiterjesztésbe.

Objektumorientált tervezési szagok

Feature Envy (irigység más osztályra) — egy osztály metódusa intenzíven használja más osztály adatait. Androidban ez akkor nyilvánul meg, amikor a ViewModel közvetlenül hozzáfér a User modell mezőihez ahelyett, hogy meghívná a modell metódusát. Jel: ha a metódus áthelyezhető abba az osztályba, amelynek adatait használja — helyezze át. Switch Statements (feltételláncok) — switch szerkezet vagy if-else lánc, amely az objektum típusát ellenőrzi. Ehelyett polimorfizmust vagy strategy pattern-t kell használni.

Data Class — osztály, amely csak adatokat tárol, de nem tartalmaz viselkedést. Maguk a data class-ok (Kotlinban) vagy struktúrák (Swiftben) nem szagok. A probléma akkor jelentkezik, amikor az ezekkel az adatokkal dolgozó üzleti logika szét van szórva a teljes kódbázisban ahelyett, hogy be lenne ágyazva. Refused Bequest — az örökös nem használja a szülő metódusainak többségét és üres megvalósításokkal bírálja felül. Helytelen öröklés jele: cserélje ki az öröklést kompozícióra.

Szagok a mobilfejlesztésben

God Activity / God Fragment — Activity vagy Fragment, amely mindent tud: az életciklusról, az adatokról, a navigációról, az engedélyekről, a DI-ről. Ez az alkalmazás legdrágábban karbantartható osztálya. Megoldás: az MVVM, MVI vagy Clean Architecture architektúra minták megosztják a felelősséget. Giant ViewController — analógia iOS-re, ahol az UIViewController tartalmazza a képernyő teljes logikáját és gyakran meghaladja az 500 sort.

Hardcoded Resources — karakterláncok, színek, méretek, API URL-ek közvetlenül a kódba ágyazva. Androidban ez megsérti az R erőforrásrendszer használatát, iOS-ben — az NSLocalizedString és Asset Catalog használatát. Javítás: az összes karakterlánc áthelyezése a strings.xml vagy Localizable.strings fájlba, URL-ek áthelyezése konfigurációs fájlba, méretek áthelyezése a dimens-be. Leaking Context — az Activity-re vagy ViewController-re való hivatkozás tovább tárolása, mint ameddig az komponens él. Memóriaszivárgáshoz és összeomlásokhoz vezet. Megoldás: gyenge hivatkozások, Jetpack Lifecycle, RxSwift DisposeBag.

SzagHol fordul előMegoldás
Long MethodAndroid/iOSExtract Method, bontás
Large ClassActivity, ViewControllerMVVM, VIPER, Clean Arch
Duplicate CodeBármely képernyőShared Component, DRY
Feature EnvyViewModel, PresenterMove Method
Leaking ContextAndroidÉletciklus-tudatos komponensek

Hogyan találjuk meg a Code Smell-t

Code review — a szagok észlelésének legmegbízhatóbb módja. Az emberi szem észreveszi a természetellenes szerkezeteket, amelyeket az automatikus elemzők kihagynak. A kódellenőrzés hatékonysága nő, ha a csapat tipikus szagok ellenőrzőlistáját használja. Javasolt egy munkamenetben legfeljebb 200–400 sor kód ellenőrzése — e küszöb után a figyelem csökken és a szagok kezdenek elkerülni.

Statikus elemzés automatizálja a strukturális szagok keresését. Android esetén a szabvány eszközök a Detekt (Kotlin) és az Android Lint, iOS esetén — a SwiftLint és a SonarQube. Ezek az eszközök hosszú metódusokat, nagy osztályokat, kódduplikációt és számos más problémát találnak. Fontos a szabályokat a projekthez igazítani — az alapértelmezett konfigurációk gyakran túl szigorúak, vagy éppen ellenkezőleg, kritikus szagokat hagynak ki.

Kódmetrikák objektív kritériumokat adnak: Cyclomatic Complexity (küszöb >10 figyelmet igényel), Lines of Code per Method (küszöb >30), Depth of Inheritance (>3 — elgondolkodtató ok). Az olyan eszközök, mint a CodeMetrics (Xcode) és a Gradle Metrics Plugin, a metrikák idřbeli változásának grafikonjait készítik. Ha egy metódus komplexitása az utolsó commit után 5-ről 15-re nőtt — ez refaktorálási jelzés.

kotlin
// Példa: Cyclomatic komplexitású = 7 metódus (5-ös küszöb felett)
fun processOrder(order: Order) {
    if (order.status == Status.NEW) { /* 10 sor */ }
    else if (order.status == Status.PAID) { /* 15 sor */ }
    else if (order.status == Status.SHIPPED) { /* 20 sor */ }
    else if (order.status == Status.DELIVERED) { /* 8 sor */ }
    else if (order.status == Status.CANCELLED) { /* 5 sor */ }
    else { throw IllegalStateException() }
}

// Javítás: polimorfizmus switch helyett
interface OrderHandler {
    fun handle(order: Order)
}

Automatikus szagkeresés nem helyettesíti a kódellenőrzést: a statikus elemzők csak strukturális problémákat találnak, de nem érzékelik a szemantikus szagokat (Feature Envy, Inappropriate Intimacy). Az automatikus eszközök és az emberi ellenőrzés kombinációja adja a legjobb eredményt. Állítsa be a CI/CD csœvezetéket úgy, hogy a build meghiúsuljon a komplexitási vagy metódushossz küszöbök túllépése esetén.

Hogyan javítsuk a Code Smell-t

Refaktorálás — a kódszagok megszüntetésének fő módszere. Fowler tucatnyi refaktorálási technikát ír le, amelyek mindegyike egy adott szagra alkalmazható. Extract Method — hosszú metódusokhoz, Extract Class — nagy osztályokhoz, Move Method — Feature Envy-hez. Fontos a refaktorálást kis lépésekben végezni, megtartva a kód működőképességét minden változtatás után.

Tesztek a refaktorálás előtt — kötelező feltétel. Ha a kód nincs lefedve egységtesztekkel, a refaktorálás ismeretlen eredménnyel járó átírássá válik. Tesztek nélkül i rendszerörökség kódhoz használjon Characterisation Tests — írjon teszteket, amelyek rögzítik a jelenlegi viselkedést, majd refaktoráljon. A tesztelés biztosítja, hogy a refaktorálás után az üzleti logika nem sérült.

Fokozatosság — a szagok sikeres megszüntetésének kulcsa a mobilfejlesztésben. Ne próbálja teljes egészében átírni a God Activity-t. Először a navigációs réteget válassza le, majd az adatréteget, aztán a megjelenítési logikát. Minden lépést kísérjen commit és tesztek futtatása. Használjon feature toggle-t a refaktorálás bekapcsolásához a felhasználók egy részére és visszaállításához probléma esetén.

  • Extract Method — bontsa fel a hosszú metódust több rövidre érthető névvel
  • Extract Class — válasszon le egy kapcsolódó mező- és metóduscsoportot külön osztályba
  • Replace Conditional with Polymorphism — cserélje le a switch-et osztályhierarchiára
  • Introduce Parameter Object — egyesítse a paramétercsoportot egy objektummá
  • Replace Inheritance with Delegation — cserélje le az extends-t kompozícióra

IDE eszközök számos refaktorálási technikát automatizálnak. Az Android Studio és az IntelliJ IDEA beépített refaktorálásokat kínál: Extract Method, Extract Interface, Pull Members Up, Encapsulate Fields. Az Xcode (14-es verziótól kezdve) javította a Swift refaktorálási támogatását. Az automatikus refaktorálások használata csökkenti a hibák kockázatát a kód kézi másolásához képest.

Code Smell a mobilfejlesztésben

Mobilfejlesztés hozzáadja a saját specifikus szagait, amelyek a platformkorlátokhoz kapcsolódnak. Androidban ezek a Context szivárgása, a le nem zárt Cursor, a Lifecycle helytelen használata. iOS-ben — retain cycle a closure-okon keresztül, helytelen munka az Auto Layout-tal, óriási ViewController-ek. Ezek a szagok nemcsak rontják a karbantarthatóságot, hanem közvetlenül befolyásolják az alkalmazás teljesítményét és stabilitását.

Callback Hell — az aszinkron műveletekkel dolgozó kód jellegzetes szaga. Az egymásba ágyazott callback-ek (callback inside callback) olvashatatlanná és nehezen hibakereshetővé teszik a kódot. Megoldás: korutinok (Kotlin), async/await (Swift 5.5+), RxJava/RxSwift vagy Combine. A Google I/O 2023 szerint a callback stílusról korutinokra áttérő projektek 30%-kal csökkentik a hibák számát és felgyorsítják az új funkciók hozzáadását.

Platform Coupling — az üzleti logika merev hozzákötése a platformkomponensekhez. Az ilyen logika tesztelése az emulátor elindítását igényli, ami lelassítja a visszacsatolási hurkot. Javítás: a Clean Architecture rétegekre bontja a kódot: Domain (tiszta Kotlin/Swift platformfüggőségek nélkül) és Data/UI (platformfüggőségekkel). Az üzleti logika JVM-en tesztelhető emulátor nélkül.

Gyakran ismételt kérdések

A Code Smell ugyanaz, mint a hiba?

Nem — a Code Smell nem hiba. A szaggal rendelkező kód helyesen működik, de nehéz karbantartani, módosítani és tesztelni. A hiba helytelen viselkedés, a szag figyelmeztetés a jövőbeni lehetséges problémákról.

Hány szagot különböztetett meg Martin Fowler?

22 szagot a „Refactoring“ könyv második kiadásában (2019). Köztük a Long Method, Large Class, Primitive Obsession, Data Clumps, Switch Statements, Speculative Generality és mások. A közösség tucatnyi új szagot adott hozzá a modern paradigmák és platformok számára.

Melyik eszköz találja meg a legjobban a Code Smell-t?

Kombináció adja a legjobb eredményt: Detekt (Android/Kotlin), SwiftLint (iOS), SonarQube (mindkettő) az automatikus elemzéshez és a kódellenőrzés a szemantikus szagokhoz. Egyetlen eszköz sem találja meg a problémák 100%-át — az emberi tapasztalat továbbra is döntő.

Figyelmen kívül hagyható a Code Smell?

Igen, ha a kód ritkán változik, vagy a közeljövőben teljesen átírásra kerül. A szagok felhalmozódása azonban technikai adóssággá válik: minden új változtatás egyre nehezebbé válik, és a javítás költsége exponenciálisan nő.

Vannak a SwiftUI és Jetpack Compose specifikus szagai?

Igen — a deklaratív keretrendszerek új szagokat hoztak létre: óriási @State blokkok, helytelen munka az ismételt renderelésekkel, túlzott recomposition, hiányzó kivonatolás külön View-kba. A SwiftUI tipikus szaga a Massive View tucatnyi @State változóval.

Összefoglalás

  • Code Smell — a mély kódprobléma felszínes jele, ami nem hiba, de csökkenti a karbantarthatóságot
  • Long Method és Large Class — a leggyakoribb szagok a mobilfejlesztésben, Extract Method és Extract Class szükséges
  • Duplicate Code — a logika duplikálása, ami minden változtatásnál megkétszerezi a munkát
  • Feature Envy és Switch Statements — a felelősség helytelen elosztásának jelei az osztályok között
  • Specifikus szagok — God Activity, Giant ViewController, Leaking Context — egyediek a mobil platformokon
  • Refaktorálás tesztek nélkül veszélyes: először Characterisation Tests, aztán kis lépések commit-okkal
  • Statikus elemzés (Detekt, SwiftLint) automatizálja a keresést, de nem helyettesíti a kódellenőrzést

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is