Code Smell v mobilním vývoji: podstata, typy a principy opravy

Autor: IT Sectr Publikováno: 2026-05-13 Doba čtení: 9 min

Code Smell je povrchový znak v kódu, který signalizuje potenciální problém v návrhu nebo architektuře aplikace. Termín zavedl Kent Beck a zpopularizoval Martin Fowler v knize „Refactoring: Improving the Design of Existing Code“. Podle Martina Fowlera, zápach kódu nemusí nutně znamenat chybu, ale téměř vždy ukazuje na potřebu refaktoringu pro zlepšení udržovatelnosti.

Hlavní

  • Code Smell — vnější znak problému v kódu, který není chybou, ale ztěžuje údržbu a vývoj
  • Dlouhá metoda — nejčastější pach: metoda, která dělá příliš mnoho a vyžaduje rozdělení na několik
  • Velká třída — třída porušující princip Single Responsibility a obsahující logiku různých domén
  • Duplicate code — opakující se fragmenty kódu, které je při změně třeba upravit na několika místech
  • Feature envy — metoda, která více využívá data jiné třídy než své vlastní

Co je Code Smell

Code Smell (zápach kódu) — je metafora pro příznaky ve zdrojovém kódu, které s vysokou pravděpodobností ukazují na hlubší problémy. Samotný termín nemá formální definici — je to heuristika založená na zkušenostech vývojářů. Martin Fowler a Kent Beck v roce 1999 poprvé systematizovali 22 pachů v knize „Refactoring“ a většina z nich zůstává aktuální i po desetiletích.

Je důležité pochopit rozdíl mezi Code Smell a chybou. Pach není chyba: kód se zkompiluje, funguje a dává správný výsledek. Problém je v tom, že takový kód je obtížné číst, měnit a testovat. Postupem času náklady na každou změnu rostou a důvěra ve správnost refaktoringu klesá. Nástroje statické analýzy (SonarQube, Detekt, SwiftLint) automaticky detekují mnoho pachů.

Heuristický charakter Code Smell znamená, že ne každou dlouhou metodu je třeba dělit a ne každá velká třída vyžaduje refaktoring. Rozhodnutí dělá vývojář, který posuzuje kontext: četnost změn, kritičnost modulu, plány rozvoje. Zkušení inženýři cítí pach intuitivně — kód „nepříjemně zapáchá“, i když formálně jsou všechna pravidla dodržena.

Hlavní typy Code Smell

Fowler rozlišil 22 pachů, které se dělí do několika kategorií. Pro mobilní vývoj jsou nejrelevantnější strukturální pachy, pachy objektově orientovaného návrhu a specifické problémy spojené s omezeními platformy. Pojďme prozkoumat každou skupinu na příkladech z reálné praxe.

Strukturální pachy

Long Method (dlouhá metoda) — nejrozšířenější pach v mobilních aplikacích. Obrazovka s registračním formulářem často obsahuje jednu metodu setupUI o délce 200+ řádků, která vytváří všechny View, nastavuje constrainty, přihlašuje se k událostem a zpracovává chyby. Řešení: rozdělení na metody podle logických bloků — configureEmailField, configurePasswordField, setupConstraints, bindViewModel.

Large Class (velká třída) — Activity nebo ViewController, který je odpovědný za zobrazení, navigaci, business logiku a síťovou komunikaci. Taková třída porušuje princip Single Responsibility a obsahuje desítky polí a metod. V Androidu je to často Fragment s 1000+ řádky obsahující logiku různých obrazovek. Řešení: oddělení presenteru/ViewModel, přesun síťové práce do repository, navigace do koordinátora.

Duplicate Code (duplikace kódu) — kopírování stejných bloků v různých částech aplikace. Typický příklad: dvě obrazovky zobrazující kartu produktu — v katalogu a v oblíbených. Pokud je logika zobrazení zkopírována, oprava chyby na jednom místě ji neopraví na druhém. Řešení: přesun společné logiky do znovupoužitelné komponenty nebo rozšíření.

Pachy objektově orientovaného návrhu

Feature Envy (závist vůči jiné třídě) — metoda jedné třídy intenzivně využívá data jiné třídy. V Androidu se to projevuje, když ViewModel přímo přistupuje k polím modelu User místo volání metody modelu. Signál: pokud lze metodu přesunout do třídy, jejíž data používá — přesuňte ji. Switch Statements (řetězce podmínek) — konstrukce switch nebo řetězec if-else kontrolující typ objektu. Místo toho je třeba použít polymorfismus nebo vzor strategy.

Data Class — třída, která pouze ukládá data, ale neobsahuje chování. Samy o sobě data class (v Kotlin) nebo struktury (ve Swift) nejsou pachem. Problém nastává, když je business logika pracující s těmito daty rozptýlena po celé kódové základně místo toho, aby byla zapouzdřena. Refused Bequest — dědic nepoužívá většinu metod rodiče a přepisuje je prázdnými implementacemi. Znak nesprávné dědičnosti: nahraďte dědičnost kompozicí.

