...
Ta som eksempel representasjon av fornavn og etternavn for en person. Dette kan gjøres med ett String-attributt, med fornavn og etternavn skilt med mellomrom, eller to separate String-attributter, ett for fornavn og ett for etternavn. Uansett hvilken konkret representasjon som velges, så handler det logisk sett om å håndtere to (uavhengige) verdier og det er ingen grunn til at detaljer om hvordan representasjonen gjøres skal være kjent for andre klasser. Istedet defineres Klassen definerer operasjoner for både å lese og endre disse to verdiene og implementasjonene tar som lar seg av detaljeneimplementere av begge løsningsalternativene. Hvilket alternativ man faktisk velger er en detalj som andre klasser ikke behøver bry seg om. Dette er illustrert i følgende figur:
PlantUML Macro | ||
---|---|---|
| ||
class Person { String getGivenName() void setGivenName(String givenName) String getFamilyName() void setFamilyName(String familyName) } note top: OperationsKun onlyoperasjoner class "Person" as Person1 { String givenName String familyName String getGivenName() void setGivenName(String givenName) String getFamilyName() void setFamilyName(String familyName) } note top: Impl. alternativeAlternativ 1, separate attributesattributter for eachhver valueverdi class "Person" as Person2 { String fullName String getGivenName() void setGivenName(String givenName) String getFamilyName() void setFamilyName(String familyName) } note top: Impl.Alternativ alternative 2, oneett attributt attributesom combiningkombinerer bothbegge valuesverdiene |
For det andre er det viktig at detaljer om hvordan data representeres med attributter kalle metoder Først og fremst gjøres dette ved å 1) definere regler for gyldighet for de ulike typene objekter og 2) sikre at alle metoder kodes i henhold til disse reglene. Dette er nøkkelen til programmeringsmetoden kalt innkapsling, som sammen med såkalte synlighetsmodifikatorer utgjør et vern mot ugyldig tilstander i programmer.
...
Innkapslingen av fornavn- og etternavn-verdiene er representert ved den første klassen, mens de to andre klassene er alternative implementasjoner som støtter denne innkapslingen. Andre klasser bruker bare operasjonene og trenger dermed ikke bry seg om eller gjøre seg avhengig av hvilket alternativ som er valgt. En kan dermed bytte mellom implementasjonsalternativ 1 og 2 uten at andre klasser blir påvirket.
Synlighetsmodifikatorer
Innkapsling består altså av å definere et sett operasjoner for sikker (og indirekte) tilgang til data, istedenfor å gi direkte tilgang til attributter og dermed lekke detaljer om implementasjonsteknikken til andre klasser. For å gjøre innkapslingen tydelig kan en angi i diagrammer den såkalte synligheten til navn, dvs. hvilke som skal være offentlig (kjent) og hvilke som skal være private. De offentlig skal være mulige å bruke (referere til) utenfor klassen og de private umulige. Dette illustreres med henholdsvis grønne og røde punkter eller + og - foran navnene, som vist i figuren under.
PlantUML Macro | ||
---|---|---|
| ||
class "Person" as Person1 {
-String givenName
-String familyName
+String getGivenName()
+void setGivenName(String givenName)
+String getFamilyName()
+void setFamilyName(String familyName)
}
note top: Synlighet angitt med grønn og rød farge
class "Person" as Person2 {
- String givenName
- String familyName
+ String getGivenName()
+ void setGivenName(String givenName)
+ String getFamilyName()
+ void setFamilyName(String familyName)
}
note top: Synlighet angitt med + og - |
Tilsvarende tilbyr mange objektorienterte språk mekanismer såkalte synlighetsmodifikatorer for å deklarere hvilke navn som skal være offentlige og private. Alternativ 1 over vil kodes som følger:
Code Block | ||||
---|---|---|---|---|
| ||||
class Person {
private String givenName;
private String familyName;
public String getGivenName() { ... }
public void setGivenName(String givenName) { ... }
public String getFamilyName() { ... }
public void setFamilyName(String familyName) { ... }
}
|