Android Academy · Oppitunti

Miksi modularisoida

Koontinopeus, omistajuus ja uudelleenkäyttö.

Oppitunti 1/413 vaihetta

Miksi modularisoida on ilmainen Android Academy-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Android Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Android Academy-kurssilla on yhteensä 4 oppituntia.

Monoliitin ongelma

Android-sovelluksen kasvaessa kaikki sen koodi sijaitsee usein yhdessä app-moduulissa. Tätä kutsutaan monoliitiksi. Aluksi ratkaisu on kätevä, mutta ajan mittaan siitä tulee hankala: jokainen muutos koskee samaa moduulia, koontiversiot hidastuvat ja tiimin jäsenet ovat jatkuvasti toistensa tiellä.

Modularisointi tarkoittaa tämän yhden suuren moduulin jakamista useiksi pienemmiksi ja tarkoitukseltaan rajatuiksi Gradle-moduuleiksi. Tässä oppitunnissa opitte, miksi tiimit tekevät näin ja mitä konkreettisia hyötyjä siitä on.

Mikä moduuli oikeastaan on

Gradlessa moduuli on itsenäisesti koottava koodiyksikkö, jolla on oma build.gradle.kts-tiedosto. Sovelluksessanne on jo vähintään yksi moduuli: :app-moduuli. Ilmoitatte jokaisen moduulin tiedostossa settings.gradle.kts.

Moduulin lisääminen on yhtä helppoa kuin sen sisällyttäminen. Jokainen moduuli tuottaa oman koontituloksensa ja voi riippua muista moduuleista.

// settings.gradle.kts
include(":app")
include(":core:designsystem")
include(":core:data")
include(":feature:home")
include(":feature:profile")

Hyöty 1: nopeammat koonnit

Suurin käytännön hyöty on koontinopeus. Gradle voi koota moduuleja rinnakkain ja ennen kaikkea välimuistittaa ja ohittaa moduulit, joiden syötteet eivät muuttuneet.

Jos muokkaatte vain moduulia :feature:profile, Gradle käyttää uudelleen kaikkien muiden moduulien valmiita koontituloksia. Monoliitissa mikä tahansa muutos voi pakottaa koko sovelluksen uudelleen kääntämiseen.

  • Rinnakkainen suoritus moduulien välillä
  • Inkrementaaliset koonnit: kootaan uudelleen vain muuttuneet osat
  • Paremmat osumat etä- ja koontivälimuistissa
// gradle.properties
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=true

Hyöty 2: selkeät rajat

Moduulit pakottavat rajat. Yhden moduulin koodi näkee vain sen, minkä toinen moduuli tarkoituksella tarjoaa. Tämä estää sotkuisen spagettikoodin, jossa jokainen luokka käsiksi jokaiseen muuhun luokkaan.

Näkyvyyttä hallitaan api- ja implementation-Gradle-määrityksillä. implementation pitää riippuvuuden moduulin sisäisenä, joten moduulin käyttäjät eivät voi vahingossa käyttää sitä.

// feature/profile/build.gradle.kts
dependencies {
    // Exposed to whoever depends on :feature:profile
    api(project(":core:model"))

    // Private: hidden from consumers of this module
    implementation(project(":core:network"))
}

Hyöty 3: uudelleenkäyttö

Kun logiikka sijaitsee tarkoitukseltaan rajatussa moduulissa, voitte käyttää sitä uudelleen missä tahansa. :core:designsystem-moduulia, joka sisältää teeman, värit ja uudelleenkäytettävät composable-funktiot, voidaan käyttää kaikissa ominaisuuksissa.

Sama ajatus toimii myös useiden sovellusten kanssa: yritys voi jakaa :core:network-moduulin useiden tuotteiden kesken sen sijaan, että koodia kopioitaisiin.

// Any feature can pull in shared building blocks
// feature/home/build.gradle.kts
dependencies {
    implementation(project(":core:designsystem"))
    implementation(project(":core:data"))
}

Hyöty 4: tiimien omistajuus

Moduulit vastaavat luontevasti tiimien omistajuutta. Maksutiimi omistaa moduulin :feature:payments ja profiilitiimi moduulin :feature:profile. Tiimit voivat työskennellä rinnakkain, ja yhdistämisristiriitoja syntyy vähemmän, koska niiden koodi sijaitsee eri kansioissa ja koontitiedostoissa.

CODEOWNERS-tiedoston kaltaiset työkalut voivat pyytää katselmointeja automaattisesti oikealta tiimiltä moduulipolun perusteella.

# .github/CODEOWNERS
/feature/payments/   @org/payments-team
/feature/profile/    @org/profile-team
/core/designsystem/  @org/platform-team

Hyöty 5: näkyvyyteen perustuva kapselointi

Moduulin sisällä Kotlinin internal-määreestä tulee tehokas. internal-luokka tai -funktio näkyy vain omassa moduulissaan. Muut moduulit eivät voi kirjaimellisesti viitata siihen.

Näin voitte tarjota pienen julkisen rajapinnan ja piilottaa toteutuksen yksityiskohdat, mitä ei voi pakottaa yhdessä suuressa moduulissa.

