Stratégia | |
---|---|
Stratégia | |
Típusú | viselkedési |
Célja | lehetővé teszi a kontextustól függően különböző üzleti szabályok vagy algoritmusok használatát. |
esetekben érvényes | amikor ugyanazon a helyen, a rendszer (vagy környezete) aktuális állapotától függően különböző algoritmusokat kell használni |
profik |
|
Mínuszok | további osztályok létrehozása |
Kapcsolódó sablonok | Híd , Sablon módszer , Adapter |
Leírása: Tervezési minták | Igen |
A stratégia ( eng. Strategy ) egy viselkedési tervezési minta , amelyet arra terveztek, hogy meghatározza az algoritmusok családját , mindegyiket magába foglalja , és biztosítsa felcserélhetőségüket. Ez lehetővé teszi az algoritmus kiválasztását a megfelelő osztály meghatározásával. A stratégiasablon lehetővé teszi a kiválasztott algoritmus megváltoztatását az azt használó ügyfélobjektumoktól függetlenül.
Az ügyfél típusa (vagy a feldolgozott adatok típusa) szerint válassza ki a megfelelő algoritmust, amelyet alkalmazni szeretne. Ha olyan szabályt használnak, amely nem változtatható, akkor nem szükséges a stratégiai mintára hivatkozni.
Az algoritmus kiválasztási eljárás elválasztása a megvalósítástól. Ez lehetővé teszi a kontextus alapján történő kiválasztást.
Az algoritmust ( Context) használó osztály egy absztrakt osztályt ( Strategy) tartalmaz, amelynek van egy absztrakt metódusa, amely meghatározza az algoritmus meghívásának módját. Minden származtatott osztály az algoritmus egy szükséges verzióját valósítja meg.
Megjegyzés: Az algoritmushívás metódusának nem kell absztraktnak lennie, ha valamilyen alapértelmezett viselkedést kíván megvalósítani.
A Microsoft WDF architektúrája ezen a mintán alapul. Minden "driver" és "device" objektumnak van egy változtathatatlan része a rendszerbe varrva, amiben egy adott implementációban megírt mutálható rész (stratégia) van regisztrálva. A változtatható rész lehet teljesen üres, ami olyan drivert ad, amelyik nem csinál semmit, de ugyanakkor képes részt venni a PnP-ben és az energiagazdálkodásban.
Az ATL -könyvtár szálfűzési modellosztályokat tartalmaz, amelyek stratégiák (a Lock / Unlock különböző megvalósításai, amelyeket aztán a rendszer fő osztályai használnak). Ezek a stratégiák azonban statikus polimorfizmust használnak sablonparamétereken keresztül, nem pedig virtuális módszereken keresztüli dinamikus polimorfizmust.
Java példa
Megvalósítási példa // Az adott stratégiát megvalósító osztálynak implementálnia kell ezt az interfészt // A kontextus osztály ezt az interfészt használja az adott stratégiai interfész meghívására Strategy { int execute ( int a , int b ); } // Valósítsa meg az algoritmust a stratégiai interfész osztály használatával ConcreteStrategyAdd implements Strategy { public int execute ( int a , int b ) { Rendszer . ki . println ( "ConcreteStrategyAdd execute()" ); return a + b ; // Adjon összeadást a-val és b-vel } } class ConcreteStrategySubtract implements Strategy { public int execute ( int a , int b ) { Rendszer . ki . println ( "ConcreteStrategySubtract execute()" ); return a - b ; // Végezzen kivonást a-val és b-vel } } class ConcreteStrategyMultiply megvalósítja a stratégiát { public int execute ( int a , int b ) { Rendszer . ki . println ( "ConcreteStrategyMultiply's execute()" ); return a * b ; // Végezzen szorzást a-val és b-vel } } // Kontextus osztály a stratégiai interfész használatával class Context { magán stratégiai stratégia ; // Konstruktor nyilvános kontextusa () { } // Új stratégia beállítása public void setStrategy ( Stratégia stratégia ) { this . stratégia = stratégia ; } public int executeStrategy ( int a , int b ) { return stratégia . végrehajt ( a , b ); } } // Alkalmazási osztály tesztelése StrategyPélda { public static void main ( String [ ] args ) { Kontextus kontextus = new Context (); összefüggésben . setStrategy ( új ConcreteStrategyAdd ()); int eredményA = kontextus . executeStrategy ( 3 , 4 ); összefüggésben . setStrategy ( új ConcreteStrategySubtract ()); int eredményB = kontextus . executeStrategy ( 3 , 4 ); összefüggésben . setStrategy ( új ConcreteStrategyMultiply ()); int eredményC = kontextus . executeStrategy ( 3 , 4 ); Rendszer . ki . println ( "A eredmény : " + A eredmény ); Rendszer . ki . println ( "B eredmény: " + B eredmény ); Rendszer . ki . println ( "C eredmény: " + C eredmény ); } }Példa C++ nyelven
Megvalósítási példa #include <iostream> osztály Stratégia { nyilvános : virtuális ~ stratégia () {} virtuális üres használat () = 0 ; }; osztály Stratégia_1 : nyilvános Stratégia { nyilvános : void use (){ std :: cout << "Stratégia_1" << std :: endl ; } }; osztály Stratégia_2 : nyilvános Stratégia { nyilvános : void use (){ std :: cout << "Stratégia_2" << std :: endl ; } }; osztály Stratégia_3 : nyilvános Stratégia { nyilvános : void use (){ std :: cout << "Stratégia_3" << std :: endl ; } }; osztály Kontextus { védett : stratégia * működés ; nyilvános : virtuális ~ Kontextus () {} virtuális void useStrategy () = 0 ; virtual void setStrategy ( Strategy * v ) = 0 ; }; osztály Kliens : nyilvános Kontextus { nyilvános : érvénytelen useStrategy () { művelet -> használat (); } void setStrategy ( Stratégia * o ) { művelet = o ; } }; int main ( int /*argc*/ , char * /*argv*/ []) { Client customClient ; stratégia_1 str1 ; Stratégia_2 str2 ; Stratégia_3 str3 ; customClient . setStrategy ( & str1 ); customClient . useStrategy (); customClient . setStrategy ( & str2 ); customClient . useStrategy (); customClient . setStrategy ( & str3 ); customClient . useStrategy (); return 0 ; } Megvalósítási példa (sablonparaméter) #include <iostream> struct Stratégia_1 { void use (){ std :: cout << "Stratégia_1" << std :: endl ; }; }; struktúra Stratégia_2 { void use (){ std :: cout << "Stratégia_2" << std :: endl ; }; }; struktúra Stratégia_3 { void use (){ std :: cout << "Stratégia_3" << std :: endl ; }; }; sablon < classOperation > _ struct Ügyfél : nyilvános üzemeltetés { érvénytelen useStrategy () { this -> use (); } }; int main ( int /*argc*/ , char * /*argv*/ []) { Client < Strategy_1 > customClient1 ; customClient1 . useStrategy (); Client < Strategy_2 > customClient2 ; customClient2 . useStrategy (); Client < Strategy_3 > customClient3 ; customClient3 . useStrategy (); return 0 ; }Példa a C# -ban
Megvalósítási példa a rendszer használatával ; névtér DesignPatterns.Behavioral.Strategy { // Az adott stratégiát megvalósító osztálynak örökölnie kell ezt a felületet // A kontextus osztály ezt az interfészt használja az adott stratégia nyilvános interfész meghívására IStrategy { void Algorithm (); } // Első konkrét megvalósítási stratégia. public class ConcreteStrategy1 : IStrategy { public void Algorithm () { Konzol . WriteLine ( "Az 1. stratégiai algoritmus fut." ); } } // Második konkrét megvalósítási stratégia. // Annyi implementáció lehet, amennyit csak akar. public class ConcreteStrategy2 : IStrategy { public void Algorithm () { Konzol . WriteLine ( "A 2. stratégiai algoritmus fut." ); } } // Kontextus, amely a stratégiát a probléma megoldására használja. public class Kontextus { // Hivatkozás az IStrategy interfészére // lehetővé teszi az automatikus váltást az egyes implementációk között // (más szóval ez egy adott stratégia választása). privát IStrategy_stratégia ; _ // Kontextus konstruktor. // Inicializálja az objektumot a stratégiával. public Context ( IStrategy stratégia ) { _stratégia = stratégia ; } // A stratégia beállításának módszere. // Stratégia módosítására szolgál futás közben. // C#-ban rekordtulajdonságként is megvalósítható. public void SetStrategy ( IStrategy stratégia ) { _strategy = stratégia ; } // Valamilyen kontextus-funkcionalitás, amely kiválaszt // egy stratégiát, és azt használja feladatának végrehajtására. public void ExecuteOperation () { _stratégia . algoritmus (); } } // Alkalmazási osztály. // Ebben a példában kontextus kliensként működik. public static class Program { // <összefoglaló> // Program belépési pont. // </summary> public static void Main () { // Kontextus létrehozása és inicializálása az első stratégiával. Kontextus kontextus = new Context ( new ConcreteStrategy1 ()); // Kontextus-művelet végrehajtása, amely az első stratégiát használja. összefüggésben . ExecuteOperation (); // Cserélje le az első stratégiát a másodikra a kontextusban. összefüggésben . SetStrategy ( új ConcreteStrategy2 ()); // Végezze el a kontextus műveletet, amely most a második stratégiát használja. összefüggésben . ExecuteOperation (); } } }Példák a D -ben
Megvalósítási példa import std . stdio ; interface IStrategy { int Action ( int a , int b ); } class TAkiegészítés : IStrategy { public int Action ( int a , int b ) { return a + b ; } } class TSubtraction : IStrategy { public int Action ( int a , int b ) { return a - b ; } } class TContexet { privát : int a , b ; IStrategy stratégia ; public : void SetAB ( int a , int b ) { TContexet . a = a ; TContextet . b = b ; }; void SetStrategy ( IStrategy stratégia ) { TContexet . stratégia = stratégia ; } int Akció () { visszatérési stratégia . Akció ( a , b ); } } void main () { TContexet kontextus = new TContexet ; összefüggésben . SetAB ( 10 , 5 ); összefüggésben . SetStrategy ( új TAaddition ); writeln ( kontextus.Művelet ( ) ); // tizenöt összefüggésben . SetStrategy ( új TSubtraction ); writeln ( kontextus.Művelet ( ) ); // 5 }Példa Delphiben
Megvalósítási példa program Stratégia_minta ; {$APPTYPE CONSOLE} type IStrategy = interfész [ '{6105F24C-E5B2-47E5-BE03-835A894DEB42}' ] eljárás Algoritmus ; vége ; TConcreteStrategy1 = osztály ( TInterfacedObject , IStrategy ) nyilvános eljárás Algorithm ; vége ; eljárás TConcreteStrategy1 . algoritmus ; begin Writeln ( 'TConcreteStrategy1.Algoritm' ) ; vége ; típus TConcreteStrategy2 = osztály ( TInterfacedObject , IStrategy ) nyilvános eljárás Algoritmus ; vége ; eljárás TConcreteStrategy2 . algoritmus ; begin Writeln ( 'TConcreteStrategy2.Algoritm' ) ; vége ; type TContext = class private FStrategy : IStrategy ; nyilvános eljárás ContextMethod ; ingatlan stratégia : IStrategy olvas FStrategy write FStrategy ; vége ; eljárás TContext . ContextMethod ; kezdje el az FStrategy programot . algoritmus ; vége ; var Kontextus : TContext ; begin Context := TContext . létrehozni ; próbáld ki a kontextust . Stratégia := TConcreteStrategy1 . létrehozni ; Kontextus . ContextMethod ; Kontextus . Stratégia := TConcreteStrategy2 . létrehozni ; Kontextus . ContextMethod ; végül Kontextus . Ingyenes ; vége ; vége .Javascript példák
Megvalósítási példa // "interfész" stratégia függvény Stratégia () { this . exec = függvény () {}; }; // Stratégia végrehajtása // az üzenet megjelenítése a böngésző állapotsorában // (nem minden böngésző támogatja) function StrategyWindowStatus () { this . exec = function ( üzenet ) { ablak . állapot = üzenet ; }; }; StrategyWindowStatus . prototípus = új stratégia (); StrategyWindowStatus . prototípus . konstruktor = StrategyWindowStatus ; // üzenet megjelenítése előugró ablakon keresztül // (a böngésző blokkolhatja) function StrategyNewWindow () { this . exec = function ( üzenet ) { var win = ablak . open ( "" , "_blank" ); nyerj . dokumentumot . írás ( "<html>" + üzenet + "</html>" ); }; }; StratégiaNewWindow . prototípus = új stratégia (); StratégiaNewWindow . prototípus . konstruktor = StrategyNewWindow ; // üzenet megjelenítése modális ablakfüggvény használatával StrategyAlert ( ) { this . exec = function ( üzenet ) { alert ( message ); }; }; Stratégiai figyelmeztetés . prototípus = új stratégia (); Stratégiai figyelmeztetés . prototípus . konstruktor = Strategy Alert ; // Kontextus function Kontextus ( stratégia ) { this . exec = function ( üzenet ) { stratégia . exec ( üzenet ); }; } // Használat var showInWindowStatus = new Context ( new StrategyWindowStatus () ); var showInNewWindow = new Context ( new StrategyNewWindow () ); var showInAlert = new Context ( new StrategyAlert () ); showInWindowStatus . exec ( "üzenet" ); showInNew Window . exec ( "üzenet" ); showInAlert . exec ( "üzenet" );Példák PHP -ben
Megvalósítási példa <?php interface NamingStrategy { function createName ( $fájlnév ); } class ZipFileNamingStrategy implementálja a NamingStrategy-t { function createName ( $fájlnév ) { return "http://downloads.foo.bar/ { $fájlnév } .zip" ; } } class TarGzFileNamingStrategy implementálja a NamingStrategy-t { function createName ( $fájlnév ) { return "http://downloads.foo.bar/ { $fájlnév } .tar.gz" ; } } class Kontextus { private $nameingStrategy ; function __construct ( NamingStrategy $stratégia ) { $this -> namingStrategy = $stratégia ; } function execute () { $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 ()); $kontextus -> végrehajtás (); ?>Példa a Python 2.7 -ben
Megvalósítási példa osztály Emberek ( objektum ): tool = Nincs def __init__ ( self , name ): self . név = név def setTool ( self , tool ): self . szerszám = szerszám def write ( self , text ): self . eszköz . írj ( ön . név , szöveg ) class ToolBase : """ `Íróeszköz` Algoritmuscsalád """ def write ( self , name , text ): emelés NotImplementedError () osztály PenTool ( ToolBase ): """Pen""" def write ( self , name , text ): print u ' %s (toll) %s ' % ( név , szöveg ) class BrushTool ( ToolBase ): """Ecset""" def write ( self , name , text ): print u ' %s (ecsettel) %s ' % ( név , szöveg ) osztály tanuló ( emberek ): """Diák""" eszköz = PenTool () osztály Festő ( Emberek ): """Művész""" eszköz = Ecseteszköz () maxim = Diák ( u 'Maxim' ) maxim . write ( u 'Előadást írok a stratégiai mintáról' ) # Maxim (tollal) Előadást írok a Stratégia mintáról sasha = Festő ( u 'Sasha' ) sasha . write ( u 'rajzot rajzolok a stratégiai mintához' ) # Sasha (ecsettel) Rajzolok egy illusztrációt a stratégia mintához # Sasha úgy döntött, hogy Sasha tanítványa lesz . setTool ( PenTool ()) sasha . írás ( u 'Nem, inkább szinopszist írok' ) # Sasha (tollal) Nem, inkább szinopszist írokPélda Rubyban
Megvalósítási példa "interfész" szükséges stratégia = interfész { kötelező_módszerek :használat } osztály StrategyOne def use " Strategy one" end implements Strategy end osztály StrategyTwo def use " Strategy two" end implements Strategy end osztály StrategyThree def use " Strategy three" end implements Strategy end osztály Kontextus attr_accessor :strategy def inicializál stratégia @strategy = stratégia vége def useStrategy stratégia . vég végét használd kontextus = kontextus . új Strategy One . új kontextus . useStrategy összefüggésben . stratégia = stratégia kettő . új kontextus . useStrategy összefüggésben . stratégia = StrategyThree . új kontextus . useStrategy
Tervezési minták | |
---|---|
Fő | |
Generatív | |
Szerkezeti | |
Viselkedési | |
Párhuzamos programozás |
|
építészeti |
|
Java EE sablonok | |
Egyéb sablonok | |
Könyvek | |
Személyiségek |