Strategie | |
---|---|
strategie | |
Typ | behaviorální |
Účel | umožňuje používat různá obchodní pravidla nebo algoritmy v závislosti na kontextu. |
Platí v případech | když na stejném místě, v závislosti na aktuálním stavu systému (nebo jeho prostředí), musí být použity různé algoritmy |
profesionálové |
|
Mínusy | vytváření dalších tříd |
Související šablony | Most , metoda šablony , adaptér |
Popsáno v Návrhové vzory | Ano |
Strategie ( angl. Strategy ) je behaviorální návrhový vzor určený k definování rodiny algoritmů , zapouzdření každého z nich a zajištění jejich zaměnitelnosti. To vám umožní vybrat algoritmus definováním příslušné třídy. Šablona strategie umožňuje změnit vybraný algoritmus bez ohledu na objekty klienta , které jej používají.
Podle typu klienta (nebo podle typu zpracovávaných dat) vyberte vhodný algoritmus, který chcete použít. Pokud se použije pravidlo, které nepodléhá změnám, není třeba odkazovat na vzor strategie.
Oddělení postupu výběru algoritmu od jeho implementace. To umožňuje provádět výběr na základě kontextu.
Třída, která používá algoritmus ( Context), zahrnuje abstraktní třídu ( Strategy), která má abstraktní metodu, která definuje, jak je algoritmus vyvolán. Každá odvozená třída implementuje jednu požadovanou verzi algoritmu.
Poznámka: Pokud má být implementováno nějaké výchozí chování, metoda volání algoritmu nemusí být abstraktní.
Architektura Microsoft WDF je založena na tomto vzoru. Každý objekt „ovladač“ a „zařízení“ má v systému všitou neměnnou část, ve které je registrována proměnlivá část (strategie) zapsaná v konkrétní implementaci. Proměnlivá část může být zcela prázdná, což dá ovladač, který nic nedělá, ale zároveň je schopen se podílet na PnP a správě napájení.
Knihovna ATL obsahuje sadu tříd modelu vláken, které jsou strategiemi (různé implementace Lock / Unlock, které pak používají hlavní třídy systému). Tyto strategie však využívají spíše statický polymorfismus prostřednictvím parametru šablony než dynamický polymorfismus prostřednictvím virtuálních metod.
Příklad Java
Příklad implementace // Třída, která implementuje konkrétní strategii, musí implementovat toto rozhraní // Třída kontextu používá toto rozhraní k vyvolání rozhraní konkrétní strategie Strategy { int execute ( int a , int b ) ; } // Implementujte algoritmus pomocí třídy rozhraní strategie ConcreteStrategyAdd implements Strategy { public int vykonat ( int a , int b ) { System . ven . println ( "Vyvolána funkce ConcreteStrategyAdd's execute()" ); vrátit a + b ; // Proveďte sčítání pomocí a a b } } class ConcreteStrategySubtract implementuje strategii { public int vykonat ( int a , int b ) { System . ven . println ( "Volaná metoda ConcreteStrategySubtract's execute()" ); vrátit a - b ; // Proveďte odčítání s aab } } class ConcreteStrategyMultiply implementuje strategii { public int vykonat ( int a , int b ) { System . ven . println ( "Calected ConcreteStrategyMultiply's execute()" ); vrátit a * b ; // Proveďte násobení pomocí a a b } } // Kontextová třída používající strategii rozhraní class Context { soukromá strategie ; _ // Konstruktor public Context () { } // Nastavení nové strategie public void setStrategy ( Strategie strategy ) { this . strategie = strategie ; } public int vykonatStrategie ( int a , int b ) { strategie návratu . provést ( a , b ); } } // Testování třídy aplikace StrategyExample { public static void main ( String [] args ) { Kontext kontextu = new Context (); kontextu . setStrategy ( new ConcreteStrategyAdd ()); int vysledekA = kontext . vykonatStrategie ( 3 , 4 ); kontextu . setStrategy ( new ConcreteStrategySubtract ()); int vysledekB = kontext . vykonatStrategie ( 3 , 4 ); kontextu . setStrategy ( new ConcreteStrategyMultiply ()); int vysledekC = kontext . vykonatStrategie ( 3 , 4 ); Systém . ven . println ( "Výsledek A: " + výsledek A ); Systém . ven . println ( "Výsledek B: " + výsledek B ); Systém . ven . println ( "Výsledek C: " + výsledek C ); } }Příklad v C++
Příklad implementace #include <iostream> třída Strategie { veřejnost : virtuální ~ Strategie () {} virtuální void použití () = 0 ; }; třída Strategie_1 : veřejná Strategie { veřejnost : void use (){ std :: cout << "Strategie_1" << std :: endl ; } }; třída Strategie_2 : veřejná Strategie { veřejnost : void use (){ std :: cout << "Strategie_2" << std :: endl ; } }; třída Strategie_3 : veřejná Strategie { veřejnost : void use (){ std :: cout << "Strategie_3" << std :: endl ; } }; Kontext třídy { chráněno : strategie * provoz ; veřejnost : virtuální ~ kontext () {} virtual void useStrategy () = 0 ; virtuální void setStrategy ( Strategie * v ) = 0 ; }; třída Klient : veřejný kontext { veřejnost : void useStrategy () { operace -> použití (); } void setStrategy ( Strategie * o ) { operace = o ; } }; int main ( int /*argc*/ , char * /*argv*/ []) { Klient customClient ; strategie_1 str1 ; Strategie_2 str2 ; Strategie_3 str3 ; customClient . setStrategy ( & str1 ); customClient . useStrategy (); customClient . setStrategy ( & str2 ); customClient . useStrategy (); customClient . setStrategy ( & str3 ); customClient . useStrategy (); návrat 0 ; } Příklad implementace (parametr šablony) #include <iostream> struct Strategy_1 { void use (){ std :: cout << "Strategie_1" << std :: endl ; }; }; struct Strategy_2 { void use (){ std :: cout << "Strategie_2" << std :: endl ; }; }; struct Strategy_3 { void use (){ std :: cout << "Strategie_3" << std :: endl ; }; }; šablona < classOperation > _ struct Klient : veřejný provoz { void useStrategy () { toto -> použít (); } }; int main ( int /*argc*/ , char * /*argv*/ []) { Klient < Strategie_1 > customClient1 ; customClient1 . useStrategy (); Klient < Strategie_2 > customClient2 ; customClient2 . useStrategy (); Klient < Strategie_3 > customClient3 ; customClient3 . useStrategy (); návrat 0 ; }Příklad v C#
Příklad implementace pomocí System ; jmenný prostor DesignPatterns.Behavioral.Strategy { // Třída, která implementuje konkrétní strategii, musí toto rozhraní zdědit // Třída kontext používá toto rozhraní k vyvolání konkrétní strategie public interface ISstrategy { void Algorithm (); } // První konkrétní implementační strategie. public class ConcreteStrategy1 : IStrategy { public void Algorithm () { Console . WriteLine ( "Strategický algoritmus 1 běží." ); } } // Druhá konkrétní implementační strategie. // Implementací může být tolik, kolik chcete. public class ConcreteStrategy2 : IStrategy { public void Algorithm () { Console . WriteLine ( "Strategický algoritmus 2 běží." ); } } // Kontext, který používá strategii k řešení svého problému. public class Context { // Odkaz na rozhraní ISstrategy // umožňuje automatické přepínání mezi konkrétními implementacemi // (jinými slovy jde o volbu konkrétní strategie). private ISstrategy_strategy ; _ // Konstruktor kontextu. // Inicializuje objekt se strategií. public Context ( Strategy strategy ) { _strategy = strategie ; } // Metoda pro nastavení strategie. // Používá se ke změně strategie za běhu. // V C# to může být také implementováno jako vlastnost záznamu. public void SetStrategy ( strategie ISstrategy ) { _strategy = strategie ; } // Některé kontextové funkce, které volí // strategii a používají ji ke splnění svého úkolu. public void ExecuteOperation () { _strategy . algoritmus (); } } // Třída aplikace. // V tomto příkladu funguje jako kontextový klient. public static class Program { // <summary> // Vstupní bod programu. // </summary> public static void Main () { // Vytvořte kontext a inicializujte jej pomocí první strategie. Kontext kontextu = new Context ( new ConcreteStrategy1 ()); // Proveďte kontextovou operaci, která používá první strategii. kontextu . ExecuteOperation (); // Nahraďte v kontextu první strategii druhou. kontextu . SetStrategy ( new ConcreteStrategy2 ()); // Proveďte kontextovou operaci, která nyní používá druhou strategii. kontextu . ExecuteOperation (); } } }Příklady v D
Příklad implementace import std . stdio ; interface ISstrategie { int Akce ( int a , int b ); } class TAddition : ISstrategie { public int Akce ( int a , int b ) { return a + b ; } } class TOdečtení : IStrategie { public int Akce ( int a , int b ) { return a - b ; } } class TContexet { private : int a , b ; strategie ; strategie ; public : void SetAB ( int a , int b ) { TContexet . a = a ; TContextet . b = b ; }; void SetStrategy ( strategie ISstrategy ) { TContexet . strategie = strategie ; } int Akce () { strategie návratu . Akce ( a , b ); } } void main () { TContexet context = new TContexet ; kontextu . SetAB ( 10,5 ) ; _ kontextu . SetStrategy ( nový TAddition ); writeln ( kontext.Akce ( ) ); // patnáct kontextu . SetStrategy ( new TSuttraction ); writeln ( kontext.Akce ( ) ); // 5 }Příklad v Delphi
Příklad implementace program Strategie_vzor ; {$APPTYPE KONZOLE} type ISstrategy = interface [ '{6105F24C-E5B2-47E5-BE03-835A894DEB42}' ] procedure Algorithm ; konec ; TConcreteStrategy1 = class ( TInterfacedObject , ISstrategy ) veřejná procedura Algoritmus ; konec ; postup TConcreteStrategy1 . algoritmus ; begin Writeln ( 'TConcreteStrategy1.Algorithm' ) ; konec ; typ TConcreteStrategy2 = class ( TInterfacedObject , ISstrategy ) veřejná procedura Algoritmus ; konec ; postup TConcreteStrategy2 . algoritmus ; begin Writeln ( 'TConcreteStrategy2.Algorithm' ) ; konec ; type TContext = class private FStrategy : IStrategy ; veřejné řízení ContextMethod ; vlastnost Strategie : ISstrategie číst FStrategie zápis FStrategie ; konec ; postup TContext . ContextMethod ; začít FStrategy . algoritmus ; konec ; var Context : TContext ; begin Context := TContext . vytvořit ; zkuste kontext . Strategie := TConcreteStrategy1 . vytvořit ; Souvislosti . ContextMethod ; Souvislosti . Strategie := TConcreteStrategy2 . vytvořit ; Souvislosti . ContextMethod ; konečně Kontext . zdarma ; konec ; konec .Příklady Javascriptu
Příklad implementace // "rozhraní" Strategie funkce Strategie () { toto . exec = funkce () {}; }; // implementovat strategii // zobrazí zprávu ve stavovém řádku prohlížeče // (nepodporováno všemi prohlížeči) function StrategyWindowStatus () { this . exec = funkce ( zpráva ) { okno . stav = zpráva ; }; }; StrategyWindowStatus . prototyp = nová strategie (); StrategyWindowStatus . prototyp . konstruktor = StrategyWindowStatus ; // zobrazit zprávu přes vyskakovací okno // (může být blokováno prohlížečem) function StrategyNewWindow () { this . exec = funkce ( zpráva ) { var win = okno . otevřít ( "" , "_blank" ); vyhrát _ dokument . napište ( "<html>" + zpráva + "</html>" ); }; }; StrategieNovéOkno . prototyp = nová strategie (); StrategieNovéOkno . prototyp . konstruktor = StrategyNewWindow ; // zobrazit zprávu pomocí funkce modálního okna StrategyAlert () { this . exec = funkce ( zpráva ) { upozornění ( zpráva ); }; }; Strategické upozornění . prototyp = nová strategie (); Strategické upozornění . prototyp . konstruktor = Strategy Alert ; // Kontext funkce Kontext ( strategie ) { this . exec = funkce ( zpráva ) { strategie . exec ( zpráva ); }; } // Použití var showInWindowStatus = new Context ( new StrategyWindowStatus () ); var showInNewWindow = new Context ( new StrategyNewWindow () ); var showInAlert = new Context ( new StrategyAlert () ); showInWindowStatus . exec ( "zpráva" ); showInNewWindow . exec ( "zpráva" ); showInAlert . exec ( "zpráva" );Příklady v PHP
Příklad implementace <?php interface NamingStrategy { function createName ( $filename ); } class ZipFileNamingStrategy implementuje NamingStrategy { function createName ( $filename ) { return "http://downloads.foo.bar/ { $filename } .zip" ; } } class TarGzFileNamingStrategy implementuje NamingStrategy { function createName ( $filename ) { return "http://downloads.foo.bar/ { $filename } .tar.gz" ; } } class Context { private $namingStrategy ; function __construct ( Strategie názvů $strategie ) { $this -> Strategie názvů = $strategie ; } funkce vykonat () { $url [] = $this -> namingStrategy -> createName ( "Calc101" ); $url [] = $this -> namingStrategy -> createName ( "Stat2000" ); return $url ; } } if ( strstr ( $_SERVER [ "HTTP_USER_AGENT" ], "Win" )) $context = new Context ( new ZipFileNamingStrategy ()); else $context = new Context ( new TarGzFileNamingStrategy ()); $kontext -> vykonat (); ?>Příklad v Pythonu 2.7
Příklad implementace třída Lidé ( objekt ): nástroj = Žádný def __init__ ( self , jméno ): self . jméno = jméno def setTool ( self , tool ): self . nástroj = nástroj def psát ( self , text ): self . nástroj . napsat ( vlastní jméno , text ) _ class ToolBase : """ `Nástroj pro zápis` Rodina algoritmů """ def write ( self , name , text ): raise NotImplementedError () class PenTool ( ToolBase ): """Pero""" def write ( self , name , text ): print u ' %s (pero) %s ' % ( name , text ) class BrushTool ( ToolBase ): """Štětec""" def write ( self , name , text ): print u ' %s (se štětcem) %s ' % ( name , text ) třída Student ( Lidé ): nástroj """Student""" = PenTool () class Painter ( People ): """Umělec""" nástroj = BrushTool () maxim = Student ( u 'Maxim' ) maxim . napište ( u 'Píšu přednášku o vzoru Strategie' ) # Maxim (perem) Píšu přednášku o vzoru Strategie sasha = Malíř ( u 'Sasha' ) sasha . napište ( u 'Kreslím ilustraci vzoru Strategie' ) # Sasha (štětcem) Kreslím ilustraci vzoru Strategie # Sasha se rozhodl stát studentem sasha . setTool ( PenTool ()) sasha . pište ( u 'Ne, radši bych napsal synopsi' ) # Sasha (perem) Ne, radši bych napsal souhrnPříklad v Ruby
Příklad implementace vyžadovat "rozhraní" strategie = rozhraní { požadované_metody :použití } class StrategyOne def use klade "Strategie jedna" konec implementuje Strategie konec class StrategyTwo def use klade "Strategie dva" end implementuje Strategy end class StrategyThree def use klade "Strategie tři" end implementuje Strategy end class Kontext attr_accessor :strategie def inicializovat strategii @strategy = strategie end def useStrategy strategy . použít konec konec kontext = kontext . nová strategie jedna . nový kontext . useStrategy kontextu . strategie = strategie dvě . nový kontext . useStrategy kontextu . strategie = StrategieTři . nový kontext . useStrategy
Designové vzory | |
---|---|
Hlavní | |
Generativní | |
Strukturální | |
Behaviorální | |
Paralelní programování |
|
architektonický |
|
Java EE šablony | |
Jiné šablony | |
knihy | |
Osobnosti |