designmønstre er designniveauløsninger til tilbagevendende problemer, som vi soft .areingeniører ofte støder på. Det er ikke kode-jeg gentager, CODE kode. Det er som en beskrivelse af, hvordan man håndterer disse problemer og designer en løsning. brug af disse mønstre betragtes som god praksis, da løsningens design er ret afprøvet og testet, hvilket resulterer i højere læsbarhed af den endelige kode., Designmønstre oprettes ganske ofte til og bruges af OOP-sprog, som Java, hvor de fleste eksempler herfra vil blive skrevet.

typer af designmønstre

der er omkring 26 mønstre i øjeblikket opdaget (jeg tror næppe, jeg vil gøre dem alle…).

disse 26 kan klassificeres i 3 typer:

1. Creational: disse mønstre er designet til klasse instantiering. De kan enten være klasseoprettelsesmønstre eller objektskabelsesmønstre.

2. Strukturelle: disse mønstre er designet med hensyn til en klasses struktur og sammensætning., Hovedmålet med de fleste af disse mønstre er at øge funktionaliteten i den involverede klasse(r) uden at ændre meget af dens sammensætning.

3. Adfærdsmæssige: disse mønstre er designet afhængigt af, hvordan en klasse kommunikerer med andre.

i dette indlæg vil vi gennemgå et grundlæggende designmønster for hver klassificeret type.

Type 1: Skabende – Singleton Design Pattern

Singleton Design Pattern er en Skabende mønster, hvis mål er at skabe blot en instans af en klasse, og til at give et samlet adgangspunkt til det pågældende objekt., Et almindeligt anvendt eksempel på en sådan klasse i Java er kalender, hvor du ikke kan lave en forekomst af denne klasse. Den bruger også sin egen getInstance()metode til at få det objekt, der skal bruges.

En klasse med singleton design pattern vil omfatte,

Singleton Klasse Diagram
  1. En privat statisk variabel, holder den eneste instans af klassen.
  2. en privat konstruktør, så den kan ikke instantieres andre steder.
  3. en offentlig statisk metode til at returnere den enkelte forekomst af klassen.,

Der er mange forskellige implementeringer af singleton design. I dag vil jeg gennemgå implementeringerne af;

1. Ivrig Instantiation

2. La .y Instantiation

3. Trådsikker instantiering

ivrig bæver

