3.1 Singleton

Singleton är ett generiskt designmönster som garanterar att en enkeltrådad applikation kommer att ha en enda instans av någon klass och ger en global åtkomstpunkt till denna instans.

Singleton

Mycket ofta gillar nybörjare som programmerare att sätta ihop verktygsmetoder i någon statisk klass - en klass som bara innehåller statiska metoder. Detta tillvägagångssätt har ett antal nackdelar - till exempel kan du inte skicka en referens till ett objekt i en sådan klass, sådana metoder är svåra att testa och liknande.

Som ett alternativ föreslogs en singleton-klasslösning: en klass som bara kan ha ett objekt. När du försöker skapa det här objektet skapas det bara om det inte redan finns, annars returneras en referens till en redan existerande instans.

Det är viktigt att det är möjligt att använda en instans av klassen, eftersom bredare funktionalitet i många fall blir tillgänglig. Till exempel kan den här klassen implementera vissa gränssnitt och dess objekt kan skickas till andra metoder som en implementering av gränssnittet. Vad kan inte göras med en uppsättning statiska metoder.

Fördelar:

  • Metoder är bundna till ett objekt, inte en statisk klass - du kan skicka ett objekt genom referens.
  • Objektmetoder är mycket lättare att testa och håna.
  • Ett objekt skapas bara när det behövs: lat objektinitiering.
  • Accelerera den första lanseringen av programmet om det finns många singlar som inte behövs för lanseringen.
  • Ensam kan vidare omvandlas till en mallstrategi eller flera sådana objekt.

Minus:

  • Det blir svårare att kontrollera mellantrådslopp och förseningar.
  • Det är svårt att skriva en flertrådig "ensamvarg" "från huvudet": tillgång till en långvarig singel bör helst inte öppna en mutex. Bättre beprövade lösningar.
  • En konflikt mellan två trådar över en oavslutad enkel tråd kommer att resultera i en fördröjning.
  • Om objektet skapas under en längre tid kan fördröjningen störa användaren eller störa realtid. I det här fallet är det bättre att överföra dess skapelse till scenen för programinitiering.
  • Specialfunktioner krävs för enhetstestning - till exempel för att sätta biblioteket i "icke-ensamt" läge och helt isolera tester från varandra.
  • En speciell taktik för att testa det färdiga programmet krävs, eftersom även konceptet "den enklaste startbarheten" försvinner, eftersom startbarheten beror på konfigurationen.

3.2 Fabriks [metod]

En fabriksmetod är ett generiskt designmönster som förser underklasser (klass-arv) med ett gränssnitt för att skapa instanser av en viss klass. Vid skapandet kan efterkommande bestämma vilken klass som ska skapas.

Med andra ord, den här mallen delegerar skapandet av objekt till avkomlingarna till den överordnade klassen. Detta gör att du inte kan använda konkreta klasser i programkoden, utan att manipulera abstrakta objekt på en högre nivå.

Fabriksmetod

Det här mönstret definierar ett gränssnitt för att skapa ett objekt, men lämnar det upp till underklasser att bestämma vilken klass som objektet ska baseras på. En fabriksmetod tillåter en klass att delegera skapandet av underklasser. Används när:

  • klassen vet inte i förväg vilka objekt av vilka underklasser den behöver skapa.
  • en klass är utformad så att objekten den skapar specificeras av underklasser.
  • klassen delegerar sitt ansvar till en av flera hjälpunderklasser, och det är planerat att bestämma vilken klass som tar över dessa ansvarsområden.

3.3 Abstrakt fabrik

En abstrakt fabrik är ett generiskt designmönster som ger ett gränssnitt för att skapa familjer av relaterade eller beroende av varandra utan att specificera deras konkreta klasser.

Mönstret implementeras genom att skapa en abstrakt klass Factory, som är ett gränssnitt för att skapa systemkomponenter (till exempel för ett fönstergränssnitt kan det skapa fönster och knappar). Sedan skrivs klasser som implementerar detta gränssnitt.

Abstrakt fabrik

Den används i de fall då programmet måste vara oberoende av processen och typer av nya objekt som skapas. När det är nödvändigt att skapa familjer eller grupper av relaterade objekt, exklusive möjligheten till samtidig användning av objekt från olika uppsättningar av dessa i samma sammanhang.

Styrkor:

  • isolerar specifika klasser;
  • förenklar utbytet av produktfamiljer;
  • garanterar produktkompatibilitet.

Låt oss säga att ditt program fungerar med filsystemet. Sedan för att arbeta i Linux behöver du LinuxFile, LinuxDirectory, LinuxFileSystem-objekt. Och för att arbeta i Windwos behöver du klasserna WindowsFile, WindowsDirectory, WindowsFileSystem.

Path-klassen, som skapas via Path.of(), är just ett sådant fall. Path är egentligen inte en klass, utan ett gränssnitt, och den har implementeringar av WindowsPath och LinuxPath. Och vilken typ av objekt som kommer att skapas är dolt från din kod och kommer att avgöras vid körning.

3.4 Prototyp

Prototyp är ett generativt designmönster.

Detta mönster definierar de typer av objekt som skapas med hjälp av en prototypinstans och skapar nya objekt genom att kopiera denna prototyp. Det låter dig komma bort från implementeringen och följa principen om "programmering genom gränssnitt".

Ett gränssnitt/abstrakt klass högst upp i hierarkin anges som den returnerande typen, och efterkommande klasser kan ersätta en arvtagare som implementerar denna typ där. Enkelt uttryckt är detta mönstret för att skapa ett objekt genom att klona ett annat objekt istället för att skapa det genom en konstruktor.

Prototyp

Mönstret används för att:

  • undvika den extra ansträngningen att skapa ett objekt på ett standardsätt (vilket betyder att använda en konstruktor, eftersom i detta fall konstruktörerna för hela objektets förfaderhierarki också kommer att kallas), när detta är oöverkomligt dyrt för applikationen.
  • undvika att ärva objektskaparen i klientapplikationen, som det abstrakta fabriksmönstret gör.

Använd detta designmönster när ditt program inte bryr sig om hur det skapar, komponerar och presenterar produkter:

  • instansierade klasser bestäms vid körning, till exempel med hjälp av dynamisk laddning;
  • du vill undvika att bygga klass- eller fabrikshierarkier som är parallella med produktklasshierarkin;
  • klassinstanser kan vara i en av flera olika tillstånd. Det kan vara bekvämare att ställa in lämpligt antal prototyper och klona dem, snarare än att manuellt instansiera klassen i lämpligt tillstånd varje gång.