Vystavený návrhový vzor: strategický vzor

V tomto blogu odhalíme Strategy Design Pattern, který se používá k vytvoření zaměnitelné rodiny algoritmů, které lze vybrat dynamicky.

'

Vítejte u prvního příspěvku ze série „Design Patterns Exposed“. V této sérii odhalíme každý návrhový vzor od nuly.





Pouhá znalost programovacího jazyka a jeho konstrukcí z vás neudělá lepšího programátora nebo vývojáře. Vyžaduje znalost návrhových vzorů pro vytvoření softwaru, který bude fungovat dnes i v budoucnu.

Mnoho vývojářů již narazilo na problémy s designem, kterým nyní nebo v budoucnu čelíte. Stanovili standardní způsob řešení tohoto problému. Použitím návrhových vzorů tedy získáte výhodu použití osvědčených technik.



Každý návrhový vzor slouží k řešení konkrétního druhu situace. Mohou nastat situace, kdy lze použít více než jeden návrhový vzor.

Většina programátorů se pokouší vyřešit problém, kterému čelí, aniž by se obtěžovali s návrhovými vzory, nadbytečným kódem nebo dokonce těsným spojením. Ale dobří programátoři začínají jinak. Přemýšlí o dnešních požadavcích, budoucích požadavcích, údržbě kódu a opětovné použitelnosti kódu.

Dobří programátoři nespěchají s zahájením programování, jakmile splní požadavky. Sedí a přemýšlejí o problému, zda bude jejich design fungovat. Pokud ano, zda to bude fungovat po 6 měsících, kdy se požadavky změní.



Dobří programátoři si vezmou pero a papír a začnou navrhovat své třídy a vztahy mezi třídami. Snaží se dosáhnout volného propojení a vysoké soudržnosti ve svém designu, přičemž při tom všem mají v mysli objektově orientované principy. Nevejdou okamžitě do nízkoúrovňového kódu. Chcete-li navrhnout flexibilní a opakovaně použitelný software, měli byste se řídit tímto přístupem, jinak se vždy ocitnete v úpravě kódu, který jste napsali dříve.

Existuje pouze jedna věc, která je v softwarovém průmyslu konstantní, a to je Změna. Požadavky se určitě budou neustále měnit. Jak tedy navrhneme software, který se váš kód snadno přizpůsobí budoucím požadavkům? K tomu musíte začít brzy a navrhnout to tak, aby budoucí požadavky neporušily váš předchozí kód.

Jak to mohu udělat?

Lze to provést dodržováním návrhových zásad a návrhových vzorů založených na těchto zásadách.

Pojďme se nyní ponořit do programování a vydat se na cestu stát se lepším programátorem. V tomto příspěvku odhalíme jeden z nejdůležitějších vzorů - Strategický vzor .

Když řeknu nejdůležitější, odráží se to na běžném problému, který řeší Strategy Pattern.

Co je to Strategy Pattern?

Zde je definice přímo z knihy „Gang čtyř“: „Strategický vzor se používá k vytvoření zaměnitelné rodiny algoritmů, ze kterých je za běhu zvolen požadovaný proces“.

V případě, že jstenerozumím, nebojte se, vysvětlíme to v ajednoduššízpůsobpro vásrozumět.

Nejprve pochopíme problém a pak uvidíme, jak to Strategický vzor může vyřešit.

Ve výše uvedeném diagramu UML máme třídu Animal abstract a dvě konkrétní třídy, Dog and Bird, vycházející ze super třídy Animal.

Pojďme tedy definovat třídu abstraktů zvířat a dvě konkrétní třídy, pes a pták.

Co si myslíte o výše uvedeném designu? V našem designu je jedna velká chyba.

Všechna zvířata nemohou létat, stejně jako ve výše uvedeném případě pes nemůže létat. Ale stále to má „létající“ chování.

Udělali jsme chybu, když jsme ve třídě Animal napsali metodu abstract fly (). Tento design donutí všechny podtřídy Dog, Bird, Penguin, Crocodile, Goose atd. K implementaci metody fly ().

Měli jsme pochopit, že létání je schopnost, kterou nebudou mít všechna zvířata. Poskytnutím metody fly () ve třídě abstraktů zvířat jsme nastavili schopnost létat ve všech podtřídách, což není správné pro všechny podtřídy zvířat.

Možná si myslíte, jaký je problém při implementaci metody fly v podtřídách. I když můžete implementovat metodu fly () v neletících podtřídách Animal, stačí vytisknout „Nemůžu létat“. Ale problém je v tom, že stále dáváte chování mouchy nelétavým zvířatům. To není správné.

Jaký je to pocit volat dog.fly () nebo crocodile.fly ().

Nyní jsme tedy pochopili, že náš návrh není správný, a proto bychom měli z podtřídy Animal odstranit metodu fly ().

