C# 
-  Padrão Comportamental 
Gof - Strategy
    ![]()  | 
    Neste artigo vou apresentar o padrão comportamental Gof Strategy. | 
O padrão de design 
Strategy define uma família de algoritmos, encapsula cada um e os torna 
intercambiáveis. 

Vamos entender o 
que isso significa:
- Família de algoritmos: 
Isso significa que este padrão fornece um conjunto de algoritmos usando um dos 
quais em tempo de execução você pode obter a saída desejada.
- Encapsula cada um :  
Este padrão permite que você coloque seus algoritmos em classes diferentes 
(encapsulando-os)
- Torna o algoritmo intercambiável:  
A beleza do padrão Strategy é que podemos selecionar em tempo de execução qual 
algoritmo queremos aplicar ao nosso objeto e também substituí-los um pelo outro.

Dessa 
forma esse padrão permite que o algoritmo varie independentemente dos clientes 
que o utilizam. E assim podemos dizer que o objetivo deste padrão é encapsular 
um algoritmo em um objeto e fornecer interfaces genéricas o suficiente para 
suportar uma variedade de algoritmos e facilitar a escolha e troca (intercâmbio) 
de algoritmos criados com uma mesma função.  
Este padrão é frequentemente usado em várias estruturas para fornecer aos usuários uma 
maneira de alterar o comportamento de uma classe sem estendê-la.
Strategy : Exemplo
Vejamos um exemplo simples para entendermos a atuação do padrão.
Vamos supor que 
temos uma tarefa a resolver  :

E que descobrimos que podemos ter 3 soluções para resolver a tarefa:
 Solucão1 , 2 e 3
Em cada solução temos representados um comportamento e um algoritmo diferente. 
Aqui temos a família de algoritmo encapsulada cada um em sua classe.
De acordo com o padrão Strategy,  a solução 
que deverá ser usada  será decidida pelo cliente apenas em tempo de 
execução.  Assim, o cliente decidirá se usará a 
Solução 1 , 2 ou 3 para realizar a tarefa em tempo de execução.
Então temos que as 
soluções que representam a família de algoritmos encapsuladas cada uma em sua 
classe
podem ser intercambiáveis e podemos selecionar qual usar em tempo de 
execução substituindo um pelo outro.
Tomando um exemplo 
do mundo real, temos que os meios de transporte para um aeroporto são um exemplo 
do padrão Strategy ou Estratégia.
Existem várias opções de transporte que podem ser usadas neste caso :
- pegar um ônibus;
- usar um carro;
- pegar um táxi;

Qualquer um desses meios de transporte leva o viajante ao aeroporto e pode ser 
usado de forma intercambiável. 
O viajante deve escolher a Estratégia com base nas compensações entre custo, 
conveniência e tempo.
Diagrama UML
O diagrama UML do padrão Strategy segundo o Gof apresenta os seguintes participantes

1- Strategy
- Define a 
Interface comum para todas as classes (variações concretas) que definem os 
diversos comportamentos esperados;
- O Context usa esta interface para chamar o 
algoritmo definido por um ConcreteStrategy;
2- ConcreteStrategy -
- Classes que 
implementam os algoritmos que devem atender a cada contexto;
3- Context - 
-Classe onde os 
objetos ConcreteStrategy serão instanciados;
-Mantém uma referência para o objeto Strategy
Assim temos aqui:
- Uma interface chamada Strategy que define um contrato a ser implementado;
- As classes de estratégia concretas A,B e C que implementam essa interface;
- Por último, a classe Context através da qual 
podemos usar diferentes estratégias concretas em tempo de execução.
As classes Context instanciam os objetos Strategy e invocam o método
AlgorithmInterface passando os parâmetros 
solicitados;
A interface Strategy decide qual das implementações 
ConcreteStrategy deve atender a chamada;
Quando podemos usar o padrão
Podemos usar o padrão Strategy quando :
- Muitas classes 
relacionadas diferem apenas em seu comportamento;
- Precisamos usar diferentes variantes de um algoritmo;
- Um algoritmo usa dados que os clientes não deveriam conhecer; Neste caso 
usamos o padrão Strategy para evitar a exposição de estruturas de dados 
complexas e específicas do algoritmo.
- Uma classe define muitos comportamentos e eles aparecem como várias instruções 
condicionais em suas operações;
Aqui em vez de muitos condicionais, podemos mover os condicionais relacionados 
para sua própria classe de Estratégia.
- Você tem um método que é aplicado em diferentes situações nas quais é exigido 
um comportamento específico;
Vantagens do padrão
Como vantagens deste padrão temos que :
-Facilita e 
simplifica os testes de unidade pois cada algoritmo tem sua classe e pode ser 
testado pela sua própria interface;
- Evita o uso de condicionais, tornando o código mais flexível e fácil de 
estender;
- É aderente aos princípios de alta coesão e baixo acoplamento;
- Orienta a programar para uma interface e usar a composição;
Desvantagem
E como desvantagem 
podemos citar que :
- Ocorre um aumento no número de classes;
-A aplicação deve estar ciente de todas as estratégias para poder selecionar a 
estratégia certa para a situação certa;
Aplicação prática do padrão
Para mostrar um 
exemplo de implementação deste padrão vamos supor que eu quero poder compactar 
arquivos, e, para isso eu tenho 3 soluções que são as estratégias que eu posso 
usar para realizar essa tarefa.
Assim eu posso compactar arquivos usando o formato Rar, 
o formato ZIP e o formato GZip.

