Ontwerppatroon zichtbaar: strategiepatroon



In deze blog zullen we Strategy Design Pattern ontdekken, dat wordt gebruikt om een ​​uitwisselbare familie van algoritmen te creëren die dynamisch kunnen worden gekozen.

'

Welkom bij het eerste bericht van de serie 'Design Patterns Exposed'. In deze serie gaan we elk ontwerppatroon helemaal opnieuw ontdekken.





postdoctoraal certificaat versus meesters

Het simpelweg kennen van een programmeertaal en zijn constructies zal je geen betere programmeur of ontwikkelaar maken. Het vereist kennis van Design Patterns om software te maken die vandaag en ook in de toekomst zal werken.

Veel ontwikkelaars zijn al die ontwerpproblemen tegengekomen waarmee u nu of in de toekomst te maken krijgt. Ze hebben een standaardmanier gespecificeerd om met dat probleem om te gaan. Dus door Design Patterns te gebruiken, krijgt u het voordeel van het gebruik van bewezen technieken.



Elk ontwerppatroon is bedoeld voor het oplossen van een bepaald soort situatie. Er kunnen situaties zijn waarin meer dan één ontwerppatroon kan worden gebruikt.

De meeste programmeurs proberen gewoon het probleem waarmee ze worden geconfronteerd op te lossen zonder zich zorgen te maken over ontwerppatronen, overtollige code of zelfs nauwe koppeling. Maar goede programmeurs beginnen anders. Ze denken na over de vereisten van vandaag, toekomstige vereisten, onderhoud van code en herbruikbaarheid van code.

Goede programmeurs hebben geen haast om te beginnen met coderen zodra ze aan de vereisten voldoen. Ze zitten en denken na over het probleem of hun ontwerp zal werken. Zo ja, of het na 6 maanden zal werken, wanneer de vereisten zullen veranderen.



Goede programmeurs pakken hun pen en papier en beginnen met het ontwerpen van hun klassen en relatie tussen klassen. Ze proberen een losse koppeling en een hoge samenhang in hun ontwerp te krijgen, terwijl ze al deze dingen doen, hebben ze Object-Oriented Principles in hun hoofd. Ze gaan niet onmiddellijk naar de low-level code. Om flexibele en herbruikbare software te ontwerpen, moet u deze aanpak volgen, anders zult u altijd merken dat u code wijzigt die u eerder had geschreven.

Er is maar één ding dat constant is in de software-industrie en dat is Verandering. De eisen zullen zeker blijven veranderen. Dus hoe ontwerpen we de software die uw code gemakkelijk kan aanpassen aan toekomstige vereisten? Daarvoor moet u vroeg beginnen en het zo ontwerpen dat toekomstige vereisten uw vorige code niet verstoren.

Hoe kan ik dat doen?

Welnu, het kan worden gedaan door ontwerpprincipes en ontwerppatronen te volgen op basis van die principes.

Laten we nu eens kijken naar codering en aan de slag gaan om een ​​betere programmeur te worden. In dit bericht gaan we een van de belangrijkste patronen ontdekken - Strategiepatroon .

Als ik het belangrijkste zeg, reflecteert het op het veelvoorkomende probleem dat wordt opgelost door Strategy Pattern.

Wat is een strategiepatroon?

Hier is de definitie rechtstreeks uit het ‘Gang of Four’-boek:Het strategiepatroon wordt gebruikt om een ​​uitwisselbare familie van algoritmen te creëren waaruit het vereiste proces tijdens runtime wordt gekozen”.

Voor het geval je dat bentniet kunnen begrijpen, maak je geen zorgen, we gaan het uitleggen in eeneenvoudigermaniervoor jou om tebegrijpen.

Laten we eerst het probleem begrijpen en dan zullen we zien hoe Strategy Pattern dat kan oplossen.

In het bovenstaande UML-diagram hebben we de abstracte klasse Animal en twee concrete klassen, Dog en Bird, die zich uitstrekken van de superklasse van Animal.

Laten we dus een abstracte klasse Animal en twee concrete klassen definiëren, Dog en Bird.

Wat vind je van het bovenstaande ontwerp? Er zit een grote fout in ons ontwerp.

Alle dieren kunnen niet vliegen, zoals in het bovenstaande geval een hond niet kan vliegen. Maar toch heeft het 'vlieggedrag'.

We hebben een fout gemaakt door de abstracte fly () -methode in de klasse Animal te schrijven. Dit ontwerp dwingt elke subklasse hond, vogel, pinguïn, krokodil, gans enz. Om de methode fly () te implementeren.

We hadden moeten begrijpen dat vliegen een vaardigheid is die niet alle dieren zullen hebben. Door de methode fly () aan te bieden in de abstracte klasse Dier hebben we het vliegvermogen in alle subklassen ingesteld, wat niet correct is voor alle subklassen van dieren.

Je zou kunnen denken wat het probleem is bij het implementeren van de vliegmethode in de subklassen. Hoewel je de methode fly () in de niet-vliegende Animal-subklassen kunt implementeren om gewoon af te drukken 'Ik kan niet vliegen'. Maar het probleem is dat je het vlieggedrag nog steeds aan niet-vliegende dieren geeft. Dit is niet correct.

Hoe voelt het om dog.fly () of crocodile.fly () te noemen.

Dus nu hebben we begrepen dat ons ontwerp niet correct is en moeten we de methode fly () verwijderen uit de subklasse Animal.