Jaký je jiný způsob navrhování našich tříd takovým způsobem, aby náš design nevynucoval chování všech podtříd zvířat, aby se chovaly mouchou.

Jedno řešení, které nám okamžitě přijde na mysl, je, že můžeme vytvořit létající rozhraní s metodou létání a toto létající rozhraní implementují pouze zvířata, která mohou létat. Tímto způsobem nebudeme vynucovat všechny podtřídy zvířat, aby definovaly chování mouchy. Pojďme si tedy kódovat tento designový přístup.

Nyní bude naše třída Animal vypadat jako níže uvedený kód po odebrání metody fly ze třídy Animal.

Nyní definujme létající rozhraní

Nyní se změní třída psatak jakoníže uvedený kód a nemusí mít chování při letu.

Podívejme se na některé z našich podtříd zvířat, které budou mít létající chování.

Vyřešili jsme náš předchozí problém, ale dostali jsme se do nového problému, a to je „Duplikace kódu“.

Řekněme, že budeme mít 100 různých podtříd létajících zvířat. Musíme duplikovat kód chování létání, protože létající rozhraní nemůže poskytnout žádnou implementaci chování chování, a později, pokud chceme změnit implementaci metody fly () v jakékoli podtřídě, budeme muset tuto třídu otevřít a změnit kód, což je špatné. Chybí nám něco velkého a to znamená, že nemůžeme změnit létající chování třídy za běhu.

Ale nebojte se, Strategy Pattern je tu, aby vás z tohoto problému dostal.

Pojďme tedy refaktorovat náš kód tak, aby používal Strategy Pattern.

Létající rozhraní zůstane stejné, jaké je. Nyní, spíše než každá létající podtřída implementující samotné létající rozhraní, budeme definovat samostatné konkrétní třídy, které budou implementovat odlišné létající chování. Uvidíme, jak na to.

Jak to tedy všechno funguje, podívejme se na TestClass

Použitím Strategy Pattern jsme nyní schopni změnit chování létání jakéhokoli zvířete za běhu, a to bez vynucení jakýchkoli podtříd k určení samotného chování létání.

Kdy použít strategický vzor?

Když chcete mít možnost dynamicky měnit chování za běhu.

Abychom jasně pochopili strategický vzor, ​​vezměme si další příklad.

Ve výše uvedené třídě zaměstnanců stanovujeme odměnu zaměstnance v závislosti na jeho / jejím označení. Pokud je zaměstnanec „stážista“, přidáváme k základnímu platu 10% bonus k výpočtu skutečné mzdy.

Pokud je zaměstnanec „webový vývojář“, přidáváme k základnímu platu 20% bonus k výpočtu skutečné mzdy a obdobný postup je u ostatních typů zaměstnanců. Ačkoli je náš algoritmus pro výpočet skutečné mzdy velmi jednoduchý, aby bylo snazší pochopit, ale většinou obsahuje mnoho srovnání a výpočtů.

Co se děje s kódem třídy zaměstnanců?

Kód pro výpočet pay (getPay ()) je statický. Předpokládám, že chci změnit bonus za „Intern“ z 10% na 14%. Budu muset otevřít kód třídy zaměstnanců a změnit jej.

A dalším problémem je, že nemohu změnit platový algoritmus zaměstnance za běhu. Jak na to? Strategický vzor se konkrétně používá k řešení tohoto druhu problému.

Podívejme se na refaktorování kódu, abychom mohli použít Strategy Pattern.

Budu definovat několik algoritmů pro výpočet platu. Pak budu schopen použít kterýkoli z těchto algoritmů k výpočtu výplaty za běhu.

Nyní se podívejme, jak se třída zaměstnanců změní.

Poznámka: Odstranil jsem logiku výpočtu výplaty ze třídy Zaměstnanec a vytvořil jsem metodu PayAlgorithm (), pomocí které nastavím PayAlgorithm, který chci použít pro výpočet výplaty.

To mi dá flexibilitu pro výpočet výplaty zadáním libovolného PayAlgorithmu dynamicky za běhu. Všimněte si také, že později, když budu muset změnit logiku výpočtu platů, mohu vytvořit nový PayAlgorithm a použít jej k výpočtu mzdy. Předchozí kód nemusím měnit, není to skvělé?

Pojďme se podívat, jak to funguje.

Doufám, že jste velmi dobře pochopili strategický vzor. Nejlepší způsob, jak se něco naučit, je cvičit.

V případě, že máte nějaké dotazy týkající se strategického vzoru nebo jiného vzoru, nechte své dotazy níže.

Dávejte pozor na další příspěvek, kde odhalíme jeden z nejpopulárnějších návrhových vzorů, Factory Pattern.

Do té doby si můžete stáhnout kód, který s ním budete hrát, a ujistěte se, že jste si v hlavě upevnili strategický vzor.

Máte na nás dotaz? Uveďte je v sekci komentáře a my se vám ozveme.

Související příspěvky:

jak klonovat objekt v javě