Intelligente Konstruktoren
Validierte Konstruktion
Intelligente Konstruktoren ist eine kostenlose Scala for Backend Engineering & Functional Programming-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Scala for Backend Engineering & Functional Programming-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Scala for Backend Engineering & Functional Programming-Kurs umfasst insgesamt 4 Lektionen.
Validierte Konstruktion
Ein Smart Constructor ist eine Factory, die Eingaben validiert, bevor sie einen Wert erzeugt. Er garantiert, dass jede Instanz, die Sie besitzen, die Invarianten des Typs erfüllt.
- Der rohe Konstruktor ist verborgen.
- Nur die validierte Erstellung ist öffentlich.
class Age private (val value: Int)
object Age:
def of(v: Int): Option[Age] =
if v >= 0 then Some(new Age(v)) else None
object Main:
def main(args: Array[String]): Unit =
println(Age.of(30).map(_.value))Privater Konstruktor
Wenn Sie den primären Konstruktor als private markieren, können Aufrufer die Validierung nicht umgehen. Das Companion-Objekt wird zum einzigen Einstiegspunkt.
class Percentage private (val value: Int)
object Percentage:
def of(v: Int): Option[Percentage] =
if v >= 0 && v <= 100 then Some(new Percentage(v)) else None
object Main:
def main(args: Array[String]): Unit =
println(Percentage.of(50).map(_.value))
println(Percentage.of(150))Option zurückgeben
Die Rückgabe von Option signalisiert, dass die Konstruktion fehlschlagen kann. Der Aufrufer muss None behandeln, sodass ungültige Daten niemals unbemerkt weitergereicht werden.
class NonEmpty private (val value: String)
object NonEmpty:
def of(s: String): Option[NonEmpty] =
if s.nonEmpty then Some(new NonEmpty(s)) else None
object Main:
def main(args: Array[String]): Unit =
println(NonEmpty.of("").map(_.value))
println(NonEmpty.of("hi").map(_.value))Either für Fehlerdetails zurückgeben
Wenn Sie erklären möchten, warum die Validierung fehlgeschlagen ist, geben Sie Either[Error, T] zurück. Das Left enthält eine beschreibende Nachricht.
class Username private (val value: String)
object Username:
def of(s: String): Either[String, Username] =
if s.isEmpty then Left("empty")
else if s.length > 10 then Left("too long")
else Right(new Username(s))
object Main:
def main(args: Array[String]): Unit =
println(Username.of(""))
println(Username.of("ada").map(_.value))Smart Constructors mit case class
Auch eine case class mit privatem Konstruktor funktioniert. Beachten Sie, dass auch das generierte apply und copy kontrolliert werden müssen. Definieren Sie daher eine eigene Factory und halten Sie den Konstruktor privat.
case class Email private (value: String)
object Email:
def of(s: String): Option[Email] =
if s.contains("@") then Some(Email(s)) else None
object Main:
def main(args: Array[String]): Unit =
println(Email.of("a@b.com"))
println(Email.of("bad"))Validierte Werte verketten
Da Smart Constructors Option oder Either zurückgeben, können Sie sie mit for-Comprehensions kombinieren, um größere validierte Objekte zu erstellen.
case class Name private (value: String)
object Name:
def of(s: String): Option[Name] =
if s.nonEmpty then Some(Name(s)) else None
case class Person(name: Name, age: Int)
object Main:
def make(n: String): Option[Person] =
for nm <- Name.of(n) yield Person(nm, 20)
def main(args: Array[String]): Unit =
println(Main.make("Bob"))Eingaben normalisieren
Ein Smart Constructor kann Daten auch normalisieren, etwa durch das Entfernen von Leerzeichen oder die Umwandlung in Kleinbuchstaben, sodass alle Instanzen eine kanonische Form besitzen.
case class Tag private (value: String)
object Tag:
def of(s: String): Option[Tag] =
val clean = s.trim.toLowerCase
if clean.nonEmpty then Some(Tag(clean)) else None
object Main:
def main(args: Array[String]): Unit =
println(Tag.of(" Scala "))Invarianten gelten dauerhaft
Sobald ein Wert den Smart Constructor passiert hat, ist seine Invariante für seine gesamte Lebensdauer garantiert. Nachgelagerter Code kann dem Wert vertrauen, ohne ihn erneut zu prüfen.
case class PositiveInt private (value: Int)
object PositiveInt:
def of(n: Int): Option[PositiveInt] =
if n > 0 then Some(PositiveInt(n)) else None
object Main:
def doubleIt(p: PositiveInt): Int = p.value * 2 // always positive
def main(args: Array[String]): Unit =
PositiveInt.of(5).foreach(p => println(Main.doubleIt(p)))Mit opaken Typen kombinieren
Für validierte Werte ohne Laufzeitkosten kombinieren Sie einen Smart Constructor mit einem opaken Typ. Es wird kein Wrapper-Objekt erzeugt, dennoch steuert die Validierung die Konstruktion.
object Domain:
opaque type Score = Int
def of(n: Int): Option[Score] =
if n >= 0 && n <= 100 then Some(n) else None
extension (s: Score) def value: Int = s
object Main:
def main(args: Array[String]): Unit =
println(Domain.of(88).map(_.value))Mehrere Validierungsregeln
Wenden Sie mehrere Prüfungen nacheinander an. Die erste fehlschlagende Regel beendet die Verarbeitung vorzeitig und gibt einen eindeutigen Fehler zurück.
object Password:
def of(s: String): Either[String, String] =
if s.length < 8 then Left("too short")
else if !s.exists(_.isDigit) then Left("need a digit")
else Right(s)
object Main:
def main(args: Array[String]): Unit =
println(Password.of("abc"))
println(Password.of("abcdef12"))Wann Sie Smart Constructors verwenden sollten
Verwenden Sie sie immer dann, wenn ein Typ Invarianten besitzt, die durch eine rohe Konstruktion verletzt werden könnten.
- Begrenzte Zahlen, nicht leere Strings, formatierte IDs.
- Geben Sie
Optionfür einfache Ja/Nein-Ergebnisse undEitherfür Begründungen zurück. - Halten Sie den rohen Konstruktor privat.
case class Port private (value: Int)
object Port:
def of(n: Int): Option[Port] =
if n >= 1 && n <= 65535 then Some(Port(n)) else None
object Main:
def main(args: Array[String]): Unit =
println(Port.of(8080))
println(Port.of(70000))Kurzer Check
Testen Sie Ihr Verständnis von Smart Constructors.
Zusammenfassung
Sie haben Smart Constructors kennengelernt.
- Validieren Sie Eingaben in einer Companion-Factory.
- Machen Sie den rohen Konstruktor privat.
- Geben Sie
OptionoderEitherzurück, um die Behandlung von Fehlern zu erzwingen. - Normalisieren Sie Eingaben optional in eine kanonische Form.
- Die Invarianten gelten dann für die gesamte Lebensdauer des Werts.
case class Even private (value: Int)
object Even:
def of(n: Int): Option[Even] =
if n % 2 == 0 then Some(Even(n)) else None
object Main:
def main(args: Array[String]): Unit =
println(Even.of(4))
println(Even.of(5))Häufig gestellte Fragen
Ist die Lektion „Intelligente Konstruktoren“ kostenlos?
Ja — der vollständige Text von „Intelligente Konstruktoren“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Scala for Backend Engineering & Functional Programming-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Scala for Backend Engineering & Functional Programming-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Intelligente Konstruktoren“?
Validierte Konstruktion Du übst Scala for Backend Engineering & Functional Programming mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Scala for Backend Engineering & Functional Programming zu starten?
Keine Vorkenntnisse erforderlich. Scala for Backend Engineering & Functional Programming auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „Intelligente Konstruktoren“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Scala for Backend Engineering & Functional Programming-Lektion Code schreiben und ausführen?
Ja. Jede Scala for Backend Engineering & Functional Programming-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Modellierung mit ADTs
- Intelligente Konstruktoren
- Newtypes
- Domänen kombinieren