Patró de disseny exposat: patró d'estratègia

En aquest bloc descobrirem el patró de disseny d’estratègia, que s’utilitza per crear una família d’algoritmes intercanviables que es poden triar dinàmicament.

'



Benvingut al primer post de la sèrie 'Disseny de patrons exposats'. En aquesta sèrie descobrirem cada patró de disseny des de zero.



Simplement conèixer un llenguatge de programació i les seves construccions no us convertirà en un millor programador o desenvolupador. Requereix coneixement dels patrons de disseny per crear programari que funcioni avui i també en el futur.

Molts desenvolupadors ja s’han trobat amb aquells problemes de disseny que s’enfronten ara mateix o que s’enfrontaran en el futur. Han especificat una forma estàndard de tractar aquest problema. Per tant, mitjançant l’ús de patrons de disseny obtindreu l’avantatge d’utilitzar tècniques provades.



Cada patró de disseny serveix per resoldre un tipus de situació concret; pot haver-hi situacions en què es pugui utilitzar més d’un patró de disseny.

La majoria dels programadors només intenten resoldre el problema al qual s’enfronten sense molestar-se en els patrons de disseny, el codi redundant o fins i tot l’acoblament estret. Però els bons programadors comencen de manera diferent. Pensen en els requisits actuals, els requisits futurs, el manteniment del codi i la reutilització del codi.

Els bons programadors no tenen pressa per començar a codificar un cop aconsegueixen els requisits. Seuen i pensen en el problema de si el seu disseny funcionarà. Si és així, si funcionarà al cap de 6 mesos, quan canviaran els requisits.



Els bons programadors agafen la seva ploma i paper i comencen a dissenyar les seves classes i la relació entre classes. Intenten aconseguir un acoblament fluix i una alta cohesió en el seu disseny, mentre que fan tot això, tenen en ment els principis orientats a objectes. No entren immediatament dins del codi de baix nivell. Per dissenyar programari flexible i reutilitzable, heu de seguir aquest enfocament en cas contrari, sempre us trobareu modificant el codi que havíeu escrit anteriorment.

Només hi ha una cosa que sigui constant a la indústria del programari i que sigui Canvi. Els requisits segurament continuaran canviant. Llavors, com dissenyem el programari perquè el vostre codi s’adapti fàcilment als requisits futurs? Per a això, heu de començar aviat i dissenyar-lo de manera que els requisits futurs no trenquin el vostre codi anterior.

Com puc fer això?

Bé, es pot fer seguint els principis de disseny i els patrons de disseny basats en aquests principis.

diferència entre titella i xef

Ara, aprofundim en la codificació i comencem el viatge per convertir-nos en un millor programador. En aquest post, descobrirem un dels patrons més importants - Patró d’estratègia .

Quan dic el més important, reflexiona sobre el problema comú que resol el patró d’estratègia.

Què és el patró d'estratègia?

Aquí teniu la definició directa del llibre ‘La colla dels quatre’:El patró d’estratègia s’utilitza per crear una família d’algoritmes intercanviables a partir dels quals s’escull el procés requerit en temps d’execució'.

Per si ho ésno puc entendre, no us preocupeu, ho explicarem en unmés senzillmaneraperquè tu ho facisentendre.

Primer entenem el problema i després veurem com el patró d’estratègia pot solucionar-ho.

Al diagrama UML anterior, tenim la classe abstracta Animal i dues classes concretes, Dog i Bird, que s’estenen des de la super classe Animal.

Definim, doncs, una classe abstracta Animal i dues classes concretes, Dog and Bird.

Què en penseu del disseny anterior? Hi ha un gran error en el nostre disseny.

Tots els animals no poden volar, com en el cas anterior un gos no pot volar. Però, tot i així, té un comportament de 'volar'.

Vam cometre un error escrivint el mètode abstract fly () dins de la classe Animal. Aquest disseny obligarà a cada subclasse Dog, Bird, Penguin, Cocodril, Goose, etc. a implementar el mètode fly ().

Hauríem d’entendre que volar és una capacitat que no tots els animals tindran. En proporcionar el mètode fly () a la classe Animal abstract, hem establert la capacitat de vol en totes les subclases que no és correcta per a totes les subclases d’animals.

Potser penseu quin és el problema en implementar el mètode fly a les subclases. Tot i que podeu implementar el mètode fly () a les subcategories Animal no volants per imprimir només 'No puc volar'. Però el problema és que encara doneu comportament a la mosca a animals que no volen. Això no és correcte.

Com se sent anomenar dog.fly () o cocodril.fly ().

Per tant, ara hem entès que el nostre disseny no és correcte i que hauríem d’eliminar el mètode fly () de la subclasse Animal.

Quina és l’altra manera de dissenyar les nostres classes de manera que el nostre disseny no imposi a totes les subclases Animal tenir un comportament de mosca.

