Dette kapittelet viser hvordan du beveger deg fra én fil i startfasen til en profesjonell modulstruktur når koden blir større. Målet er ikke bare å splitte kode i flere filer, men å gjøre prosjektet lettere å forstå, enklere å vedlikeholde og tryggere å videreutvikle.
God modulstruktur handler derfor først og fremst om ansvar. Når hver fil og hver mappe har en tydelig rolle, blir det lettere å finne feil, lese gjennom endringer og vite hvor ny funksjonalitet faktisk hører hjemme.
Start enkelt. Del opp når én fil gjør mer enn ett av disse:
Det avgjørende er ikke hvor mange linjer en fil har, men hvor mange forskjellige typer ansvar den bærer samtidig. En kort fil kan fortsatt være uoversiktlig hvis den blander routing, validering, domenelogikk og responsbygging i samme flyt.
Bruk korte, tydelige alias. Det gjør koden lettere å lese.
bruk std.web som web
bruk std.liste som liste
bruk std.io som io
Klare alias gjør det lettere å skille mellom hva som kommer fra standardbiblioteket og hva som er egen domenelogikk. Det blir ekstra nyttig når prosjektet etter hvert får flere egne moduler som ligner på hverandre i navn eller ansvar.
prosjekt/
website/
index.no
services/
pricing.no
contacts.no
seo.no
data/
rates.no
tests/
services_pricing.no
web_api.no
std/
website.toml
Regel: én mappe per ansvarstype gir forutsigbarhet når du vokser.
Poenget med et slikt oppsett er ikke at alle prosjekter må se like ut. Poenget er at leseren raskt forstår hvor web-laget slutter, hvor domenelogikken ligger og hvor testene er samlet. Struktur er i stor grad et kommunikasjonsverktøy for utviklere.
Når disse grensene er tydelige, blir det lettere å endre én del av systemet uten at alt annet må leses på nytt. Det er akkurat dette som gjør større kodebaser håndterbare over tid.
servicesdataindex.no kun holde ruteoppsett og bindingDet er ofte lurt å gjøre dette gradvis. Hvis du prøver å designe hele sluttilstanden på én gang, ender du fort med for mange mapper og for lite faktisk verdi. En bedre strategi er å dele opp når et konkret ansvar begynner å bli tungt å ha liggende sammen med resten.
// services/pricing.no
funksjon beregn_total(pris: heltall, mva: heltall) -> heltall {
returner pris + (pris * mva / 100)
}
// website/index.no
bruk services.pricing som pricing
funksjon pris_handler() -> tekst {
la pris: heltall = pricing.beregn_total(10000, 25)
returner "" + tekst_fra_heltall(pris) + "
"
}
Eksemplet viser et viktig prinsipp: web-laget ber om en verdi, men trenger ikke selv å eie beregningsregelen. Når domenelogikken flyttes ut, blir den enklere å teste, enklere å gjenbruke og enklere å diskutere som egen del av systemet.
funksjon init() -> heltall {
la ok: bool = sann
hvis ok da {
skriv("Klare moduler")
}
returner 0
}
Oppstartskoden bør helst være så enkel som mulig. Jo mindre domenelogikk som ligger skjult i oppstartsfasen, desto lettere er det å forstå hva tjenesten faktisk gjør når den starter, og hvor feil bør letes hvis noe går galt.
Én testfil pr. domene gjør feilsøking enklere.
test "pris-regel" {
la pris: heltall = pricing.beregn_total(100, 25)
assert_eq(pris, 125)
}
Dette er en god vane fordi testene da følger den samme ansvarsdelingen som produksjonskoden. Hvis alt ligger i én stor testfil, mister du fort oversikten over hvilke deler av prosjektet som faktisk er dekket godt og hvilke som bare delvis er verifisert.
En annen vanlig feil er å la navnene bli for tekniske eller for interne. Hvis modulnavn ikke tydelig sier hva de eier, hjelper ikke oppdelingen så mye. Gode navn og tydelige grenser henger tett sammen.
Flytt én funksjon fra `index.no` til `services/pricing.no` og lag en tilsvarende test i `tests/services_pricing.no`.
Når du er klar, gå til Testing-dokumentasjonen for kvalitetssikring av modulene. Det er ofte først når modulstruktur og teststruktur begynner å støtte hverandre at et prosjek