public class EagerSingleton {// create an instance of the class.private static EagerSingleton instance = new EagerSingleton();// private constructor, so it cannot be instantiated outside this class.private EagerSingleton() { }// get the only instance of the object created.public static EagerSingleton getInstance() {return instance;}}

denne type instantiering sker under klasseindlæsning, da instantieringen af den variable forekomst sker uden for enhver metode. Dette udgør en stor ulempe, hvis denne klasse slet ikke bruges af klientapplikationen. Beredskabsplanen, hvis denne klasse ikke bruges, er den dovne instantiering.,

La Daysy Days

Der er ikke meget forskel fra ovenstående implementering. De væsentligste forskelle er, at den statiske variabel oprindeligt erklæres null og kun instantieres inden forgetInstance() – metoden, hvis – og kun hvis-instansvariablen forbliver null på kontroltidspunktet.

dette løser et problem, men en anden eksisterer stadig. Hvad hvis to forskellige klienter får adgang til Singleton-klassen på samme tid, lige til millisekundet?, Nå, de vil kontrollere, om forekomsten er null på samme tid, og vil finde det sandt, og det vil også skabe to forekomster af klassen for hver anmodning fra de to klienter. For at løse dette skal trådsikker instantiering implementeres.

(tråd) sikkerhed er nøglen

i Java bruges nøgleordet synkroniseret på metoder eller objekter til at implementere trådsikkerhed, så kun en tråd får adgang til en bestemt ressource ad gangen. Klassen instantiation er sat i en synkroniseret blok, således at metoden kun kan tilgås af clientn klient på et givet tidspunkt.,

overhead for den synkroniserede metode er høj, og reducerer udførelsen af hele operationen. hvis eksempelvariablen allerede er instantieret, køres metoden getInstance(), hver gang en klient får adgang til synchronized, og ydeevnen falder. Dette sker bare for at kontrollere, om instance variablernes værdi er null. Hvis det finder ud af, at det er, forlader det metoden.

for at reducere denne overhead anvendes dobbelt låsning., Kontrollen bruges før synchronized metoden, og hvis værdien er null alene, kører synchronized metoden.

nu til den næste klassifikation.

Type 2: Structural – the Decorator Design Pattern

Jeg vil give dig et lille scenario for at give en bedre kontekst til hvorfor og hvor du skal bruge Dekoratormønsteret.

sig, at du ejer en kaffebar, og som enhver nybegynder starter du med kun to typer almindelig kaffe, husblandingen og mørk stege., I dit faktureringssystem var der en klasse for de forskellige kaffeblandinger, som arver klassen beverage abstract. Folk begynder faktisk at komme forbi og have din vidunderlige (omend bitter?) kaffe. Så er der kaffe ne .bs, som Gud forbyder, vil have sukker eller mælk. Sådan en travesty for kaffe!! ??nu skal du også have disse to tilføjelser, både til menuen og desværre på faktureringssystemet. Oprindeligt, din IT-person vil lave en underklasse til begge kaffe, den ene inklusive sukker, den anden mælk., Da kunderne altid har ret, siger man disse frygtede ord:

” Kan jeg få en mælkekaffe med sukker, tak?”

???

der går dit faktureringssystem griner i dit ansigt igen. Nå, tilbage til tegnebrættet….

IT-personen tilføjer derefter mælkekaffe med sukker som en anden underklasse til hver forældreklasse. Resten af måneden er glat sejlads, folk stiller op for at få din kaffe, du tjener faktisk penge. ??

men vent, der er mere!

verden er imod dig igen., En konkurrent åbner på tværs af gaden, med ikke kun 4 typer kaffe, men mere end 10 tilføjelser også! ?

du køber alle dem og mere for at sælge bedre kaffe selv, og husk bare, at du har glemt at opdatere det dratted faktureringssystem. Du kan muligvis ikke lave det uendelige antal underklasser for alle kombinationer af alle tilføjelser, med de nye kaffeblandinger også. For ikke at nævne størrelsen af det endelige system.??

tid til faktisk at investere i et ordentligt faktureringssystem., Du finder nyt IT-personale, der faktisk ved, hvad de laver, og de siger;

“hvorfor, dette vil være så meget lettere og mindre, hvis det brugte dekoratormønsteret.”

hvad I alverden er det?

dekoratørens designmønster falder ind under den strukturelle kategori, der beskæftiger sig med den faktiske struktur af en klasse, hvad enten det er ved arv, sammensætning eller begge dele. Målet med dette design er at ændre en objekts funktionalitet på runtime. Dette er et af de mange andre designmønstre, der bruger abstrakte klasser og grænseflader med komposition for at få det ønskede resultat.,

lad os give Matematik en chance (gyser?) for at bringe alt dette i perspektiv;

Tag 4 kaffeblandinger og 10 tilføjelser. Hvis vi holdt os til genereringen af underklasser for hver anden kombination af alle tilføjelser til en type kaffe. Det er;

(10-1)2 = 92 = 81 underklasser

Vi trækker 1 fra 10, da du ikke kan kombinere en tilføjelse med en anden af samme type, sukker med sukker lyder dumt. Og det er kun til en kaffeblanding. Multiplicer at 81 ved 4, og du får en kæmpestor 324 forskellige underklasser!, Tal om alt det kodning …

men med dekoratørmønsteret kræves kun 16 klasser i dette scenario. Vil du vædde?

Dekoratør Design Mønster Klasse diagram
Class diagram i henhold til café scenarie

Hvis vi kort vores scenarie i henhold til klasse diagrammet ovenfor, vi får 4 klasser for 4 kaffeblandinger, 10 for hver add-on og 1 for den abstrakte komponent og 1 mere til det abstrakte dekoratør. Se! 16!, Giv nu de 100 dollars.?? (jk, men det vil ikke blive nægtet, hvis det gives… bare at sige)

som du kan se ovenfra, ligesom de konkrete kaffeblandinger er underklasser af drikkevareabstrakt klassen, addon abstrakt klassen arver også sine metoder fra den. Tilføjelser, der er dens underklasser, arver igen nye metoder til at tilføje funktionalitet til basisobjektet, når det er nødvendigt.

lad os komme til kodning for at se dette mønster i brug.,

først for at lave den abstrakte drikkevareklasse, at alle de forskellige kaffeblandinger vil arve fra:

derefter for at tilføje begge de konkrete kaffeblandingsklasser.

addon abstract klassen arver også fra Beverage abstract klassen (mere om dette nedenfor).

og nu de konkrete implementeringer af denne abstrakte klasse:

som du kan se ovenfor, kan vi videregive enhver underklasse af drikkevarer til enhver underklasse af AddOn og få de ekstra omkostninger såvel som den opdaterede beskrivelse. Og da AddOn-klassen i det væsentlige er af type drik, kan vi videregive en AddOn til en anden AddOn., På denne måde kan vi tilføje et vilkårligt antal tilføjelser til en bestemt kaffeblanding.

nu for at skrive noget kode for at teste dette ud.

Det endelige resultat er:

S. S. dette er i Sri Lanka Rupees

Det virker! Vi var i stand til at tilføje mere end en tilføjelse til en kaffeblanding og med succes opdatere dens endelige omkostninger og beskrivelse uden at skulle lave uendelige underklasser for hver tilføjelseskombination for alle kaffeblandinger.

endelig til den sidste kategori.,

Type 3: Behavioral – Kommandodesignmønsteret

et adfærdsdesignmønster fokuserer på, hvordan klasser og objekter kommunikerer med hinanden. Hovedfokus for kommandomønsteret er at indgyde en højere grad af løs kobling mellem involverede parter (Læs: klasser).

Uhhhh … Hvad er det?

kobling er den måde, at to (eller flere) klasser, der interagerer med hinanden, godt interagerer. Det ideelle scenario, når disse klasser interagerer, er, at de ikke er stærkt afhængige af hinanden. Det er løs kobling., Så, en bedre definition for løs kobling ville være, klasser, der er sammenkoblet, at gøre mindst brug af hinanden.

behovet for dette mønster opstod, når anmodninger skulle sendes uden bevidst at vide, hvad du beder om, eller hvem modtageren er.

i dette mønster afkobles den påkaldende klasse fra den klasse, der faktisk udfører en handling. Invoker klassen har kun den konverterbare metode e .ecute, som kører den nødvendige kommando, når klienten anmoder om det.

lad os tage et grundlæggende eksempel i den virkelige verden ved at bestille et måltid på en fancy restaurant., Når strømmen går, giver du din ordre (kommando) til tjeneren (invoker), som derefter overleverer den til kokken(modtager), så du kan få mad. Det lyder måske enkelt … men lidt meh at kode.

ideen er ret simpel, men kodningen går rundt om næsen.,

Kommando Design Mønster Klasse Diagram

Den strøm af drift på den tekniske side er, gør du en konkret kommando, som gennemfører Kommando interface, beder modtageren til at udføre en handling, og send kommandoen til at invoker. Den invoker er den person, der ved, hvornår de skal give denne kommando. Kokken er den eneste, der ved, hvad de skal gøre, når de får den specifikke kommando/ordre., Så når henvendelsesmetoden for invoker køres, får den til gengæld kommandoobjektets eksekveringsmetode til at køre på modtageren og dermed udføre nødvendige handlinger.,

Hvad er vi nødt til at gennemføre, er;

  1. Et interface Kommando
  2. En klasse For at gennemfører Kommando interface
  3. En klasse Tjeneren (invoker -)
  4. A class Chef (modtager)

Så, kodning går ud som dette:

Chef, modtageren

Kommando, interface

public interface Command {public abstract void execute();}

For, at den konkrete kommando

Tjeneren, invoker

public class Waiter {private Order order;public Waiter(Order ord) {this.order = ord;}public void execute() {this.order.execute();}}

Du, kunden

Som du kan se ovenfor, Kunden gør en Ordre og sæt Modtageren som Kok., Ordren sendes til Tjeneren, som vil vide, hvornår ordren skal udføres (dvs.hvornår kokken skal give ordren til at lave mad). Når invoker udføres, køres ordrernes eksekveringsmetode på modtageren (dvs. kokken får kommandoen til enten at lave pasta ? eller bage kage?).,

Endelige Kunde Output

Hurtig recap

I dette indlæg vil vi gik gennem:

  1. Hvad er et design pattern virkelig er,
  2. De forskellige typer af design-mønstre, og hvorfor de er forskellige
  3. En grundlæggende eller fælles design-mønsteret for hver type

jeg håber, at dette var nyttigt.

Find koden repo for stillingen, her.