Strategi | |
---|---|
strategi | |
Type | adfærdsmæssige |
Formål | giver dig mulighed for at bruge forskellige forretningsregler eller algoritmer afhængigt af konteksten. |
Gælder i sager | når de er på samme sted, afhængigt af den aktuelle tilstand af systemet (eller dets miljø), skal der bruges forskellige algoritmer |
fordele |
|
Minusser | oprettelse af yderligere klasser |
Relaterede skabeloner | Bro , skabelonmetode , adapter |
Beskrevet i Design Patterns | Ja |
Strategi ( eng. Strategy ) er et adfærdsdesignmønster designet til at definere en familie af algoritmer , indkapsle hver af dem og sikre deres udskiftelighed. Dette giver dig mulighed for at vælge en algoritme ved at definere den passende klasse. Strategiskabelonen giver dig mulighed for at ændre den valgte algoritme uanset de klientobjekter, der bruger den.
Vælg den relevante algoritme, der skal anvendes, efter typen af klient (eller den type data, der behandles). Hvis der anvendes en regel, der ikke kan ændres, er der ingen grund til at henvise til strategimønsteret.
Adskillelse af algoritmevalgsprocedure fra dens implementering. Dette gør det muligt at foretage valg baseret på kontekst.
Klassen, der bruger algoritmen ( Context) inkluderer en abstrakt klasse ( Strategy), der har en abstrakt metode, der definerer, hvordan algoritmen aktiveres. Hver afledt klasse implementerer en påkrævet version af algoritmen.
Bemærk: En algoritmeopkaldsmetode behøver ikke at være abstrakt, hvis en eller anden standardadfærd skal implementeres.
Microsoft WDF - arkitekturen er baseret på dette mønster. Hvert "driver" og "device" objekt har en uforanderlig del syet ind i systemet, hvori en foranderlig del (strategi) skrevet i en specifik implementering er registreret. Den mutable del kan være helt tom, hvilket vil give en driver, der ikke gør noget, men samtidig er i stand til at deltage i PnP og strømstyring.
ATL- biblioteket indeholder et sæt threading-modelklasser, der er strategier (forskellige implementeringer af Lock / Unlock, som derefter bruges af systemets hovedklasser). Disse strategier bruger dog statisk polymorfi gennem en skabelonparameter snarere end dynamisk polymorfi gennem virtuelle metoder.
Java eksempel
Implementeringseksempel // Klassen, der implementerer den bestemte strategi, skal implementere denne grænseflade // Kontekstklassen bruger denne grænseflade til at påkalde den bestemte strategigrænseflade Strategi { int execute ( int a , int b ) ; } // Implementer algoritmen ved hjælp af strategigrænsefladeklassen ConcreteStrategyAdd implementerer Strategy { public int execute ( int a , int b ) { System . ud . println ( "Kaldet ConcreteStrategyAdd's execute()" ); returnere a + b ; // Lav en tilføjelse med a og b } } klasse ConcreteStrategySubtract implementerer strategi { public int execute ( int a , int b ) { System . ud . println ( "Kaldet ConcreteStrategySubtract's execute()" ); returnere a - b ; // Lav en subtraktion med a og b } } klasse ConcreteStrategyMultiply implementerer Strategi { public int execute ( int a , int b ) { System . ud . println ( "Kaldet ConcreteStrategyMultiply's execute()" ); returnere a * b ; // Gør en multiplikation med a og b } } // Kontekstklasse ved hjælp af strategigrænsefladeklassen Kontekst { privat Strategistrategi ; _ // Konstruktør offentlig kontekst () { } // Sæt ny strategi public void setStrategy ( Strategy strategy ) { this . strategi = strategi ; } public int executeStrategy ( int a , int b ) { return strategi . udføre ( a , b ); } } // Test applikationsklasse StrategiEksempel { public static void main ( String [] args ) { Kontekst kontekst = ny kontekst (); kontekst . setStrategy ( ny ConcreteStrategyAdd ()); int resultatA = kontekst . executeStrategy ( 3 , 4 ); kontekst . setStrategy ( ny ConcreteStrategySubtract ()); int resultatB = kontekst . executeStrategy ( 3 , 4 ); kontekst . setStrategy ( ny ConcreteStrategyMultiply ()); int resultatC = kontekst . executeStrategy ( 3 , 4 ); System . ud . println ( "Resultat A: " + resultat A ); System . ud . println ( "Resultat B:" + resultat B ); System . ud . println ( "Resultat C: " + resultat C ); } }Eksempel i C++
Implementeringseksempel #include <iostream> klasses strategi { offentligt : virtuel ~ Strategi () {} virtuel ugyldig brug () = 0 ; }; klasse Strategi_1 : offentlig strategi { offentligt : void use (){ std :: cout << "Strategi_1" << std :: endl ; } }; klasse Strategi_2 : offentlig strategi { offentligt : void use (){ std :: cout << "Strategi_2" << std :: endl ; } }; klasse Strategi_3 : offentlig strategi { offentligt : void use (){ std :: cout << "Strategi_3" << std :: endl ; } }; klasse kontekst { beskyttet : strategi * drift ; offentligt : virtuel ~ kontekst () {} virtual void useStrategy () = 0 ; virtual void setStrategy ( Strategy * v ) = 0 ; }; klasse Klient : offentlig kontekst { offentligt : ugyldig brugStrategi () { operation -> brug (); } void setStrategy ( Strategi * o ) { operation = o ; } }; int main ( int /*argc*/ , char * /*argv*/ []) { Custom CustomClient ; strategi_1 str1 ; Strategi_2 str2 ; Strategi_3 str3 ; customClient . setStrategy ( & str1 ); customClient . brug Strategi (); customClient . setStrategy ( & str2 ); customClient . brug Strategi (); customClient . setStrategy ( & str3 ); customClient . brug Strategi (); returnere 0 ; } Implementeringseksempel (skabelonparameter) #include <iostream> struct Strategi_1 { void use (){ std :: cout << "Strategi_1" << std :: endl ; }; }; struct Strategi_2 { void use (){ std :: cout << "Strategi_2" << std :: endl ; }; }; struct Strategi_3 { void use (){ std :: cout << "Strategi_3" << std :: endl ; }; }; skabelon < classOperation > _ struct Kunde : offentlig drift { ugyldig brugStrategi () { dette -> brug (); } }; int main ( int /*argc*/ , char * /*argv*/ []) { Client < Strategi_1 > customClient1 ; customClient1 . brug Strategi (); Client < Strategy_2 > customClient2 ; customClient2 . brug Strategi (); Client < Strategy_3 > customClient3 ; customClient3 . brug Strategi (); returnere 0 ; }Eksempel i C#
Implementeringseksempel bruger System ; namespace DesignPatterns.Behavioral.Strategy { // Klassen, der implementerer den bestemte strategi, skal arve denne grænseflade // Kontekstklassen bruger denne grænseflade til at påkalde den bestemte strategi offentlige grænseflade IStrategy { void Algorithm (); } // Første konkrete implementeringsstrategi. public class ConcreteStrategy1 : IStrategy { public void Algorithm () { Console . WriteLine ( "Strategialgoritme 1 kører." ); } } // Anden konkret implementeringsstrategi. // Der kan være så mange implementeringer, som du vil. public class ConcreteStrategy2 : IStrategy { public void Algorithm () { Console . WriteLine ( "Strategialgoritme 2 kører." ); } } // Kontekst, der bruger strategien til at løse sit problem. public class Context { // Reference til IStrategy-grænsefladen // giver dig mulighed for automatisk at skifte mellem specifikke implementeringer // (med andre ord, dette er valget af en specifik strategi). privat IStrategy_strategy ; _ // Kontekstkonstruktør. // Initialiserer objektet med strategien. offentlig kontekst ( ISstrategistrategi ) { _strategi = strategi ; _ } // Metode til fastlæggelse af strategien. // Bruges til at ændre strategi under kørsel. // I C# kan det også implementeres som en record-egenskab. public void SetStrategy ( IStrategy strategy ) { _strategy = strategy ; } // Nogen kontekstfunktionalitet, der vælger // en strategi og bruger den til at udføre sin opgave. public void ExecuteOperation () { _strategi . algoritme (); } } // Ansøgningsklasse. // Fungerer som en kontekstklient i dette eksempel. offentlig statisk klasse Program { // <resumé> // Programindgangspunkt. // </summary> public static void Main () { // Opret en kontekst og initialiser den med den første strategi. Kontekstkontekst = ny Kontekst ( ny KonkretStrategy1 ( )); // Udfør en kontekstoperation, der bruger den første strategi. kontekst . ExecuteOperation (); // Erstat den første strategi med den anden i konteksten. kontekst . SetStrategy ( ny ConcreteStrategy2 ()); // Udfør kontekstoperationen, som nu bruger den anden strategi. kontekst . ExecuteOperation (); } } }Eksempler i D
Implementeringseksempel import std . stdio ; interface IStrategy { int Action ( int a , int b ); } klasse TAddition : IStrategy { public int Action ( int a , int b ) { return a + b ; } } klasse TSubtraktion : IStrategy { public int Action ( int a , int b ) { retur a - b ; } } klasse TContexet { privat : int a , b ; IStrategistrategi ; _ public : void SetAB ( int a , int b ) { TContexet . a = a ; TContexet . b = b ; }; void SetStrategy ( IStrategy strategy ) { TContexet . strategi = strategi ; } int Action ( ) { returstrategi . Handling ( a , b ); } } void main () { TContexet kontekst = ny TContexet ; kontekst . SetAB ( 10 , 5 ); kontekst . SetStrategy ( ny TAddition ); writeln ( kontekst . Handling ( ) ); // femten kontekst . SetStrategy ( ny TSubtraktion ); writeln ( kontekst . Handling ( ) ); // 5 }Eksempel i Delphi
Implementeringseksempel program Strategy_pattern ; {$APPTYPE KONSOL} type IStrategy = interface [ '{6105F24C-E5B2-47E5-BE03-835A894DEB42}' ] procedure Algoritme ; ende ; TConcreteStrategy1 = klasse ( TInterfacedObject , IStrategy ) offentlig procedurealgoritme ; _ ende ; procedure TConcreteStrategy1 . algoritme ; start Writeln ( 'TConcreteStrategy1.Algorithm' ) ; ende ; type TConcreteStrategy2 = klasse ( TInterfacedObject , IStrategy ) offentlig procedurealgoritme ; _ ende ; procedure TConcreteStrategy2 . algoritme ; start Writeln ( 'TConcreteStrategy2.Algorithm' ) ; ende ; type TContext = klasse privat FStrategy : IStrategy ; offentlig procedure ContextMethod ; ejendomsstrategi : IStrategy læs FStrategy skriv FStrategy ; _ ende ; procedure TKontekst . ContextMethod ; begynde FStrategy . algoritme ; ende ; var Context : TContext ; start Context := TContext . skabe ; prøv kontekst . Strategi := TBetonStrategi1 . skabe ; Kontekst . ContextMethod ; Kontekst . Strategi := TConcreteStrategy2 . skabe ; Kontekst . ContextMethod ; endelig kontekst . Gratis ; ende ; ende .Javascript eksempler
Implementeringseksempel // "interface"-strategi function Strategy () { this . exec = funktion () {}; }; // implementere strategi // vis beskeden i browserens statuslinje // (understøttes ikke af alle browsere) funktion StrategyWindowStatus () { this . exec = funktion ( meddelelse ) { vindue . status = besked ; }; }; StrategiWindowStatus . prototype = ny strategi (); StrategiWindowStatus . prototype . constructor = StrategiWindowStatus ; // vis besked via popup // (kan være blokeret af browser) funktion StrategyNewWindow () { this . exec = funktion ( meddelelse ) { var win = vindue . åben ( "" , "_blank" ); vinde . dokument . skriv ( "<html>" + besked + "</html>" ); }; }; StrategiNewWindow . prototype = ny strategi (); StrategiNewWindow . prototype . constructor = StrategiNewWindow ; // vis besked ved hjælp af modal vinduesfunktion StrategyAlert ( ) { this . exec = funktion ( meddelelse ) { advarsel ( meddelelse ); }; }; Strategialarm . prototype = ny strategi (); Strategialarm . prototype . constructor = Strategialarm ; // Kontekst funktion Kontekst ( strategi ) { dette . exec = funktion ( meddelelse ) { strategi . exec ( meddelelse ); }; } // Brug var showInWindowStatus = new Context ( ny StrategyWindowStatus () ); var showInNewWindow = new Context ( new StrategyNewWindow () ); var showInAlert = new Context ( new StrategyAlert () ); showInWindowStatus . exec ( "meddelelse" ); showInNewWindow . exec ( "meddelelse" ); showInAlert . exec ( "meddelelse" );Eksempler i PHP
Implementeringseksempel <?php interface NamingStrategy { function createName ( $filename ); } klasse ZipFileNamingStrategy implementerer NamingStrategy { function createName ( $filename ) { return "http://downloads.foo.bar/ { $filename } .zip" ; } } klasse TarGzFileNamingStrategy implementerer NamingStrategy { function createName ( $filename ) { return "http://downloads.foo.bar/ { $filename } .tar.gz" ; } } klasse Kontekst { privat $nameStrategy ; funktion __construct ( Navngivningsstrategi $strategi ) { $this -> namingStrategy = $strategi ; } funktion execute () { $url [] = $this -> navngivningsstrategi -> createName ( "Calc101" ); $url [] = $this -> navngivningsstrategi -> createName ( "Stat2000" ); returner $url ; } } if ( strstr ( $_SERVER [ "HTTP_USER_AGENT" ], "Win" )) $context = new Context ( ny ZipFileNamingStrategy ()); else $context = new Context ( ny TarGzFileNamingStrategy ()); $kontekst -> udfør (); ?>Eksempel i Python 2.7
Implementeringseksempel klasse Personer ( objekt ): værktøj = Ingen def __init__ ( selv , navn ): selv . navn = navn def setVærktøj ( selv , værktøj ): selv . værktøj = værktøj def skrive ( selv , tekst ): selv . værktøj . skriv ( selv . navn , tekst ) class ToolBase : """ `Skriveværktøj` Algoritmefamilie """ def skriv ( selv , navn , tekst ): raise NotImplementedError () klasse PenTool ( ToolBase ): """Pen""" def skriv ( selv , navn , tekst ): print u ' %s (pen) %s ' % ( navn , tekst ) klasse BrushTool ( ToolBase ): """Brush""" def skriv ( selv , navn , tekst ): print u ' %s (med pensel) %s ' % ( navn , tekst ) klasse Elev ( Personer ): """Student""" værktøj = PenTool () klasse Maler ( People ): """Kunstner""" værktøj = BrushTool () maxim = Student ( u 'Maxim' ) maxim . skriv ( u 'Jeg skriver et foredrag om strategimønsteret' ) # Maxim (med en pen) Jeg skriver et foredrag om strategimønsteret sasha = Maler ( u 'Sasha' ) sasha . skriv ( u 'Jeg tegner en illustration til strategimønsteret' ) # Sasha (med en pensel) Jeg tegner en illustration til strategimønsteret # Sasha besluttede at blive elev af sasha . setTool ( PenTool ()) sasha . skriv ( u 'Nej, jeg vil hellere skrive en synopsis' ) # Sasha (med en pen) Nej, jeg vil hellere skrive en synopsisEksempel i Ruby
Implementeringseksempel kræver "interface" strategi = interface { required_methods :use } klasse StrategyOne def brug sætter "Strategy one" end implementerer Strategy end klasse StrategyTwo def brug sætter "Strategy two" end implementerer Strategi end klasse StrategyThree def brug sætter "Strategy three" end implementerer Strategi end klasse Kontekst attr_accessor : strategi def initialisere strategi @strategi = strategi slut def brugStrategi strategi . brug ende ende kontekst = kontekst . ny strategi 1 . ny kontekst . brug Strategi kontekst . strategi = strategi to . ny kontekst . brug Strategi kontekst . strategi = StrategyThree . ny kontekst . brug Strategi
Design mønstre | |
---|---|
Hoved | |
Generativ | |
Strukturel | |
Adfærdsmæssigt | |
Parallel programmering |
|
arkitektonisk |
|
Java EE skabeloner | |
Andre skabeloner | |
Bøger | |
Personligheder |