Assim vamos usar o padrão Strategy para definir como podemos implementar 3 
algoritmos de forma que possamos escolher o formato em tempo de execução.
Implementação prática
Levando em conta este cenário vamos implementar o padrão Strategy usando uma aplicação Console .NET Core (.NET 5.0) criada no VS 2019 Community.
A seguir temos o diagrama de classes obtido a partir do VS 2019 na implementação do padrão:

A seguir temos o código usado na implementação:
1- A interface ICompressao
| 
		  
		 //Strategy public interface ICompressao { void ComprimirArquivo(string nomeArquivo); }  | 
	
2- A classe CompressaoContext
		     //Context
    public class CompressaoContext
    {
        private ICompressao _icompressao;
        public CompressaoContext(ICompressao icompressao)
        {
            _icompressao = icompressao;
        }
		        public void DefineStrategy(ICompressao icompressao)
        {
            _icompressao = icompressao;
        }
		        public void CriarArquivoCompactado(string nomeArquivo)
        {
            _icompressao.ComprimirArquivo(nomeArquivo);
        }
    }
		
  | 
	
3- Classe CompressaoZip
| 
		    
		public class CompressaoGzip : ICompressao { public void ComprimirArquivo(string nomeArquivo) { Console.WriteLine($"\nO arquivo {nomeArquivo} foi compactado usando GZip " + $"\nUm arquivo com extensão .gzip foi criado"); } }  | 
	
4- Classe CompressaoGzip
| 
		
		    public 
		class CompressaoZip : ICompressao { public void ComprimirArquivo(string nomeArquivo) { Console.WriteLine($"\nO arquivo '{nomeArquivo}' foi compactado usando Zip " + $"\nUm arquivo com extensão .zip foi criado"); } }  | 
	
5- Classe CompressaoRar
| 
		
		    public 
		class CompressaoRar : ICompressao { public void ComprimirArquivo(string nomeArquivo) { Console.WriteLine($"\nO arquivo '{nomeArquivo}' foi compactado usando Rar. " + $"\nUm arquivo com extensão .rar foi criado"); } }  | 
	
7- Program
		
  | 
	
A execução do projeto irá apresentar o seguinte resultado:

Desta forma com o 
padrão Strategy é possível reutilizar o código por todo o projeto.
Pegue o código 
do projeto aqui : 
 
StrategyExemplo.zip
"Bendito seja o 
Deus e Pai de nosso Senhor Jesus Cristo, Pai das misericórdias e Deus de toda 
consolação,
que nos consola em todas as nossas tribulações, para que, com a consolação que 
recebemos de Deus, possamos consolar os que estão passando por tribulações."
2 Coríntios 1:3,4
Referências:
NET - Unit of Work - Padrão Unidade de ...
NET - O padrão de projeto Decorator
NET - Padrão de Projeto Builder
C# - O Padrão Strategy (revisitado)
NET - O padrão de projeto Command
NET - Apresentando o padrão Repository