Modellering med ADT'er
Gør ulovlige tilstande urepræsenterbare
Modellering med ADT'er er en gratis Scala til backendudvikling og funktionel programmering-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Scala til backendudvikling og funktionel programmering, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Scala til backendudvikling og funktionel programmering-kurset indeholder 4 lektioner i alt.
Algebraiske datatyper
Algebraiske datatyper (ADT'er) er grundlaget for funktionel domænemodellering. De kombinerer produkttyper (OG) og sumtyper (ELLER) for at beskrive data præcist.
- Produkt: en post med flere felter.
- Sum: et valg mellem flere varianter.
case class Point(x: Int, y: Int) // product type
object Main:
def main(args: Array[String]): Unit =
println(Point(1, 2))Produkttyper
En produkttype samler værdier. I Scala er en case class et produkt: en instans indeholder alle sine felter på samme tid.
case class User(name: String, age: Int)
object Main:
def main(args: Array[String]): Unit =
val u = User("Ada", 36)
println(u.name)
println(u.age)Sumtyper
En sumtype er en værdi, der præcis er én af flere varianter. Scala 3-enums udtrykker dette direkte.
enum PaymentMethod:
case Cash
case Card(number: String)
case Crypto(wallet: String)
object Main:
def main(args: Array[String]): Unit =
val p: PaymentMethod = PaymentMethod.Card("1234")
println(p)Gør ugyldige tilstande umulige at repræsentere
Det centrale princip er at designe typer, så ugyldige data ikke engang kan konstrueres. Hvis typesystemet forbyder en ugyldig tilstand, behøver du aldrig kontrollere den ved kørsel.
enum Connection:
case Disconnected
case Connected(sessionId: String)
object Main:
def main(args: Array[String]): Unit =
// No way to have a sessionId while Disconnected
val c: Connection = Connection.Connected("abc")
println(c)Dårligt design kontra godt design
En flad post med nullable felter inviterer til ugyldige tilstande. Når hver situation modelleres som en variant, fjernes de.
- Dårligt:
case class Conn(connected: Boolean, sessionId: String)tillader connected=false med et sessionId. - Godt: En sumtype knytter feltet til den rigtige tilstand.
enum Door:
case Open
case Closed
case Locked(key: String)
object Main:
def main(args: Array[String]): Unit =
val d: Door = Door.Locked("k1")
println(d)Kombination af produkter og summer
Virkelige modeller indlejrer produkter i summer og omvendt. Hver variant kan indeholde sit eget produkt af felter.
case class Address(city: String, zip: String)
enum Contact:
case Email(value: String)
case Postal(address: Address)
object Main:
def main(args: Array[String]): Unit =
val c: Contact = Contact.Postal(Address("Paris", "75001"))
println(c)Pattern matching på ADT'er
Du bruger pattern matching til at behandle ADT'er. Fordi typen er lukket, advarer compileren, hvis du mangler en variant.
enum Shape:
case Circle(r: Double)
case Rect(w: Double, h: Double)
object Main:
def area(s: Shape): Double = s match
case Shape.Circle(r) => 3.14159 * r * r
case Shape.Rect(w, h) => w * h
def main(args: Array[String]): Unit =
println(area(Shape.Rect(2, 3)))Rekursive ADT'er
ADT'er kan referere til sig selv, så træer, lister og udtryk kan modelleres naturligt.
enum Expr:
case Num(value: Int)
case Add(left: Expr, right: Expr)
object Main:
def eval(e: Expr): Int = e match
case Expr.Num(v) => v
case Expr.Add(l, r) => eval(l) + eval(r)
def main(args: Array[String]): Unit =
val e = Expr.Add(Expr.Num(2), Expr.Num(3))
println(eval(e))Valgfrihed med Option
Brug Option i stedet for null til at modellere et felt, der måske ikke findes. Typen gør fraværet eksplicit og tvinger dig til at håndtere det.
case class Profile(name: String, nickname: Option[String])
object Main:
def main(args: Array[String]): Unit =
val p = Profile("Grace", None)
println(p.nickname.getOrElse("(none)"))Præcis modellering af størrelser
Erstat primitive obsession. I stedet for rå Ints og Strings skal du indpakke meningsfulde størrelser, så typerne dokumenterer hensigten og forhindrer forvekslinger.
case class Quantity(value: Int)
case class Price(cents: Long)
case class LineItem(qty: Quantity, price: Price)
object Main:
def main(args: Array[String]): Unit =
val item = LineItem(Quantity(3), Price(500))
println(item)Hvorfor ADT'er er vigtige
ADT'er giver korrekthed og tydelighed.
- Ugyldige tilstande kan ikke oprettes.
- Udtømmende matching opdager manglende tilfælde ved kompilering.
- Dataenes struktur dokumenterer domænet.
enum OrderStatus:
case Pending
case Shipped(tracking: String)
case Delivered(at: Long)
object Main:
def main(args: Array[String]): Unit =
val s: OrderStatus = OrderStatus.Shipped("TRK1")
println(s)Hurtigt tjek
Test din forståelse af modellering baseret på ADT'er.
Opsummering
Du har lært domænemodellering med ADT'er.
- Produkttyper (
case class) kombinerer felter med OG. - Sumtyper (
enum) tilbyder et valg med ELLER. - Indlejr dem for at modellere rige domæner og rekursive strukturer.
- Brug
Optioni stedet for null. - Design, så ugyldige tilstande ikke kan repræsenteres.
enum Event:
case Created(id: Int)
case Deleted(id: Int, reason: String)
object Main:
def describe(e: Event): String = e match
case Event.Created(id) => s"created $id"
case Event.Deleted(id, reason) => s"deleted $id: $reason"
def main(args: Array[String]): Unit =
println(describe(Event.Deleted(1, "spam")))Lær Scala med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 39
- Lektioner
- 143
Ofte stillede spørgsmål
Er lektionen “Modellering med ADT'er” gratis?
Ja — hele teksten til “Modellering med ADT'er” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Scala til backendudvikling og funktionel programmering-kurset, skal du opgradere til CoddyKit PRO. Scala til backendudvikling og funktionel programmering-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Modellering med ADT'er”?
Gør ulovlige tilstande urepræsenterbare Du øver dig i Scala til backendudvikling og funktionel programmering med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Scala til backendudvikling og funktionel programmering?
Der kræves ingen tidligere erfaring. Scala til backendudvikling og funktionel programmering på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.
Hvor lang tid tager lektionen “Modellering med ADT'er”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Scala til backendudvikling og funktionel programmering-lektion?
Ja. Alle Scala til backendudvikling og funktionel programmering-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Modellering med ADT'er
- Smarte konstruktører
- Newtypes
- Sammensætning af domæner