🛡️ Øvelse 22 – Opretholdelse af invarians med konstruktøren
ℹ️ Information
Formålet med denne øvelse er at give en grundlæggende introduktion til håndhævelse af invarians gennem konstruktøren.
Ved at definere regler for, hvilken data et objekt må indeholde, og sikre sig, at objekter ikke kan oprettes uden at overholde disse regler (håndhævelse af invarians), kan andre dele af softwaren altid stole på, at objektet overholder de regler, som gælder inden for domænet. Det betyder, at objekter, der eksisterer i softwaren, bevarer deres integritet.
Immutability, hvor objektets tilstand ikke kan ændres efter oprettelse, er en stærk måde at sikre invarians på, hvilket gør private fields vigtige.
Du kan læse mere om private fields og konstruktører her:
⚠️ Bemærk: Brug ikke metoder, som I skal anvende i trin 7 og 8, til validering – valider direkte i konstruktøren.
💡 Kort eksempel på invarianshåndhævelse
En invariant er en regel, som altid skal være opfyldt, for at et objekt kan betragtes som gyldigt i det domæne, det repræsenterer.
Nogle invariants er simple, eksempelvis at en nødvendig værdi ikke må være tom. Andre kommer mere direkte fra domænet, eksempelvis at et antal sider i en bog skal være større end nul.
Constructorens opgave er at sikre, at objektet ikke kan oprettes, hvis disse regler ikke er opfyldt.
Nedenfor ses et eksempel på en simpel klasse Book, hvor invarians håndhæves i constructoren:
public class Book
{
private readonly string title;
private readonly string author;
private readonly int pageCount;
public Book(string title, string author, int pageCount)
{
if (string.IsNullOrWhiteSpace(title))
{
throw new ArgumentException(
"Title cannot be null, empty or whitespace",
nameof(title));
}
if (string.IsNullOrWhiteSpace(author))
{
throw new ArgumentException(
"Author cannot be null, empty or whitespace",
nameof(author));
}
if (pageCount <= 0)
{
throw new ArgumentOutOfRangeException(
nameof(pageCount),
"A book must have at least one page");
}
this.title = title;
this.author = author;
this.pageCount = pageCount;
}
public string GetTitle()
{
return title;
}
public string GetAuthor()
{
return author;
}
public int GetPageCount()
{
return pageCount;
}
}
📝 Bemærk: Dette er et forenklet og tænkt eksempel.
I et rigtigt domæne kan der være flere regler, som skal være opfyldt, før et objekt kan betragtes som gyldigt. Hvilke invariants der er relevante, afhænger af det konkrete domæne og de krav, som gælder for systemet.
Formålet med eksemplet er derfor ikke at definere alle regler for en bog, men at vise princippet: Constructoren skal forhindre, at et objekt oprettes i en tilstand, som domænet betragter som ugyldig.
📝 Instruktioner
- Opret en ny konsolapplikation i C#.
- Opret en ny klasse ved navn
Person. - Opret to private fields i klassen:
firstnameoglastname, begge af typenstring. - Implementer klassens konstruktør, som tager imod to
string-argumenter og initialiserer de private fields. - Håndhæv invariansen i konstruktøren ved at validere, at
firstnameoglastnameikke ernullog opfylder de samme regler som i Opgave 18 – Inputvalidering i konsolapplikation. Hvis reglerne ikke er overholdt, skal der kastes en exception. - Lav en metode
GetFirstName, som returnerer værdien affirstname. - Lav en metode
GetLastName, som returnerer værdien aflastname. - Opret en instans af
Personmed gyldige værdier for for- og efternavn. - Udskriv navnene i konsollen.
🤔 Refleksionsspørgsmål
- Hvordan sikrer håndhævelse af invarians gennem konstruktøren objektets integritet?
- Hvilken rolle spiller exceptions i valideringsprocessen i konstruktøren?
- Hvorfor er det vigtigt at undgå at lade objekter eksistere i en ugyldig tilstand?
- Hvordan relaterer immutability sig til sikker softwareudvikling og undgåelse af utilsigtede fejl?
- Hvordan kan denne tilgang med invarians og konstruktører forebygge sikkerhedsproblemer?
Kobling til relevante standarder og principper
| Element i øvelsen | Relateret standard / princip | Kommentar |
|---|---|---|
| Invarianshåndhævelse | ISO/IEC 27002:2022, afsnit 8.26 (applikationssikkerhed) | Anbefaler validering og integritetstjek af input til en applikation. |
| OWASP ASVS 5.0.0, Kontrol 16.5 (Error Handling) | Krav om korrekt håndtering af fejl(undtagelser) | |
| Secure by Design (Johnsson et al.) | Fremhæver princippet om at skabe robuste domænemodeller og sikre objekters tilstand gennem konstruktion. |
🔗 Ved at sikre invarians i konstruktion og undgå at objekter kan eksistere i en ugyldig tilstand, øges pålidelighed og sikkerhed i softwaren.