Pachy v mobilním vývoji

God Activity / God Fragment — Activity nebo Fragment, který ví všechno: o životním cyklu, datech, navigaci, oprávněních, DI. Toto je nejdražší třída na údržbu v aplikaci. Řešení: architektonické vzory MVVM, MVI nebo Clean Architecture rozdělují odpovědnost. Giant ViewController — analogie pro iOS, kde UIViewController obsahuje veškerou logiku obrazovky a často přesahuje 500 řádků.

Hardcoded Resources — řetězce, barvy, velikosti, URL API vložené přímo do kódu. V Androidu to porušuje použití systému zdrojů R, v iOS — NSLocalizedString a Asset Catalog. Oprava: přesuňte všechny řetězce do strings.xml nebo Localizable.strings, URL do konfiguračního souboru, velikosti do dimens. Leaking Context — uchovávání reference na Activity nebo ViewController déle, než žije samotná komponenta. Vede k únikům paměti a pádům. Řešení: slabé reference, Jetpack Lifecycle, RxSwift DisposeBag.

PachKde se vyskytujeŘešení
Long MethodAndroid/iOSExtract Method, rozdělení
Large ClassActivity, ViewControllerMVVM, VIPER, Clean Arch
Duplicate CodeLibovolná obrazovkaShared Component, DRY
Feature EnvyViewModel, PresenterMove Method
Leaking ContextAndroidKomponenty vědomé životního cyklu

Jak najít Code Smell

Code review — nejspolehlivější způsob detekce pachů. Lidské oko vidí nepřirozené konstrukce, které automatické analyzátory přehlížejí. Efektivita code review se zvyšuje, pokud tým používá kontrolní seznam typických pachů. Doporučuje se kontrolovat ne více než 200–400 řádků kódu v jedné relaci — po tomto prahu pozornost klesá a pachy začínají unikat.

Statická analýza automatizuje vyhledávání strukturálních pachů. Pro Android jsou standardními nástroji Detekt (Kotlin) a Android Lint, pro iOS — SwiftLint a SonarQube. Tyto nástroje nacházejí dlouhé metody, velké třídy, duplikaci kódu a mnoho dalších problémů. Je důležité nakonfigurovat pravidla pro projekt — výchozí konfigurace jsou často příliš přísné nebo naopak přehlížejí kritické pachy.

Metriky kódu poskytují objektivní kritéria: Cyclomatic Complexity (práh >10 vyžaduje pozornost), Lines of Code per Method (práh >30), Depth of Inheritance (>3 — důvod k zamyšlení). Nástroje jako CodeMetrics (Xcode) a Gradle Metrics Plugin vytvářejí grafy změn metrik v čase. Pokud se složitost metody zvýšila z 5 na 15 po posledním commitu — to je signál k refaktoringu.

kotlin
// Příklad: metoda se složitostí Cyclomatic = 7 (nad prahem 5)
fun processOrder(order: Order) {
    if (order.status == Status.NEW) { /* 10 řádků */ }
    else if (order.status == Status.PAID) { /* 15 řádků */ }
    else if (order.status == Status.SHIPPED) { /* 20 řádků */ }
    else if (order.status == Status.DELIVERED) { /* 8 řádků */ }
    else if (order.status == Status.CANCELLED) { /* 5 řádků */ }
    else { throw IllegalStateException() }
}

// Oprava: polymorfismus místo switch
interface OrderHandler {
    fun handle(order: Order)
}

Automatické vyhledávání pachů nenahrazuje code review: statické analyzátory nacházejí pouze strukturální problémy, ale nezachycují sémantické pachy (Feature Envy, Inappropriate Intimacy). Kombinace automatických nástrojů a lidské kontroly poskytuje nejlepší výsledek. Nakonfigurujte CI/CD pipeline tak, aby build selhal při překročení prahů složitosti nebo délky metody.

Jak opravit Code Smell

Refaktoring — hlavní metoda eliminace pachů kódu. Fowler popisuje desítky technik refaktoringu, z nichž každá je použitelná na konkrétní pach. Extract Method — pro dlouhé metody, Extract Class — pro velké třídy, Move Method — pro Feature Envy. Je důležité provádět refaktoring v malých krocích a zachovat funkčnost kódu po každé změně.

Testy před refaktoringem — povinná podmínka. Pokud není kód pokryt jednotkovými testy, refaktoring se mění v přepisování s neznámým výsledkem. Pro legacy kód bez testů použijte Characterisation Tests — napište testy, které zaznamenávají současné chování, a poté refaktorujte. Testování poskytuje jistotu, že po refaktoringu není business logika poškozena.

