Håndtering af genstande i Java er et grundlæggende aspekt af objektorienteret programmering. Det involverer at kontrollere og vedligeholde de data, der er gemt i et objekt, og hvordan disse data ændres over tid. Her er en sammenbrud af processen og nøgleovervejelser:
1. Forståelse af objekttilstand:
* stat defineret: Staten for et objekt er repræsenteret af de værdier, der er gemt i dets felter (forekomstvariabler). Disse værdier definerer objektets tilstand på et givet tidspunkt.
* statsændringer: Staten ændrer sig, når metoder kaldes på det objekt, der ændrer værdierne for dets felter.
* Objektidentitet vs. tilstand: Det er vigtigt at skelne mellem et objekts identitet (dets unikke placering i hukommelsen) og dens tilstand (de data, den har). To objekter kan have den samme tilstand, men stadig være forskellige objekter.
2. Nøgleprincipper og teknikker:
* Indkapsling (data skjul):
* princip: Begræns direkte adgang til objektets felter. Lav felter "Privat".
* Formål: Beskytter den interne tilstand mod utilsigtet ændring. Giver dig mulighed for at kontrollere, hvordan staten får adgang til og ændres.
* Implementering: Brug 'private' adgangsmodifikatorer til felter. Giv offentlige 'getter' (Accessor) og 'Setter' (mutator) metoder til at interagere med staten på en kontrolleret måde.
* Eksempel:
`` Java
offentlig klasse person {
privat strengnavn;
privat int alder;
offentlig person (strengnavn, int alder) {
dette.name =navn;
dette.age =alder;
}
public String getName () {
returnavn;
}
public void setName (strengnavn) {
dette.name =navn;
}
public int getage () {
returalder;
}
public void setage (int alder) {
if (alder> =0) {// validering
dette.age =alder;
} andet {
System.out.println ("Alder kan ikke være negativt.");
}
}
}
`` `
* kontrolleret adgang med getters og bosættere:
* getters (tilbehør): 'Offentlige' metoder, der returnerer værdien af et felt. De giver skrivebeskyttet adgang til objektets tilstand.
* Setters (mutatorer): 'Offentlige' metoder, der tillader ændring af et felts værdi. afgørende skal indstillinger omfatte validering og logik for at sikre, at staten forbliver konsekvent og gyldig.
* uforanderlighed: Hvis du vil forhindre statsændringer efter oprettelse af objekt, skal du ikke give setters. Opret objektet med alle nødvendige tilstandsoplysninger i konstruktøren.
* validering:
* Formål: Sikrer, at objektets tilstand forbliver gyldig i henhold til reglerne for din ansøgning.
* Implementering: Inkluder valideringslogik i bosættere og konstruktører. Kontroller for ugyldige værdier, såsom negative aldre, tomme strenge eller numre uden for rækkevidde.
* Eksempel: (Se metoden 'Setage' i klassen 'Person' ovenfor.)
* uforanderlighed:
* princip: Et uforanderligt objekts tilstand kan ikke ændres, når den er oprettet.
* Fordele:
* Trådsikkerhed: Imputable objekter er i sagens natur trådsikre, fordi deres tilstand ikke kan ændres samtidigt.
* enkelhed: Lettere at resonnere om og fejlsøger, fordi staten er forudsigelig.
* cache: Kan sikkert cache uden at bekymre sig om ændringer.
* Implementering:
* Lav alle felter 'Final' og 'Privat'.
* Giv ikke nogen bosættere.
* Hvis et felt er et mutabelt objekt (som en 'liste' eller 'kort'), skal du returnere en defensiv kopi i getteren for at forhindre ekstern ændring.
* Eksempel:
`` Java
offentlig endelig klasse uforanderligPoint {
Privat final Int X;
Privat final int y;
public ImmutablePoint (int x, int y) {
dette.x =x;
dette.y =y;
}
offentlig int getx () {
returner x;
}
public int gety () {
returnere y;
}
}
`` `
* observatørmønster (for afhængige objekter):
* Hvornår skal man bruge: Når tilstanden for et objekt (emnet) påvirker tilstanden af andre objekter (observatører).
* mekanisme: Emnet opretholder en liste over observatører og underretter dem, når dens stat ændrer sig. Observatører opdaterer sig derefter i overensstemmelse hermed.
* Eksempel: En aktiekurs tracker giver muligvis besked til alle registrerede investorer, når prisen på en aktie ændres.
* memento mønster (til statsbevaring):
* Hvornår skal man bruge: Når du har brug for at gemme og gendanne et objekts tilstand på forskellige tidspunkter (f.eks. For fortryd/gento funktionalitet).
* mekanisme: Objektet opretter et "memento" -objekt, der indeholder et øjebliksbillede af dets nuværende tilstand. Mementoet kan opbevares og bruges senere til at gendanne genstanden til den gemte tilstand.
* tilstandsmønster (for adfærd baseret på tilstand):
* Hvornår skal man bruge: Når et objekts adfærd ændres afhængigt af dets interne tilstand.
* mekanisme: Repræsentere hver mulig tilstand som en separat klasse. Kontekstobjektet (objektet, hvis adfærd ændrer sig), har en henvisning til et tilstandsobjekt. Når en metode kaldes på konteksten, delegerer den opkaldet til det aktuelle tilstandsobjekt.
* Eksempel: En salgsautomat kan have stater som "Idle", "Valg af produkt", "Dispensing" og "Outofstock", hver med forskellige opførsler.
* trådsikkerhed (samtidighed):
* Betydning: Hvis flere tråde kan få adgang til og ændre tilstanden for et objekt samtidigt, skal du sikre trådsikkerhed.
* Teknikker:
* Synkronisering: Brug `synkroniserede 'blokke eller metoder til at beskytte kritiske sektioner af kode, hvor staten ændres.
* låse: Brug `java.util.concurrent.locks` til mere finkornet kontrol over låsning.
* atomvariabler: Brug `java.util.concurrent.atomic` klasser (f.eks.` AtomicInteger`, `AtomicBoolean`) til atomoperationer på primitive typer.
* uforanderlige genstande: Som nævnt tidligere er uforanderlige genstande iboende trådsikre.
* Eksempel:
`` Java
public class counter {
privat int count =0;
public Synchronized void increment () {
grev ++;
}
public int getCount () {
returantal;
}
}
`` `
* serialisering:
* Formål: Konvertering af et objekts tilstand til en strøm af bytes til opbevaring eller transmission.
* Implementering: Implementere interface `java.io.serialiserbar '. JVM håndterer serialiseringsprocessen automatisk. Du kan tilpasse serialisering ved hjælp af det 'forbigående' nøgleord (for at ekskludere felter) og ved at implementere `writeObject ()` og `readObject ()` metoder.
* Overvejelser: Vær opmærksom på kompatibiliteten af serialiserede objekter, når du opdaterer klassedefinitionen.
3. Bedste praksis:
* princip om mindst privilegium: Giv kun adgang til objektets tilstand, der er absolut nødvendig.
* klar navngivning: Brug beskrivende navne på felter, getters og sættere for at gøre koden let at forstå.
* Dokument din kode: Forklar formålet med hvert felt og den forventede opførsel af getters og sættere i Javadoc -kommentarer.
* Test grundigt: Skriv enhedstest for at verificere, at objektets tilstand styres korrekt, og at valideringsregler håndhæves.
* Overvej brugssagen: Den bedste tilgang til statsledelse afhænger af de specifikke krav i din ansøgning. Vælg de teknikker, der giver den rigtige balance mellem fleksibilitet, sikkerhed og ydeevne.
* Undgå offentlige felter: Direkte udsættelse af felter som 'offentlig' er generelt dårlig praksis. Det omgår indkapsling og gør det vanskeligt at kontrollere og vedligeholde staten.
* defensiv kopiering: Når du returnerer mutable objekter fra getters, skal du overveje at returnere en * defensiv kopi * for at forhindre, at den, der ringer, ændrer objektets interne tilstand direkte. Dette er især vigtigt i uforanderlige klasser.
* Overvej at bruge poster (Java 14+): Registreringer er en kortfattet måde at oprette uforanderlige dataklasser på. De genererer automatisk konstruktører, getters, `lig ()`, `hashcode ()` og `toString ()` metoder. De er velegnet til at repræsentere dataoverførselsobjekter (DTO'er) eller enkle datastrukturer.
Kortfattet:
Håndtering af objekttilstand i Java er et kritisk aspekt af objektorienteret design. Ved at overholde principper som indkapsling, uforanderlighed, validering og trådsikkerhed kan du oprette robuste, vedligeholdelige og pålidelige applikationer. De specifikke teknikker, du vælger, afhænger af kompleksiteten af dine objekter og kravene i din applikation.