Strategia (patrono de designo)

In ingenieria de programmatura, le patrono **strategia** es un patrono de designo (*design pattern*) de typo comportamental. Gratias a illo algorithmos pote esser selectionate in tempore de execution secundo certe conditiones.

Le patrono strategia servi pro situationes ubi il es necessari de permutar dynamicamente le algorithmos usate in un application. Le patrono strategia consiste a definir un famiglia de algorithmos, incapsular cata un de illos como objecto, e render illos intercambiabile. Iste patrono permitte que le algorithmos cambia independentemente del clientes qui lo usa.

## Uso
Quando un objecto pote effectuar plure tractamentos differente, dependente de un variabile o de un stato.

## Exemplo in C++

```cpp
#include <iostream>
using namespace std;

class IStrategia
{
public:
  virtual void executar() = 0; 
    // executar() es un function virtual pur
    // e de iste facto IStrategia es un classe abstracte
    // in altere parolas un classe que non pote esser instantiate
};

class AlgorithmoA : public IStrategia
{
public:
  void executar()
  {
    cout << "Tractamento A" << endl;
  }
};

class AlgorithmoB : public IStrategia
{
public:
  void executar()
  {
    cout << "Tractamento B" << endl;
  }
};

class AlgorithmoC : public IStrategia
{
public:
  void executar()
  {
    cout << "Tractamento C" << endl;
  }
};

class Elemento
{
private:
  IStrategia* strategia;

public:
  Elemento(IStrategia* strategia) : strategia(strategia)
  {
  }

  void executar()
  {
    strategia->executar();
  }
};

int main()
{
  AlgorithmoA algoA;
  AlgorithmoB algoB;
  AlgorithmoC algoC;

  Elemento elementoA{&algoA};
  Elemento elementoB{&algoB};
  Elemento elementoC{&algoC};

  elementoA.executar();     // Le elemento A va effectuar le tractamento A
  elementoB.executar();     // Le elemento B va effectuar le tractamento B
  elementoC.executar();     // Le elemento C va effectuar le tractamento C
}
```

Vide classe abstracte e function virtual pur.

## Exemplo in C#
Ideas simile duce a un realisation per interfacie.

Le objecto qui debe haber un strategia adaptabile al execution implementa le interfacie IStrategia: le mesme interfacie que le altere objectos. Le objecto principal delega le execution del carga a un altere objecto membro qui implementa IStrategia.

Le objecto membro essente declarate in le classe como un interfacie, su implementation importa pauco, on pote consequentemente cambiar de strategia durante le execution. Iste maniera de agir se approxima al Principio del injection de dependentia.

```csharp
using System;

/// <summary> Le maniera como le grande general guidara su truppas</summary>
interface IStrategia 
{
  void Executar();
}

/// <summary> Iste grande homine qui facera selectiones decisive </summary>
class SeniorDelGuerra 
{

/// <summary> un strategia generic </summary>
  IStrategia _strategia;

  /// <summary> como cambiar de strategia </summary>
  public IStrategia Strategia 
  { 
    set { _strategia = value; } 
  }

  /// <summary> delegation del carga </summary>
  public void PrenderLeCitate() 
  {
    _strategia.Executar();
  }
}

class DestruerLePonteLevatoriDeFacie : IStrategia 
{
  public void Executar() 
  {
    Console.WriteLine("Prender le citate de facie per destruer le ponte levatori.");
  }
}

class PassarPerLeFacieNord : IStrategia 
{
  public void Executar() 
  {
    Console.WriteLine("Prender le citate per ascender le muralia nord.");
  }
}

class AttenderQueLeCitateSeRende : IStrategia 
{
  public void Executar() 
  {
    Console.WriteLine("Attender que il ha nihil plus a mangiar in le citate "
      + "e que tote le mundo mori de fame.");
  }
}

class MaritarSeConLeCosinaDelDuce : IStrategia 
{
  public void Executar() 
  {
    Console.WriteLine("Organisar un maritage con le cosina del Duce "
      + "alora que illa rejunge le citate de retorno del Baleares "
      + "e invitar tote le citate a un grande festa.");
  }
}

/// <summary> Differente situationes </summary>
enum Meteo 
{
  IlFaceBelleTempore,
  IlHaBruma,
  IlFaceTroppoDeCalorProLaborar,
  IlPluve
}

class Program 
{
  static void Main() 
  {
    // nostre actor
    var kevin = new SeniorDelGuerra();

    // le hasardos del systema
    var meteo = (Meteo)(new Random().Next(0, 3));

    // un ligation tardive
    switch (meteo) 
    {
      case Meteo.IlFaceBelleTempore: 
        kevin.Strategia = new DestruerLePonteLevatoriDeFacie();
        break;
      case Meteo.IlHaBruma:
        kevin.Strategia = new PassarPerLeFacieNord(); 
        break;
      case Meteo.IlFaceTroppoDeCalorProLaborar:
        kevin.Strategia = new AttenderQueLeCitateSeRende(); 
        break;
      case Meteo.IlPluve:
        kevin.Strategia = new MaritarSeConLeCosinaDelDuce(); 
        break;
      default: 
        throw new Exception("Nah, senior del guerra non es un "
          + "occupation tanto fascinante, in fin: tu decide vader "
          + "elevar capras in Périgord.");
    }

    // un execution al parve cibollas
    kevin.PrenderLeCitate();
  }
}
```


## Exemplo in Delphi

Source: Delphi GOF Design Patterns (CodePlex)


```delphi
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.

{ file projecto }
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.
```