Wat is de andere manier om onze klassen zo te ontwerpen dat ons ontwerp niet alle subklassen van dieren afdwingt om vlieggedrag te hebben?

Een oplossing die meteen in ons opkomt, is dat we een vliegende interface kunnen maken met een vliegmethode en alleen dieren die kunnen vliegen, zullen die vliegende interface implementeren. Op deze manier zullen we niet alle Animal-subklassen afdwingen om een ​​vlieggedrag te definiëren. Dus laten we deze ontwerpbenadering coderen.

Nu ziet onze Animal-klasse eruit als de onderstaande code nadat de fly-methode uit de Animal-klasse is verwijderd.

Laten we nu de Flying-interface definiëren

Nu zal de hondenklasse worden gewijzigdnet zode onderstaande code en het hoeft geen vlieggedrag te hebben.

Laten we eens kijken naar enkele van onze Animal-subklassen die vlieggedrag zullen hebben.

We hebben ons vorige probleem opgelost, maar we kwamen in een nieuw probleem terecht en dat is 'Code Duplication'.

Stel dat we 100 verschillende subklassen voor vliegende dieren krijgen. We moeten de code voor vlieggedrag dupliceren, aangezien de vliegende interface geen implementatie voor vlieggedrag kan bieden, en als we later de implementatie van de methode fly () in een subklasse willen wijzigen, zullen we die klasse moeten openen en de code moeten wijzigen, wat slecht is. Het ontbreekt ons aan iets groots en dat wil zeggen dat we het vlieggedrag van een klas tijdens runtime niet kunnen veranderen.

Maar maak je geen zorgen, Strategy Pattern is er om je uit dit probleem te halen.

Dus laten we onze code herstructureren om Strategiepatroon te gebruiken.

Vliegende interface blijft hetzelfde zoals het is. In plaats van elke vliegende subklasse die de vliegende interface zelf implementeert, gaan we afzonderlijke concrete klassen definiëren die een ander vlieggedrag zullen implementeren. Laten we eens kijken hoe we dat moeten doen.

hoe logger te gebruiken in java

Dus, hoe het allemaal werkt, laten we eens kijken naar de TestClass

Door Strategiepatroon te gebruiken, zijn we nu in staat om het vlieggedrag van elk dier tijdens het rennen te veranderen en dat is zonder enige subklassen te dwingen om het vlieggedrag zelf te specificeren.

Wanneer Strategiepatroon gebruiken?

Wanneer u het gedrag tijdens runtime dynamisch wilt kunnen veranderen.

Laten we nog een voorbeeld nemen om er zeker van te zijn dat u het strategiepatroon goed begrijpt.

In de bovenstaande werknemersklasse stellen we het loon van de werknemer vast op basis van zijn / haar aanwijzing. Als een werknemer een 'stagiair' is, voegen we 10% bonus toe aan het basissalaris om het werkelijke loon te berekenen.

Als een werknemer een 'webontwikkelaar' is, voegen we 20% bonus toe aan het basissalaris om het werkelijke loon te berekenen en het vergelijkbare proces volgt voor andere soorten werknemers. Hoewel ons algoritme voor het berekenen van de werkelijke beloning heel eenvoudig is om het gemakkelijker te begrijpen, bevat het meestal veel vergelijkingen en berekeningen.

Dus, wat is er mis met code voor werknemersklassen?

Welnu, de code voor het berekenen van het loon (getPay ()) is statisch. Stel dat ik de bonus voor 'Intern' wil veranderen van 10% naar 14%. Ik zal de code van de werknemersklasse moeten openen en deze moeten wijzigen.

En een ander probleem is dat ik het salarisalgoritme van een werknemer niet tijdens runtime kan wijzigen. Dus, hoe doe je dat? Strategiepatroon wordt specifiek gebruikt om dit soort problemen op te lossen.

Laten we de code herstructureren om Strategiepatroon te gebruiken.

Ik ga verschillende algoritmen definiëren om het loon te berekenen. Dan kan ik elk van deze algoritmen gebruiken om het loon tijdens runtime te berekenen.

Laten we nu eens kijken hoe de werknemersklasse gaat veranderen.

Opmerking: Ik heb de loonberekeningslogica verwijderd uit de werknemersklasse en een set PayAlgorithm () -methode gemaakt waarmee ik het PayAlgorithm zal instellen dat ik wil gebruiken voor de loonberekening.

Dit geeft mij de flexibiliteit om het loon te berekenen door een PayAlgorithm dynamisch tijdens runtime op te geven. Houd er ook rekening mee dat als ik de logica van de loonberekening moet wijzigen, ik later een nieuw PayAlgorithm kan maken en dat kan gebruiken om het loon te berekenen. Ik hoef de vorige code niet te wijzigen, is het niet geweldig?

Dus laten we zien dat het werkt.

Ik hoop dat je het Strategiepatroon heel goed hebt begrepen. De beste manier om iets te leren is door te oefenen.

Als je vragen hebt met betrekking tot Strategy Pattern of een ander Pattern, laat je vragen hieronder achter.

Kijk uit voor het volgende bericht, waar we een van de meest populaire ontwerppatronen, Fabriekspatronen, zullen ontdekken.

Tot die tijd kun je de code downloaden, ermee spelen en ervoor zorgen dat je het strategiepatroon in je hoofd vasthoudt.

Heeft u een vraag voor ons? Noem ze in het opmerkingengedeelte en we nemen contact met u op.

Gerelateerde berichten: