Strateji (tasarım deseni)

Bu makale yayınlanmamış çalışma veya doğrulanmamış ifadeler (ekim 2014).

Referans ekleyerek veya yayınlanmamış içeriği kaldırarak yardımcı olabilirsiniz.

Olarak yazılım mühendisliğinde , patron stratejisi a, desen (desen) , belirli koşullar altında icra süre boyunca anında seçilebileceği yoluyla davranış algoritmaları.

Strateji tasarım modeli, bir uygulamada kullanılan algoritmaların dinamik olarak değiştirilmesinin gerekli olduğu durumlar için kullanışlıdır. Strateji modelinin, bir algoritma ailesini tanımlama, her birini bir nesne olarak kapsülleme ve birbirinin yerine geçebilir hale getirme araçları sağlaması amaçlanmıştır. Bu patron, kullanan müşterilerden bağımsız olarak algoritmaların değişmesine izin verir.

kullanım

Bir nesne, bir değişkene veya duruma bağlı olarak birkaç farklı işlem uygulayabildiğinden.

Yapısı

C ++ 'da örnek

#include <iostream> #include <memory> // IStrategie est l’interface permettant d’exécuter un algorithme class IStrategie { public: void execute() { process(); } // NVI virtual ~IStrategie() = default; // Héritage, donc destructeur public virtuel private: virtual void process() = 0; // IStrategie::process() est une fonction virtuelle pure // et de ce fait IStrategie est une classe abstraite // autrement dit une classe qui ne peut être instanciée }; class AlgorithmeA : public IStrategie { private: // Chaque Algorithme redéfinit la façon de procéder void process() override { std::cout << "Traitement A" << std::endl; } }; class AlgorithmeB : public IStrategie { private: void process() override { std::cout << "Traitement B" << std::endl; } }; class AlgorithmeC : public IStrategie { private: void process() override { std::cout << "Traitement C" << std::endl; } }; // Contexte est la classe visible par le client. // Elle fait le lien entre les demandes du client et l’algorithme (ou les algorithmes) à utiliser. class Contexte final { private: std::unique_ptr<IStrategie> strategie; public: Contexte(std::unique_ptr<IStrategie> new_strategie) : strategie(std::move(new_strategie)) {} void execute() { strategie->execute(); } void setAlgorithme(std::unique_ptr<IStrategie> new_strategie) { strategie = std::move(new_strategie); } }; int main() { Contexte contexte(std::make_unique<AlgorithmeA>()); contexte.execute(); // Le contexte va effectuer le traitement A contexte.setAlgorithme(std::make_unique<AlgorithmeB>()); contexte.execute(); // Le contexte va effectuer le traitement B contexte.setAlgorithme(std::make_unique<AlgorithmeC>()); contexte.execute(); // Le contexte va effectuer le traitement C return 0; }

Bkz soyut sınıf ve saf sanal fonksiyon .

C # Örneği

Benzer fikirler, arayüzleri kullanarak gerçekleştirmeye götürür.

Çalışma zamanında uyarlanabilir bir stratejiye sahip olması gereken nesne, IStrategie'yi uygular: diğer nesnelerle aynı arabirim. Ana nesne, görevin yürütülmesini IStrategie'yi uygulayan başka bir üye nesneye devreder.

Üye nesne sınıfta bir arabirim olarak bildiriliyor, uygulaması önemli değil, bu nedenle stratejiyi çalışma zamanında değiştirebiliriz. İşleri bu şekilde yapmanın , bağımlılık aşılama ilkesine benzer .