// In :core:data
// Public API other modules may use
fun interface UserRepository {
    suspend fun loadUser(id: String): User
}

// Hidden from other modules
internal class DefaultUserRepository(
    private val api: UserApi
) : UserRepository {
    override suspend fun loadUser(id: String) = api.fetch(id).toUser()
}

Hinta: jonkin verran lisätyötä

Modularisointi ei ole ilmaista. Jokaiselle moduulille on ylläpidettävä omaa build.gradle.kts-tiedostoa, ja teidän on päätettävä, mikä moduuli omistaa kunkin koodiosan. Pienen sovelluksen liiallinen modularisointi lisää työtä ilman hyötyä.

Nyrkkisääntö on tämä: modularisoikaa, kun koontiajat hidastavat työtä, tiimit törmäävät toisiinsa tai teillä on selkeitä uudelleenkäytettäviä kerroksia. Viikonloppuharrasteen sovellus tarvitsee harvoin 30 moduulia.

Tyypillinen moduulirakenne

Yleinen ja skaalautuva rakenne jakaa moduulit app-, feature- ja core-kerroksiin. :app-moduuli yhdistää kaiken; feature-moduulit sisältävät käyttäjälle näkyvät näkymät, ja core-moduulit yhteisen infrastruktuurin.

// Conceptual project tree
// app/                  <- single entry point, wires features
// feature/
//   home/
//   profile/
//   settings/
// core/
//   designsystem/       <- theme + reusable composables
//   data/               <- repositories
//   network/            <- Retrofit/Ktor
//   model/              <- shared data classes

Convention-pluginit pitävät kokonaisuuden hallittavana

Kun moduuleja on paljon, saman Gradle-asetuksen kopioiminen kaikkialle on ansa. Tiimit erottavat yhteisen määrityksen convention-plugineiksi (moduulissa build-logic). Tällöin jokainen varsinainen moduuli ottaa käyttöön yhden pluginin sen sijaan, että kymmeniä rivejä toistettaisiin.

Näette tämän mallin suurissa avoimen lähdekoodin sovelluksissa, kuten Now in Androidissa. Tässä vaiheessa riittää, että tiedätte tavoitteen: koontitiedostot pidetään pieninä ja yhdenmukaisina.

// feature/home/build.gradle.kts
plugins {
    // One convention plugin sets up Android + Compose + Kotlin
    id("myapp.android.feature")
}

android { namespace = "com.myapp.feature.home" }

Ajattelutapa: ajatelkaa kerroksittain

Hyödyllisin yksittäinen ajattelumalli on tämä: riippuvuuksien pitäisi kulkea alaspäin. Feature-moduulit riippuvat core-moduuleista, mutta core-moduulit eivät riipu feature-moduuleista. :app-moduuli sijaitsee aivan ylimpänä ja riippuu kaikesta, mitä se tarvitsee sovelluksen kokoamiseen.

Kun pidätte suunnan johdonmukaisena, moduuligraafi pysyy selkeänä ja vältätte syklit, joita käsittelette myöhemmällä oppitunnilla.

// Allowed:  app -> feature -> core
// Forbidden: core -> feature (upward) or feature -> feature (sideways)
// app/build.gradle.kts
dependencies {
    implementation(project(":feature:home"))
    implementation(project(":feature:profile"))
}

Pikakysymys

Mikä seuraavista on konkreettisin jokapäiväinen hyöty, jonka tiimit saavat kasvavan Android-sovelluksen modularisoinnista?

Kertaus: miksi modularisoida

Opitte, miksi tiimit jakavat monoliitin moduuleiksi:

  • Nopeammat koonnit rinnakkaisen suorituksen ja inkrementaalisen välimuistin avulla
  • Selkeät rajat käyttämällä määrityksiä api/implementation ja määrettä internal
  • core-kerrosten, kuten design systemin ja verkkokerroksen, uudelleenkäyttö
  • Tiimien omistajuus ja vähemmän yhdistämisristiriitoja

Näitte myös kustannukset (ylimääräiset koontitiedostot) sekä kultaisen säännön: riippuvuudet kulkevat alaspäin, app -> feature -> core. Seuraavaksi piirrätte feature- ja core-moduulien väliset todelliset rajat.

Aloita maksutta

Opi Kotlin tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
36
Oppitunnit
152

Usein kysytyt kysymykset

Onko oppitunti ”Miksi modularisoida” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Android Academy-oppimispolun 3 oppituntia, myös oppitunnin “Miksi modularisoida”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Android Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Miksi modularisoida”?

Koontinopeus, omistajuus ja uudelleenkäyttö. Harjoittelet Android Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Android Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Android Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.

Kuinka kauan ”Miksi modularisoida”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Android Academy-oppitunnilla?

Kyllä. Jokainen Android Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Miksi modularisoida
  2. Ominaisuus- ja ydinmoduulit
  3. Moduuliriippuvuuksien hallinta
  4. Navigointi moduulien välillä
← Takaisin: Android Academy