com compilar un programa Java

Una solució que ens ve al cap immediatament és que podem crear una interfície de vol amb mètode de vol i només els animals que puguin volar implementaran aquesta interfície de vol. D'aquesta manera, no farem complir totes les subclases d'animals per definir un comportament de mosca. Per tant, codifiquem aquest enfocament de disseny.

Ara, la nostra classe Animal tindrà l’aspecte del codi següent després d’eliminar el mètode fly de la classe Animal.

Ara definim la interfície Flying

Ara, es canviarà la classe de gossoscomel codi següent i no necessita tenir comportament de mosca.

Vegem algunes de les nostres subclases d'animals que tenen un comportament de vol.

Hem resolt el nostre problema anterior, però ens hem trobat amb un problema nou, que és 'Duplicació de codi'.

Digueu que tindrem 100 subclases d’animals voladors diferents. Hem de duplicar el codi per al comportament de la mosca ja que la interfície de vol no pot proporcionar cap implementació per al comportament de la mosca i, més endavant, si volem canviar la implementació del mètode fly () en qualsevol subclasse haurem d’obrir aquesta classe i canviar el codi, que és dolent. Ens falta alguna cosa gran i, és a dir, no podem canviar el comportament de vol d'una classe en temps d'execució.

Però no us preocupeu, el patró d’estratègia hi ha per sortir d’aquest problema.

Per tant, refactoritzem el nostre codi per utilitzar el patró d’estratègia.

La interfície de vol seguirà sent la mateixa que és. Ara, en lloc de implementar la pròpia interfície de vol per cada subclasse de vol, definirem classes concretes separades que implementaran diferents comportaments de vol. Vegem com fer-ho.

Així, doncs, com funciona tot, vegem el TestClass

En utilitzar el patró d’estratègia, ara podem canviar el comportament de vol de qualsevol animal en temps d’execució i això sense aplicar cap subclasse per especificar el comportament de vol en si mateix.

Quan s’ha d’utilitzar el patró d’estratègia?

Quan vulgueu poder canviar dinàmicament el comportament en temps d'execució.

Per assegurar-vos que enteneu clarament el patró d’estratègia, posem un altre exemple.

A la classe Empleat anterior, establim el sou de l’empleat en funció de la seva designació. Si un empleat és “intern”, afegirem un 10% de bonificació al salari bàsic per calcular el sou real.

Si un empleat és un 'desenvolupador web', afegirem un 20% de bonificació al salari bàsic per calcular la paga real i es produeix un procés similar per a altres tipus d'empleats. Tot i que el nostre algorisme per calcular el sou real és molt senzill per facilitar la comprensió, però la majoria de les vegades, inclou moltes comparacions i càlculs.

c ++ ordenar matriu d’ints

Què passa, doncs, amb el codi de la classe dels empleats?

Bé, el codi per calcular el salari (getPay ()) és estàtic. Suposem que vull canviar la bonificació per a 'Intern' del 10% al 14%. Hauré d’obrir el codi de la classe Empleat i canviar-lo.

I un altre problema és que no puc canviar l’algoritme de remuneració d’un empleat en temps d’execució. Llavors, com fer-ho? El patró d’estratègia s’utilitza específicament per tractar aquest tipus de problemes.

Refactoritzem el codi per utilitzar patró d’estratègia.

Vaig a definir diversos algoritmes per calcular el sou. Després podré utilitzar qualsevol d'aquests algoritmes per calcular el pagament en temps d'execució.

Ara, vegem com canviarà la classe Employee.

Nota: He eliminat la lògica de càlcul de la paga de la classe Employee i he creat un mètode de PayAlgorithm () definit mitjançant el qual definiré el PayAlgorithm que vull utilitzar per al càlcul de la paga.

Això em donarà la flexibilitat per calcular el sou especificant dinàmicament qualsevol PayAlgorithm en temps d'execució. Tingueu en compte també que més endavant, si he de canviar la lògica de càlcul de la remuneració, puc crear un nou PayAlgorithm i utilitzar-lo per calcular la paga. No necessito canviar el codi anterior, no és fantàstic?

Així doncs, ho veiem funcionant.

Espero que hagueu entès molt bé el patró d’estratègia. La millor manera d’aprendre alguna cosa és practicant.

En cas que tingueu alguna consulta relacionada amb el patró d’estratègia o qualsevol altre patró, deixeu-les a continuació.

Compte amb la propera publicació, on descobrirem un dels patrons de disseny més populars, Factory Pattern.

Fins que pugueu descarregar el codi amb ell i assegureu-vos de consolidar el patró d'estratègia al cap.

Tens alguna pregunta? Esmenta’ls a la secció de comentaris i et respondrem.

Articles Relacionats: