3.1 Singleton

Singleton er et generisk designmønster som garanterer at en enkelt-tråds applikasjon vil ha en enkelt forekomst av en eller annen klasse, og gir et globalt tilgangspunkt til denne forekomsten.

Singleton

Svært ofte liker nybegynnere programmerere å sette sammen verktøymetoder i en statisk klasse - en klasse som bare inneholder statiske metoder. Denne tilnærmingen har en rekke ulemper - for eksempel kan du ikke sende en referanse til et objekt av en slik klasse, slike metoder er vanskelige å teste, og lignende.

Som et alternativ ble det foreslått en singleton-klasseløsning: en klasse som bare kan ha ett objekt. Når du forsøker å opprette dette objektet, opprettes det bare hvis det ikke allerede eksisterer, ellers returneres en referanse til en allerede eksisterende forekomst.

Det er viktig at det er mulig å bruke en forekomst av klassen, siden i mange tilfeller blir bredere funksjonalitet tilgjengelig. For eksempel kan denne klassen implementere noen grensesnitt og objektet kan overføres til andre metoder som en implementering av grensesnittet. Hva kan ikke gjøres med et sett med statiske metoder.

Fordeler:

  • Metoder er bundet til et objekt, ikke en statisk klasse - du kan sende et objekt ved referanse.
  • Objektmetoder er mye lettere å teste og håne.
  • Et objekt opprettes bare når det er nødvendig: initialisering av lat objekt.
  • Akselerere den første lanseringen av programmet hvis det er mange singler som ikke er nødvendig for lanseringen.
  • Alene kan gjøres videre til en mal-strategi eller flere slike objekter.

Minuser:

  • Det blir vanskeligere å kontrollere mellomtrådsløp og forsinkelser.
  • Det er vanskelig å skrive en flertråds "loner" "fra hodet": tilgang til en langvarig singleton bør ideelt sett ikke åpne en mutex. Bedre utprøvde løsninger.
  • En konflikt mellom to tråder over en uferdig enkelt tråd vil resultere i en forsinkelse.
  • Hvis objektet blir opprettet over lang tid, kan forsinkelsen forstyrre brukeren eller forstyrre sanntid. I dette tilfellet er det bedre å overføre opprettelsen til scenen for programinitialisering.
  • Spesielle funksjoner kreves for enhetstesting - for eksempel for å sette biblioteket i "ikke-ensom" modus og fullstendig isolere tester fra hverandre.
  • En spesiell taktikk for å teste det ferdige programmet er nødvendig, fordi selv konseptet "den enkleste oppstartbarheten" forsvinner, fordi oppstartbarheten avhenger av konfigurasjonen.

3.2 Fabrikk [metode]

En fabrikkmetode er et generisk designmønster som gir underklasser (classes-inheritors) et grensesnitt for å lage forekomster av en bestemt klasse. På opprettelsestidspunktet kan etterkommere bestemme hvilken klasse som skal opprettes.

Med andre ord, denne malen delegerer opprettelsen av objekter til etterkommerne av den overordnede klassen. Dette lar deg bruke ikke konkrete klasser i programkoden, men å manipulere abstrakte objekter på et høyere nivå.

Fabrikkmetode

Dette mønsteret definerer et grensesnitt for å lage et objekt, men lar det være opp til underklasser å bestemme hvilken klasse objektet skal baseres på. En fabrikkmetode lar en klasse delegere opprettelsen av underklasser. Brukes når:

  • klassen vet ikke på forhånd hvilke objekter av hvilke underklasser den må lage.
  • en klasse er utformet slik at objektene den lager spesifiseres av underklasser.
  • klassen delegerer sitt ansvar til en av flere hjelpeunderklasser, og det er planlagt å bestemme hvilken klasse som overtar disse ansvarsoppgavene.

3.3 Abstrakt fabrikk

En abstrakt fabrikk er et generisk designmønster som gir et grensesnitt for å lage familier av relaterte eller gjensidig avhengige objekter uten å spesifisere deres konkrete klasser.

Mønsteret implementeres ved å lage en abstrakt klasse Factory, som er et grensesnitt for å lage systemkomponenter (for eksempel for et vindusgrensesnitt kan det lage vinduer og knapper). Deretter skrives klasser som implementerer dette grensesnittet.

Abstrakt fabrikk

Den brukes i tilfeller der programmet må være uavhengig av prosessen og typene av nye objekter som opprettes. Når det er nødvendig å opprette familier eller grupper av relaterte objekter, unntatt muligheten for samtidig bruk av objekter fra forskjellige sett av disse i samme kontekst.

Styrker:

  • isolerer spesifikke klasser;
  • forenkler utskifting av produktfamilier;
  • garanterer produktkompatibilitet.

La oss si at programmet ditt fungerer med filsystemet. For å jobbe i Linux trenger du LinuxFile, LinuxDirectory, LinuxFileSystem-objekter. Og for å jobbe i Windwos trenger du WindowsFile, WindowsDirectory, WindowsFileSystem-klassene.

Path-klassen, som er opprettet via Path.of(), er nettopp et slikt tilfelle. Path er egentlig ikke en klasse, men et grensesnitt, og den har WindowsPath og LinuxPath implementeringer. Og hva slags objekt som skal opprettes, er skjult fra koden din og vil avgjøres under kjøring.

3.4 Prototype

Prototype er et generativt designmønster.

Dette mønsteret definerer hvilke typer objekter som er opprettet ved hjelp av en prototypeforekomst og oppretter nye objekter ved å kopiere denne prototypen. Den lar deg komme vekk fra implementeringen og følge prinsippet om "programmering gjennom grensesnitt".

En grensesnitt/abstrakt klasse øverst i hierarkiet er spesifisert som returtype, og etterkommerklasser kan erstatte en arving som implementerer denne typen der. Enkelt sagt er dette mønsteret for å lage et objekt ved å klone et annet objekt i stedet for å lage det gjennom en konstruktør.

Prototype

Mønsteret brukes til å:

  • unngå den ekstra innsatsen med å lage et objekt på en standard måte (som betyr å bruke en konstruktør, siden i dette tilfellet vil konstruktørene av hele objektets forfedrehierarki også bli kalt), når dette er uoverkommelig dyrt for applikasjonen.
  • unngå å arve objektskaperen i klientapplikasjonen, slik det abstrakte fabrikkmønsteret gjør.

Bruk dette designmønsteret når programmet ditt ikke bryr seg om hvordan det lager, komponerer og presenterer produkter:

  • instansierte klasser bestemmes ved kjøretid, for eksempel ved bruk av dynamisk lasting;
  • du vil unngå å bygge klasse- eller fabrikkhierarkier som er parallelle med produktklassehierarkiet;
  • klasseforekomster kan være i en av flere forskjellige tilstander. Det kan være mer praktisk å angi riktig antall prototyper og klone dem, i stedet for å manuelt instansiere klassen i riktig tilstand hver gang.