using System; /// <summary> La manière dont le grand général guidera ses troupes</summary> interface IStrategie { void MettreEnOeuvre(); } /// <summary> Ce grand homme qui fera bientôt des choix décisifs </summary> class SeigneurDeLaGuerre { /// <summary> une stratégie générique </summary> IStrategie _strategie; /// <summary> comment changer de stratégie </summary> public IStrategie Strategie { set { _strategie = value; } } /// <summary> délégation de la tâche </summary> public void PrendreLaVille() { _strategie.MettreEnOeuvre(); } } class DéfoncerLePontLevisDeFace : IStrategie { public void MettreEnOeuvre() { Console.WriteLine("Prendre la ville de face en défonçant le pont-levis."); } } class PasserParLaFaceNord : IStrategie { public void MettreEnOeuvre() { Console.WriteLine("Prendre la ville en escaladant la muraille nord."); } } class AttendreQueLaVilleSeRende : IStrategie { public void MettreEnOeuvre() { Console.WriteLine("Attendre qu'il n'y ait plus rien à manger en ville " + "et que tout le monde meure de faim."); } } class SeMarierAvecLaCousineDuDuc : IStrategie { public void MettreEnOeuvre() { Console.WriteLine("Organiser un mariage avec la cousine du Duc " + "alors qu'elle rejoint la ville de retour des Baléares " + "et inviter toute la ville à une grande fête."); } } /// <summary> Différentes situations </summary> enum Météo { IlFaitBeau, IlYADuBrouillard, IlFaitTropChaudPourTravailler, IlPleut } class Program { static void Main() { // notre acteur var kevin = new SeigneurDeLaGuerre(); // les aléas du système var météo = (Météo)(new Random().Next(0, 4)); // une liaison tardive switch (météo) { case Météo.IlFaitBeau: kevin.Strategie = new DéfoncerLePontLevisDeFace(); break; case Météo.IlYADuBrouillard: kevin.Strategie = new PasserParLaFaceNord(); break; case Météo.IlFaitTropChaudPourTravailler: kevin.Strategie = new AttendreQueLaVilleSeRende(); break; case Météo.IlPleut: kevin.Strategie = new SeMarierAvecLaCousineDuDuc(); break; default: throw new Exception("Nan finalement seigneur de la guerre c'est " + "pas cool comme job : vous décidez d'aller cueillir " + "des champignons dans le Périgord."); } // une exécution aux petits oignons kevin.PrendreLaVille(); } }

Delphi'de Örnek

kaynak: Delphi GOF Tasarım Modelleri (CodePlex)