Postupnost — klíč k úspěšnému odstraňování pachů v mobilním vývoji. Nepokoušejte se přepsat God Activity celou. Oddělte nejprve vrstvu navigace, poté vrstvu dat, pak logiku zobrazení. Každý krok doprovázejte commitem a spuštěním testů. Použijte feature toggle k zapnutí refaktoringu pro část uživatelů a vrácení zpět v případě problémů.

  • Extract Method — rozdělte dlouhou metodu na několik krátkých srozumitelnými názvy
  • Extract Class — oddělte související skupinu polí a metod do samostatné třídy
  • Replace Conditional with Polymorphism — nahraďte switch hierarchií tříd
  • Introduce Parameter Object — slučte skupinu parametrů do objektu
  • Replace Inheritance with Delegation — nahraďte extends kompozicí

Nástroje IDE automatizují mnoho technik refaktoringu. Android Studio a IntelliJ IDEA nabízejí vestavěné refaktoringy: Extract Method, Extract Interface, Pull Members Up, Encapsulate Fields. Xcode (od verze 14) zlepšil podporu refaktoringu pro Swift. Použití automatických refaktoringů snižuje riziko chyb ve srovnání s ručním kopírováním kódu.

Code Smell v mobilním vývoji

Mobilní vývoj přidává vlastní specifické pachy spojené s omezeními platformy. V Androidu jsou to únik Context, neuzavřený Cursor, nesprávné použití Lifecycle. V iOS — retain cycle přes closures, nesprávná práce s Auto Layout, gigantické ViewControllery. Tyto pachy nejen zhoršují udržovatelnost, ale přímo ovlivňují výkon a stabilitu aplikace.

Callback Hell — charakteristický pach pro kód pracující s asynchronními operacemi. Vnořené callbacky (callback inside callback) činí kód nečitelným a obtížně laditelným. Řešení: korutiny (Kotlin), async/await (Swift 5.5+), RxJava/RxSwift nebo Combine. Podle Google I/O 2023 projekty, které přešly z callback stylu na korutiny, snižují počet chyb o 30% a zrychlují přidávání nových funkcí.

Platform Coupling — pevné svázání business logiky s komponentami platformy. Testování takové logiky vyžaduje spuštění emulátoru, což zpomaluje zpětnou vazbu. Oprava: Clean Architecture rozděluje kód na vrstvy Domain (čistý Kotlin/Swift bez závislostí na platformě) a Data/UI (se závislostmi na platformě). Business logika se testuje na JVM bez emulátoru.

Často kladené otázky

Je Code Smell to samé co chyba?

Ne — Code Smell není chyba. Kód s pachem funguje správně, ale je obtížné ho udržovat, měnit a testovat. Chyba je nesprávné chování, pach je varování o potenciálních problémech v budoucnosti.

Kolik pachů rozlišil Martin Fowler?

22 pachů ve druhém vydání knihy „Refactoring“ (2019). Mezi nimi Long Method, Large Class, Primitive Obsession, Data Clumps, Switch Statements, Speculative Generality a další. Komunita přidala desítky nových pachů pro moderní paradigmata a platformy.

Který nástroj nejlépe nachází Code Smell?

Kombinace dává nejlepší výsledek: Detekt (Android/Kotlin), SwiftLint (iOS), SonarQube (oba) pro automatickou analýzu a code review pro sémantické pachy. Žádný nástroj nenachází 100% problémů — lidská zkušenost zůstává rozhodující.

Lze Code Smell ignorovat?

Lze, pokud se kód mění zřídka nebo bude v blízké budoucnosti zcela přepsán. Hromadění pachů se však mění v technický dluh: každá nová změna je stále obtížnější a náklady na opravu rostou exponenciálně.

Existují pachy specifické pro SwiftUI a Jetpack Compose?

Ano — deklarativní frameworky vytvořily nové pachy: gigantické @State bloky, nesprávná práce s opakovaným renderováním, nadměrná recomposition, chybějící extrakce do samostatných View. Pro SwiftUI je typickým pachem Massive View s desítkami proměnných @State.

Shrnutí

  • Code Smell — povrchový znak hlubokého problému v kódu, který není chybou, ale snižuje udržovatelnost
  • Long Method a Large Class — nejčastější pachy v mobilním vývoji, vyžadující Extract Method a Extract Class
  • Duplicate Code — duplikace logiky, která zdvojnásobuje práci při každé změně
  • Feature Envy a Switch Statements — znaky nesprávného rozdělení odpovědnosti mezi třídami
  • Specifické pachy — God Activity, Giant ViewController, Leaking Context — unikátní pro mobilní platformy
  • Refaktoring bez testů je nebezpečný: nejprve Characterisation Tests, pak malé kroky s commity
  • Statická analýza (Detekt, SwiftLint) automatizuje vyhledávání, ale nenahrazuje code review

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také