unit strategy; interface type TContext = class; IStrategy = interface ['{7F63C143-98D0-4B8C-A02B-894D145BB745}'] function Move(c: TContext): integer; end; TStrategy1 = class(TInterfacedObject, IStrategy) public function Move(c: TContext): integer; end; TStrategy2 = class(TInterfacedObject, IStrategy) public function Move(c: TContext): integer; end; TContext = class private FStrategy: IStrategy; FCounter: integer; public constructor Create(counter: integer); function Algorithm: integer; procedure SetStrategy(s: IStrategy); property counter: integer read FCounter write FCounter; end; implementation { TStrategy1 } function TStrategy1.Move(c: TContext): integer; begin c.Counter := c.Counter + 1; Result := c.Counter; end; { TStrategy2 } function TStrategy2.Move(c: TContext): integer; begin c.Counter := c.Counter - 1; Result := c.Counter; end; { TContext } function TContext.Algorithm: integer; begin Result := FStrategy.Move(Self) end; constructor TContext.Create(counter: integer); begin inherited; FCounter := counter; FStrategy := TStrategy1.Create; end; procedure TContext.SetStrategy(s: IStrategy); begin FStrategy := s; end; end. { fichier projet } program Behavioral.strategy.Pattern; {$APPTYPE CONSOLE} uses SysUtils, strategy in 'strategy.pas'; var context: TContext; i: integer; begin try context := TContext.Create(12); context.SetStrategy(TStrategy1.Create); try for i := 0 to 30 do begin if i = 15 then begin WriteLn(#10 + '|| '); context.SetStrategy(TStrategy2.Create); end; Write(IntToStr(context.Algorithm) + ' '); end; ReadLn; finally context.Free; end; except on E:Exception do Writeln(E.Classname, ': ', E.Message); end; end.

Smalltalk örneği

Burada, bir arabanın davranışı sürüş stratejisine bağlı olarak değiştirilebilir:

ConduiteSport>>avance Transcript show: 'à fond à fond'; cr ConduiteTranquille>>avance Transcript show: 'on roule doucement'; cr Voiture>>modeSport strategieConduite := ConduiteSport new Voiture>>modeTranquille strategieConduite := ConduiteTranquille new Voiture>>avance strategieConduite avance

Bu nedenle yazabiliriz:

maVoiture := Voiture new. maVoiture modeSport. maVoiture avance. "Affiche 'à fond à fond'" maVoiture modeTranquille. maVoiture avance. "Affiche 'on roule doucement'"

Java örneği

Flying () ve quacking () 'in Duck sınıfının ördekten ördeğe değişen bölümleri olduğunu biliyoruz.

Bu davranışları Duck sınıfından ayırmak için, bu iki yöntemi sınıftan çıkarıyoruz ve her davranışı temsil edecek yeni bir sınıflar kümesi oluşturuyoruz.


Duck , BehaviorVol ve BehaviorCancan arabirim türünün özniteliklerini kullanır (ördeğin "gürültüsü").

PerformVol () ve performCancan () yöntemlerinin kodunu kapsülleyen bu arabirimlerdir .

Strateji tasarım modeline göre, onları birbirinin yerine geçebilir hale getirmek için kapsüllemek istediğimiz bu yöntemlerdir.

Bu yöntemleri birbirinin yerine kullanılabilir hale getirme arzumuza rağmen:

  • hala ortak tutmak istediğimiz başka yöntemler var: burada swim () yöntemi .
  • ve seçilen uygulamaya özgü olmasını istediğimiz diğer yöntemler: burada display () yöntemi .
public abstract class Canard { ComportementVol comportementVol; ComportementCancan comportementCancan; public Canard() { } public abstract void afficher(); public void effectuerVol() { comportementVol.voler(); } public void effectuerCancan() { comportementCancan.cancaner(); } public void nager() { System.out.println("Tous les canards flottent, même les leurres!"); } public void setComportementVol(ComportementVol comportementVol) { this.comportementVol = comportementVol; } public void setComportementCancan(ComportementCancan comportementCancan) { this.comportementCancan = comportementCancan; } }

Şimdi, bu uzmanlaşma olacak Ördek sınıfı devralma iki yeni sınıflar uygulayarak Duck . Colvert sınıfı :

public class Colvert extends Canard { public Colvert() { comportementVol = new VolerAvecDesAiles(); comportementCancan = new Cancan(); } public void afficher() { System.out.println("Je suis un vrai colvert"); } }

Ve PrototypeCanard sınıfı  :

public class PrototypeCanard extends Canard { public PrototypeCanard() { comportementVol = new NePasVoler(); comportementCancan = new Cancan(); } public void afficher() { System.out.println("Je suis un prototype de canard"); } }

Davranış Uçuş özelliği olan sınıf uygulayan bir amacı, davranış Uçuş arabirimi .

public interface ComportementVol { public void voler(); }

' Özelliği, QuackBehavior olan sınıfının uyguladığı arayüzü bir amacı QuackBehavior.

public interface ComportementCancan { public void cancaner() ; }

Her iki arabirimi de uygulayan yeni bir sınıf oluşturarak gerekenden çok FlyBehavior ve QuackBehavior belirtmek mümkündür . Bu durumda, fly () ' yi uygulamak bu sınıflara kalmıştır ...

public class VolerAvecDesAiles implements ComportementVol { public void voler() { System.out.println("Je vole !!"); } } public class NePasVoler implements ComportementVol { public void voler() { System.out.println("Je ne sais pas voler"); } }

... ve istenen davranışı belirtmek için quack () .

public class Cancan implements ComportementCancan { public void cancaner() { System.out.println("Cancan"); } }


Notlar ve referanslar

  1. Freeman, Eric, 1965- , Freeman, Elisabeth. , Sierra, Kathy. ve Bates, Bert. ( İngilizceden çevrilmiştir  ), Tasarım kalıpları, önce kafa , Beijing / Cambridge / Paris vb., O'Reilly,2005, 637  s. ( ISBN  2-84177-350-7 ve 978-2-84177-350-3 , OCLC  181354957 , çevrimiçi okuyun )