# **PADRÕES DE PROJETO - GOF**
## ABSTRACT FACTORY
###### tags: `Padrões de Projeto` `Padrões Criacional`
### Intenção
Fornecer uma interface para criar famílias de objetos relacionados ou dependentes sem especificar suas classes concretas.
### Descrição
Neste padrão, a fábrica (conhecida com Factory) recebe solicitações por objetos concretos a partir de um cliente. Este padrão pode ser utilizado quando um sistema de software precisa ser independente de como classes concretas (produtos) são criadas, compostas ou representadas. No padrão, uma fábrica fica responsável por encapsular a criação de uma família de produtos. Nesse caso, um cliente precisa conhecer somente as interfaces desses produtos, não a sua implementação, aumentando assim o encapsulamento e abstração.
### Benefícios
A aplicação deste padrão traz como benefício principla o isolamento de classes concretas. Se for necessário trocar uma família inteira de produtos, esse processo se torna menos impactante nas demais partes do sistema, pois as classes produtos ficam isoladas e não expõem sua implementação a classe cliente, diminuindo o acoplamento.
### Frequência do uso
Nível 5
### Participantes
* `Abstract Factory` - Declara uma interface para operações que criam objetos produtos abstratos
* `Concrete Factory` - Implementa as operações que criam objetos produtos concretos;
* `Abstract Product` - Define um objeto produto a ser criado pela correspondente fábrica concreta que implementa a interface de Abstract Product;
* Client - Usa somente as interface declaradas pelas classes Abstract Factory e Abstract Product;
### Exemplo
Supndo que temos que construir um controle de acesso a dados para dois tipos de bancos distintos, SQL Server e Oracle.
```csharp=
namespace AbstractFactory{
public abstract class DBCommand {
public abstract void Execute();
}
}
namespace AbstractFactory{
public abstract class DBConnection {
public abstract void Open();
}
}
namespace AbstractFactory{
public class SQLCommand: DBCommand
{
public override void Execute(){
Console.WriteLine("Metodo SQL Command executado com sucesso.");
}
}
}
namespace AbstractFactory{
public class SQLConnection: DBConnection
{
public override void Open(){
Console.WriteLine("Método SQL Connection foi executado com sucesso.");
}
}
}
namespace AbstractFactory{
public abstract class DBFactory
{
public abstract DBConnection CreateConnection();
public abstract DBCommand CreateCommand();
}
}
namespace AbstractFactory{
public class OracleCommand: DBCommand
{
public override void Execute(){
Console.WriteLine("Método Oracle Command executado com sucesso.");
}
}
}
namespace AbstractFactory{
public class OracleConnection: DBConnection
{
public override void Open(){
Console.WriteLine("Método Oracle Connection foi executado com sucesso.");
}
}
}
namespace AbstractFactory{
public class OracleFactory: DBFactory
{
public override DBConnection CreateConnection(){
return new OracleConnection();
}
public override DBCommand CreateCommand(){
return new OracleCommand();
}
}
}
namespace AbstractFactory{
public class SQLFactory : DBFactory
{
public override DBConnection CreateConnection(){
return new SQLConnection();
}
public override DBCommand CreateCommand(){
return new SQLCommand();
}
}
}
namespace AbstractFactory
{
class Program
{
static void Main(string[] args)
{
var db = new OracleFactory();
var con = db.CreateConnection();
con.Open();
var cmd = db.CreateCommand();
cmd.Execute();
}
}
}
```
## BUILDER
###### tags: `Padrões de Projeto` `Padrões Criacional`
### Intenção
<p>
Separa a construção de um objeto complexo da sua representação, de modo que o mesmo processo de construção pode criar diferentes representações.
</p>
### Descrição
<p>
O padrão pode ser aplicado quando o algoritimo para a construção de um objeto deve ser independente das partes que o compõem e de como elas são montadas. O processo de construção deve permitir diferentes representações para o objeto que é construído.
</p>
### Benefícios
<p>
A aplicação deste padrão traz alguns benefícios, como permitir variar a representação interna de u produto, pois uma interface permite ao construtor ocultar essa representação. O padrão melhora a modularidade pelo encapsulamento da forma como um objeto complexo é construído e representado. Em outras palavras, ele isola o código da construção.
</p>
### Frequência de uso
Nível 2
### Participantes
<ul>
<li><strong>Builder</strong> - Especifica uma interface abstrata para a criação de partes de um objeto-produto;</li>
<li><strong>Concret Builder</strong> - Constrói e monta partes do produto pela implementação da interface de Builder; define e mantém a representação que cria e fornece uma interface para a recuperação do produto;</li>
<li><strong>Diretor</strong> - Contrói um objeto usando a interface de Builder;</li>
<li><strong>Product</strong> - Representa o objeto complexo em construção, concrete Builder contrói a representação interna do produto e define o processo pelo qual ele é montado,
inclui classes que definem as partes constituintes, inclusive as interfaces para a montagem das partes do resultado final.</li>
</ul>
### Diagrama

### Exemplo
```csharp=
public class Veiculo
{
private string _tipo;
private Dictionary<string,string> _parts = new Dictionary<string,string>();
public Veiculo(string tipo)
{
_tipo = tipo;
}
public string this[string key]{
get {return _parts[key];}
set {_parts[key] = value;}
}
public void Mostrar(){
Console.WriteLine("***********************************************************");
Console.WriteLine($"Tipo: {_tipo}");
Console.WriteLine($"Motor: {_parts["motor"]}");
Console.WriteLine($"Pneus: {_parts["pneus"]}");
Console.WriteLine($"Portas: {_parts["portas"]}");
Console.WriteLine("***********************************************************");
}
}
public abstract class VeiculoBuilder{
protected Veiculo _veiculo;
public Veiculo Veiculo { get {return _veiculo;} }
public abstract void BuildMotor();
public abstract void BuildPortas();
public abstract void BuildPeneus();
}
public class MotoBuilder : VeiculoBuilder
{
public MotoBuilder()
{
_veiculo = new Veiculo("Moto");
}
public override void BuildMotor()
{
_veiculo["motor"] = "250c";
}
public override void BuildPeneus()
{
_veiculo["pneus"] = "2";
}
public override void BuildPortas()
{
_veiculo["portas"] = "0";
}
}
public class CarroBuilder : VeiculoBuilder
{
public CarroBuilder()
{
_veiculo = new Veiculo("Carro de Passeio");
}
public override void BuildMotor()
{
_veiculo["motor"] = "127C";
}
public override void BuildPeneus()
{
_veiculo["pneus"] = "4";
}
public override void BuildPortas()
{
_veiculo["portas"] = "4";
}
}
public class Director {
public void MontarVeiculo(VeiculoBuilder builder){
builder.BuildMotor();
builder.BuildPortas();
builder.BuildPeneus();
}
}
class Program
{
static void Main(string[] args)
{
VeiculoBuilder builder;
var diretor = new Director();
builder = new CarroBuilder();
diretor.MontarVeiculo(builder);
builder.Veiculo.Mostrar();
builder = new MotoBuilder();
diretor.MontarVeiculo(builder);
builder.Veiculo.Mostrar();
}
}
```
## FACTORY METHOD
###### tags: `Padrões de Projeto` `Padrões Criacional`
### Intenção
<p>
Definir uma inteface para criar um objeto, mas deixa as subclasses decidir qual classe instanciar. Permite uma classe adiar a instanciação para subclasses.
</p>
### Descrição
<p>
O padrão pode ser aplicado quando uma classe não é capaz de saber antecipadamente quais objetos devem realmente ser cirados, ou ainda, quando uma classe repassa (delega) para suas subclasses e responsabilidade de quais objetos realmente devem ser criados.
</p>
### Benefícios
<p>
O uso do padrão traz vários benefícios, sendo o maior deles a flexibilidade. como a criação de um objeto que é encapsulada por um método de fábrica, classes clientes não criam esses objetos diretamente. Além disso, como uma classe cliente usa o método de fábrica para obter uma instância de uma classe desejada, o padrão pode ser usado como uma forma transparente e flexível para fornecer um objeto diferente. Isso porque é possível retornar uma subclasse compatível com a classe do objeto retornado pelo método. Também é útil para conectar hierarquias de classes paralelas, quando uma classe precisa delegar determinada responsabilidade para outra classe. Nesse caso, o padrão facilita essa interação.
</p>
### Frequência de uso
Nível 5
### Participantes
<ul>
<li><strong>Product</strong> – define a interface do objeto que o método de fábrica cria;</li>
<li><strong>Concrete Product</strong> – Implementa a interface Product; </li>
<li><strong>Creator</strong> – Declara o método de fábrica, o qual retorna um objeto do tipo Product. Creator também pode definir uma implementação por omissão do método factory que retorna por omissão um objeto Concrete Product; </li>
<li><strong>Concrete Creator</strong> – redefine o método fábrica para retornar uma instância de um Concrete Product</li>
</ul>
### Diagrama

### Exemplo
```csharp=
public interface IAutenticacao
{
void Autenticar();
}
public interface ICreator
{
IAutenticacao CreateInstance();
}
public class AutenticacaoGoogle: IAutenticacao
{
public void Autenticar(){
Console.WriteLine("Autenticado pelo Google");
}
}
public class AutenticacaoLinkedin: IAutenticacao
{
public void Autenticar(){
Console.WriteLine("Autenticado pelo linkedin");
}
}
public class LinkedinCreator: ICreator
{
public IAutenticacao CreateInstance()
{
return new AutenticacaoLinkedin();
}
}
public class GoogleCreator: ICreator
{
public IAutenticacao CreateInstance()
{
return new AutenticacaoGoogle();
}
}
class Program
{
static void Main(string[] args)
{
List<ICreator> creators = new List<ICreator>();
creators.Add(new LinkedinCreator());
creators.Add(new GoogleCreator());
foreach (var item in creators)
{
IAutenticacao aut = item.CreateInstance();
aut.Autenticar();
}
}
}
```
## SINGLETON
###### tags: `Padrões de Projeto` `Padrões Criacional`
### Inteção
Garante que uma classe tem apenas uma instância, e fornece um ponto global de acesso a ela.
### Descrição
O padrão `Singleton` pode ser usado quando for preciso haver apenas uma instância de uma classe e essa instância tiver que dar acesso aos clientes através de um ponto bem conhecido. Ou quando a única instância tiver de ser extensível através de subclasses, possibilitando aos clientes usar uma instância estendida sem alterar o seu código.
### Benefícios
Entre alguns benefícios do uso do padrão, podemos citar o acesso controlado à instância única; pode-se criar subclasses do `singleton` sem impacto nas classes clientes; permite ainda o controle do número de instâncias internamente.
### Frequência de uso
Nível 4
### Participantes
* **`Singleton`** - define uma operação **`instance`** que permite aos clientes acessarem sua única instância. **`instance`** é uma operação de classe (método estático); pode ser responsável pela criação de sua própria instância única.
### Diagrama

### Exemplo
```csharp=
public class ConexaoBaseDado
{
private static ConexaoBaseDado _instance;
// esconde o construtor
protected ConexaoBaseDado(){}
public static ConexaoBaseDado Instance()
{
// garante que apenas uma instância seja criada.
if (_instance == null)
_instance = new ConexaoBaseDado();
return _instance;
}
public string stringConexao { get; set; }
public void Open()
{
Console.WriteLine($"Conexao com banco {stringConexao}");
}
}
static void Main(string[] args)
{
var con1 = ConexaoBaseDado.Instance();
con1.stringConexao = "SQL Server";
con1.Open();
var con2 = ConexaoBaseDado.Instance();
con2.Open();
if (con1 == con2)
Console.WriteLine("São a mesma instância");
}
```
## ADAPTER
##### tags: `Padrões de Projeto` `Padrões estruturais`
### Intenção
Converter a interface de uma classe em outra interface esperada pelo clientes. Permite que classes trabalhem em conjunto, pois de outra forma não poderiam devido a terem interfaces incompatíveis.
### Descrição
O padrão pode ser usando quando você quiser usar uma classe existente, mas sua interface não corresponder à interface que necessita; ou quando você quiser criar uma classe reutilizável que coopere com classes não relacionadas ou não-prevista, ou seja classes que não necessariamente tenha interfaces compatíveis; você precisar usar várias subclasses existentes, porém, for impraticável adaptar essas interfaces criando subclasses para cada uma. Um adaptador de objeto pode adaptar a interfaces de sua classe mãe.
### Benefícios
O padrão traz alguns benefícios. Um adaptador de classe adapta *Adaptee* a *Target* através do uso efetivo de uma classe Adapter concreta, com isso permite a *Adapter* substituir algum comportamento do *Adaptee*, uma vez que *Adapter* é uma subclasse de *Adaptee*. Um adaptador de objeto permite a um único Adapter trabalhar com muitos *Adaptees*. O Adapter também pode acrescentar funcionalidades a todos os *Adaptees* de uma só vez.
### Frequência de uso
Nível 4
### Participantes
* **Target** - define a interface específica do domínio que o Cliente usa;
* **Cliente** - colabora com objeto compatível com a interface de Target;
* **Adaptee** - define uma interface existente que necessita ser adptada;
* **Adapter** - adapta a interface do Adaptee à interface do Tarquet;
### Diagrama

### Exemplo
```csharp=
public class Targuet
{
public virtual void Request()
{
Console.WriteLine("Método Request da targuet chamado");
}
}
public class Adaptee {
public void SpecificRequest(){
Console.WriteLine ("Método especifico de Adaptee foi chamado.");
}
}
public class Adapter: Targuet {
private Adaptee _adaptee = new Adaptee();
public override void Request(){
_adaptee.SpecificRequest();
}
}
class Program
{
static void Main(string[] args)
{
Targuet targuet1 = new Adapter();
Targuet targuet2 = new Targuet();
targuet1.Request();
targuet2.Request();
}
}
```
## BRIDGE
##### tags: `Padrões projeto` `Padrões estruturais`
### Intenção
Desacopla uma abstração de sua implementação, de modo que os dois possam variar independentemente.
### Descrição
O padrão pode ser usado para evitar o vínculo permanente entre uma abstração e sua implementação, por exemplo quando a implementação deve ser alterada em tempo de execução. Tanto as abstrações como as suas implementações tiverem de ser extensíveis por meio de subclasses, nesse caso permite combinar diferentes abstrações e implementações e estendê-las independentemente. Mudanças na implementação de uma abstração não tem impacto sobre clientes. Ou ainda, para compatilhar uma mesma implementação entre vários objetos.
### Benefícios
Entre os benefícios trazidos por este padrão, podemos destacar o desacoplamento de interface da implementação, melhoria na extensibilidade, ocultação de detalhes de implementação dos clientes.
### Frequência de uso nível 3
### Participantes
* **Abstration** - Define a interface de abstração, mantém uma referência para o objeto do tipo implementor;
* **Refined Abstraction** - Estende a interface definida por Abstraction;
* **Implementor** - Define a interface para as classes de implementação;
* **Concrete Implementor** - Implementa a interface de implementor e define sua implementação concreta;
### Diagrama

### Exemplo
```csharp=
public abstract class Exportacao {
public ExportacaoImplementor Implementor { private get; set; }
public virtual void Exportar(){
Implementor.Exportar();
}
}
public class ExportacaoExtensao : Exportacao{
public override void Exportar()
{
base.Exportar();
}
}
public abstract class ExportacaoImplementor{
public abstract void Exportar();
}
public class ExportacaoDoc: ExportacaoImplementor{
public override void Exportar()
{
Console.WriteLine("Exportando arquivo DOC");
}
}
public class ExportacaoPDF: ExportacaoImplementor {
public override void Exportar()
{
Console.WriteLine("Exportando arquivo PDF");
}
}
class Program
{
static void Main(string[] args)
{
Exportacao pdf = new ExportacaoExtensao();
pdf.Implementor = new ExportacaoPDF();
pdf.Exportar();
Exportacao doc = new ExportacaoExtensao();
doc.Implementor = new ExportacaoDoc();
doc.Exportar();
}
}
```
## COMPOSITE
##### tags: `Padrões de projetos` `Padrões estruturais`
### Intenção
Compor objetos em estruturas de árvore para representar hierarquias parte ou todo. *Composite* permite que clientes tratem objetos individuais e composições de objetos de maneira uniforme.
### Descrição
Por exemplo, em interfaces gráficas um elemento gráfico pode ser constituído pela composição de fários outros elementos gráficos. Uma janela pode conter um ou mais ícones, uma caixa de texto e vários outros elementos gráficos, até mesmo outra janela. Considerando que uma determinada hierarquia de classes *Control* como a *supoer-classe* comum a todas as classes que *Form* seria representada como uma classe que contém zero (0) ou mais elementos gráficos.
É importante observar que será responsabilidade do objeto composto, para cada método a ser aplicável à lista de objetos que possi, implementá-lo de maneira repetitiva. Por exemplo, no caso da hierarquia de elementos gráficos exemplificada, suponha que um objeto cliente ative o método *Draw* de um objeto do tipo *Form*. Exte método deverá ser capaz de ativar os métodos *Draw* de cada um dos objetos que ele contém. Desta maneira será possível interagir com uma composição de objetos da mesma forma que se interage com objetos individuais.
### Benefícios
Entre os benefícios trazidos pelo uso do padrão podemos citar a definição de hierarquia de classes que consistem de objetos primitivos e objetos compostos, podendo assim compor objetos mais complexos. Sempre que o código do cliente esperar um objeto primitivo, poderá também aceitar um composto. Além disso, o padrão torna o cliente simples, pois pode tratar estruturas diferentes de maneira uniforme (não importa se é um tipo folha ou composto). Torna também mais fácil a adição de novas espécies de componentes.
### Frequência de uso
Nível 4
### Participantes
* ***Component*** - declara a interface para os objetos na composição; implementa comportamento padrão para interface comum; declara interface para gerenciar filhos;
* ***Leaf*** - representa objetos ***"folhas"*** na composição;
* ***Composite*** - define comportamentos para os componentes que têm filhos; implementa operações relacionadas com os filhos;
* ***Client*** - manipula objetos na composição através da interface de ***Component***;
### Diagrama

### Exemplo
```csharp=
public abstract class Component
{
protected string _name;
public Component(string name)
{
this._name = name;
}
public abstract void Add(Component c);
public abstract void Remove(Component c);
public abstract void Display();
}
public class Button : Component
{
public Button(string name) : base(name){}
public override void Add(Component c)
{
Console.WriteLine("Não é possível adicionar elementos a este componente");
}
public override void Display()
{
Console.WriteLine(_name);
}
public override void Remove(Component c)
{
Console.WriteLine("Não é possível remover elemento");
}
}
public class TextBox: Component
{
public TextBox(string name) : base(name){}
public override void Add(Component c)
{
Console.WriteLine("Não é possível adicionar elementos a este componente");
}
public override void Display()
{
Console.WriteLine(_name);
}
public override void Remove(Component c)
{
Console.WriteLine("Não é possível remover elemento");
}
}
private List<Component> _children = new List<Component>();
public Formulario(string name)
: base(name)
{
}
public override void Add(Component c)
{
this._children.Add(c);
}
public override void Display()
{
Console.WriteLine(_name);
foreach (var item in _children){
item.Display();
}
}
public override void Remove(Component c)
{
this._children.Remove(c);
}
}
class Program
{
static void Main(string[] args)
{
var formulario = new Formulario("Cadastro de pessoas");
formulario.Add(new Button("Novo"));
formulario.Add(new Button("Gravar"));
formulario.Add(new Button("Cancelar"));
formulario.Add(new Button("Excluir"));
formulario.Add(new Button("Anterior"));
formulario.Add(new Button("Proximo"));
formulario.Add(new Button("Sair"));
formulario.Add(new TextBox("Nome"));
formulario.Add(new TextBox("CPF"));
formulario.Add(new TextBox("Telefone"));
formulario.Add(new TextBox("e-mail"));
formulario.Display();
}
}
```
## DECORATOR
##### tags: `Padrões de projetos` `Padrões estruturais`
### Intenção
Anexar responsabilidades adicionais a um objeto dinamicamente. Fornece uma alternativa flexível na criação de subclasses para estender funcionalidades.
### Descrição
O padrão, e conhecido também como wrapper, favorece o uso de composição sobre a herança. Permite adicionar (ou remover) responsabilidades individuais a uma classe de forma dinâmica, flexível e transparente. Ao usuar herança, uma classe formalmente especifica seu tipo herdado e gera uma relação de dependência praticamente imutável, gerando fortes acoplamentos. O padrão Decorator, ao invés disso, permite estender uma classe "decorando-a" com novas funcionalidades, sem que seja necessário criar uma grande hierarquiva de subclasses.
### Benefícios
Os benefícios do uso do padrão são inúmeros, como principal e já citado a flexibilidade, pois não faz uso de herança, que é estática. Além disso, evita criar uma classe com inúmeras responsabilidades expostas em suas interface, já que a "decoração" é interna. Funções são delegadas internamente sem exposição publica.
### Frequência de uso
Nível 3
### Participantes
* ***Componente*** - Define a interface para objetos que podem ter responsabilidades acrescentadas dinamicamente;
* ***ConcreteComponent*** - Define um objeto para o qual as responsabilidades adicionais podem ser atribuídas;
* ***Decorator*** - Mantém uma referência para um objeto **Component** e define uma interface que segue a interface de **Component**;
* **ConcreteDecorator** - Acrescenta responsabilidades ao componente.
### Diagrama

### Exemplo
```csharp=
public abstract class BaseDataSet
{
public abstract void Write();
}
public class DataSet : BaseDataSet
{
public override void Write()
{
Console.WriteLine("Método DataSet.Write() chamado");
}
}
public class DataSetDecorator: BaseDataSet
{
public BaseDataSet DataSetBase { protected get; set; }
public override void Write()
{
Console.WriteLine("Método DataSetDecorator.Write() Chamado");
this.DataSetBase.Write();
}
}
public class DataSetConcreteDecorator: DataSetDecorator
{
public override void Write(){
Console.WriteLine("Método DataSetConcreteDecorator.Write() Chamado");
this.DataSetBase.Write();
}
public void WriteXML(){
Console.WriteLine("Método DataSetConcreteDecorator.WriteXML() Chamado");
}
}
class Program
{
static void Main(string[] args)
{
DataSet ds = new DataSet();
DataSetConcreteDecorator dc = new DataSetConcreteDecorator();
dc.DataSetBase = ds;
dc.Write();
dc.WriteXML();
}
}
```
## FAÇADE
##### tags: `Padrões de projetos` `Padrões estruturais`
### Intenção
Fornecer uma interface unificada para um conjunto de interfaces em um subsistema. Facade define uma interface de nível mais elevado que faz o subsistema mais fácil de usar.
### Descrição
Uma boa aplicação para o *Façade* "fachada" é criar uma forma mais simples para os objetos clientes de lidarem com um sistema mais complexo, escondendo muito de sua implementação fortalecendo o encapsulamento e isolamento.
### Benefícios
Torna uma biblioteca de software mais fácil de entender e usar; tornar o código que utiliza esta biblioteca mais fácil de entender; reduzir as dependências em relação às características internas de uma biblioteca, trazendo flexibilidade no desenvolvimento do sistema; envolver uma interface mal desenhada, com uma interface melhor definda.
### Frequência de uso
Nível 5
### Participantes
* ***Façade*** - Conhece quais as classes do subsistema que são responsáveis pelo atendimento de uma solicitação; delega solicitações de clientes a objetos apropriados do subsistema;
* ***Classes de subsistema*** - Implementam as funcionalidades do subsistema; encarregam-se do trabalho atribuído a elas pelo objeto *Façade*; não tem conhecimento "referência" ao *Façade*;
### Diagrama

### Exemplo
```csharp=
public abstract class MailFormat{}
public class MailFormatHTML : MailFormat {}
public class MailFormatTXT : MailFormat {}
public class MailMessage
{
private string _message;
private MailFormat _format;
public string Message
{
get { return _message; }
set { _message = value; }
}
public MailMessage(string message, MailFormat format)
{
// formatar mensagem aqui...
this._message = message;
this._format = format;
}
}
public class SMTPSettings
{
private string _serverName;
public string ServerName
{
get { return _serverName; }
set { _serverName = value; }
}
private string _userName;
public string UserName
{
get { return _userName; }
set { _userName = value; }
}
private string _password;
public string Password
{
get { return _password; }
set { _password = value; }
}
}
public class Mail
{
private SMTPSettings _conf;
public Mail(SMTPSettings conf)
{
this._conf = conf;
}
public void Send(MailMessage message)
{
// usando configurações SMTP
Console.WriteLine("Enviando mensagem...");
Console.WriteLine(message.Message);
}
}
public class Email
{
private Mail _mail;
private MailFormat _format;
private SMTPSettings _conf;
private MailMessage _msg;
public Email()
{
this._conf = new SMTPSettings()
{
ServerName = "smtp.gmail.com",
Password = "123",
UserName = "default"
};
this._mail = new Mail(_conf);
this._format = new MailFormatTXT();
this._msg = new MailMessage("", _format);
}
public void Enviar(string Mensagem)
{
_msg.Message = Mensagem;
_mail.Send(_msg);
}
}
class Program
{
static void Main(string[] args)
{
var email = new Email();
email.Enviar("Olá, você esta encaminhando um e-mail ao mundo.");
}
}
```
## FLYWEIGHT
##### tags: `Padrões de projetos` `Padrões estruturais`
### Intenção
Usar compartilhamento para suportar um grande número de objetos semelhantes de forma eficiente.
### Descrição
O objetivo do padrão Flyweight é minimizar o uso de memória no armazenamento de vários objetos através do compartilhamento de informações em comum que essas instâncias possuem. É essa a ideia da aplicação do padrão, fazer com que tenhamos aplicações leves. Quando trabalhamos com orientação a objetos, utilizamos classes para representar cada parte das aplicações. Por exemplo, um sistema de vendas terá objetos que representam boletos, notas fiscais, item da nota etc. um editor de texto provavelmente téra objetos que representam parágrafos, frases, caracteres, imagens etc. Com essa abordagem temos vantagens da programação orientada a objetos, como herança, polimorfismo e encapsulamento, no entanto podemos introduzir um gasto na manutenção de todas essas estruturas de objetos. É esse problema que o Flyweight atua.
O conceito principal para a utilização deste padrão é a distinção entre dados intrínsecos e dados extrínsecos. Dados intrínsecos são as informações comuns entre as várias instâncias e que por essa característica podem ser compartilhadas já os dados extrínsecos são as informações específicas de cada objeto e que consequentemente não podem ser compartilhadas. Os dados intrínsecos são mantidos nos objetos que implementam a Flyweight, e os extrínsecos são mantidos pelo cliente. Este padrão é especialmente indicado para os casos de aplicações com um grande número de objetos com muitas informações que devem ser armazenados em memória, do outro lado, ele não deve ser utilizado em situações em que precisamos fazer comparações entre os objetos, já que como eles serão compartilhados, esse tipo de ação se torna inviável "as comparações sempre retornarão que os objetos são os mesmos!".
### Benefícios
Redução do número total de instâncias obtidas com o compartilhamento.
### Frequência de uso
Nível 1
### Participantes
* ***Flyweight*** – é a interface que define como devem ser as classes que trabalham neste padrão.
É importante citar que ela descreve como os dados extrínsecos são recebidos, ou seja, as
operações que fazem essa transposição de informações;
* ***ConcreteFlyweight*** – são as classes que implementam o contrato IFlyweight e que devem
permitir o compartilhamento. Essas classes mantêm dados intrínsecos;
* ***UnsharedConcreteFlyweight*** – possuem as mesmas características do ConcreteFlyweight, no
entanto não são objetos compartilhados. Isso porque esse padrão permite o
compartilhamento, mas não obriga que isso seja sempre seguido;
* ***FlyweightFactory*** – classe que é responsável pela criação dos objetos, além de manter o
repositório de objetos que implementam o Flyweight;
* ***Client*** – é quem utiliza os objetos IFlyweight, sempre os obtendo através do FlyweightFactory.
### Diagrama

### Exemplo
```csharp=
class Program
{
//Client
static void Main(string[] args)
{
// externo
int ext = 10;
FlyweightFactory fabrica = new FlyweightFactory();
Flyweight f1 = fabrica.getFlyweight("A");
f1.Operation(ext++);
Flyweight f2 = fabrica.getFlyweight("B");
f2.Operation(ext++);
Flyweight f3 = fabrica.getFlyweight("C");
f3.Operation(ext++);
Flyweight f4 = fabrica.getFlyweight("A");
f4.Operation(ext++);
Flyweight f5 = new UnsharedConcreteFlyweight();
f5.Operation(ext++);
}
}
public abstract class Flyweight
{
public abstract void Operation(int ext);
}
public class FlyweightFactory
{
private Hashtable _flyweights = new Hashtable();
//constructor
public FlyweightFactory()
{
_flyweights.Add("A", new ConcreteFlyweight());
_flyweights.Add("B", new ConcreteFlyweight());
_flyweights.Add("C", new ConcreteFlyweight());
}
public Flyweight getFlyweight(string key)
{
return (Flyweight)_flyweights[key];
}
}
public class ConcreteFlyweight : Flyweight
{
public override void Operation(int ext)
{
Console.WriteLine("Concrete Flyweight: " + ext);
}
}
public class UnsharedConcreteFlyweight : Flyweight
{
public override void Operation(int ext)
{
Console.WriteLine("UnsharedConcreteFlyweight: " + ext);
}
}
```
## PROXY
##### tags: `Padrões de projetos` `Padrões estruturais`
### Intenção
Fornecer um substituo ou espaço reservado para outro objeto controlar o acesso a ele.
### Descrição
Um proxy, de forma geral, é uma classe que funciona com uma interface para outra classe. A classe proxy poderia conectar-se a qualquer coisa, uma conexão de rede, um objeto grande em memória, um arquivo, ou a um recurso que é difícil ou impossível de ser duplicado.
### Benefícios
Podemos dizer que um proxy pode ocultar o fato de que um objeto reside em um espaço de memória diferente, um proxy virtual pode executar otimizações, tais como criação de objetos sob demanda.
### Frequência de uso
Nível 4
### Participantes
* ***Proxy*** - Mantém uma referência que permite ao *proxy* acessar o objeto real, fornece uma interface idêntica ao *Subject*, por esse motivo ele pode substituir o objeto real ***RealSubject***, controla o acesso ao objeto real, podendo ser responsável pela criação de destruição;
* ***Subject*** - Define uma interface comum para *RealSuject* e *Proxy*;
* ***RealSubject*** - Define o objeto real que o *proxy* representa;
### Diagrama

### Exemplo
```csharp=
class Program
{
static void Main(string[] args)
{
ICalc calc = new CalcProxy();
var r = calc.Somar(3, 5);
Console.WriteLine(r.ToString());
}
}
interface ICalc
{
int Somar(int x, int y);
}
// Proxy
public class CalcProxy : ICalc
{
// RealSubject
private Calc _calc;
public int Somar(int x, int y)
{
// instancia por demanda (lazy)
if (_calc == null)
{
_calc = new Calc();
}
// repassando a chamada ao RealSubject
return _calc.Somar(x, y);
}
}
public class Calc : Proxy.ICalc
{
public int Somar(int x, int y)
{
return x + y;
}
}
```
## CHAIN OF RESPONSABILITY
##### tags: `Padrões de projetos` `Padrões comportamentais`
### Intenção
Evitar o acoplamento do remetente de uma solicitação ao seu receptor, ao dar a mais de um objeto a oportunidade de tratar a solicitação. Encadear os objetos receptores, passando a solicitação ao longo da cadeia até que um objeto o trate.
### Descrição
Neste padrão cada objeto receptor possui uma lógica descrevendo os tipos de solicitação que é capaz de processar e como passar adiante aquelas que requeiram processamento por outros receptores. A deleção das solicitações podem formar uma árvore de recursão, com um mecanismo especial para inserção de novos receptores no final da cadeia existente. Dessa forma, fornece um acoplamento mais fraco por evitar a associação explícita do remetente de uma solicitação ao seu receptor e dar a mais de um objeto a oportunidade de tratar a solicitação. Um exemplo da aplicação desse padrão é o mecanismo de herança nas linguagens orientadas a objeto, onde um método chamado em um objeto é buscado na classe que implementa o objeto e, se não encontrado, na superclasse dessa classe, de maneira recursiva.
### Benefícios
O padrão permite determinar quem será o objeto que irá tratar a requisição durante a execução. Cada objeto pode tratar ou passar a mensagem para o próximo na cascata. Dessa forma, o acomplamento é reduzido, dando ainda flexibilidade adicional na atribuição de responsabilidades a objetos.
### Frequência de uso
Nível 2
### Participantes
* ***Handler*** - Define uma interface para tratar solicitações;
* ***ConcreteHandler*** - Trata de solicitações pelas quais é responsável; pode acessar seu sucessor;
* ***Client*** - Inicia a solicitação para um objeto ConcreteHandler da cadeia;
### Diagrama

### Exemplo
```csharp=
class Program
{
static void Main(string[] args)
{
var valForm = new Formulario();
var valServer = new Server();
var valBD = new BD();
valForm.setSucessor(valServer);
valServer.setSucessor(valBD);
// passando requisição para cadeia de responsabilidade
valForm.ValidateUser("User", "123");
}
}
// Handler
public abstract class BaseValidate
{
protected BaseValidate _sucessor;
public void setSucessor(BaseValidate sucessor)
{
this._sucessor = sucessor;
}
public abstract bool ValidateUser(string name, string password);
}
public class BD : BaseValidate
{
public override bool ValidateUser(string name, string password)
{
bool ret = name == password;
Console.WriteLine("Validação feita no Banco de Dados:" + ret);
// encadeia chamada
if (_sucessor != null)
_sucessor.ValidateUser(name, password);
return ret;
}
}
// ConcreteHandler
public class Formulario : BaseValidate
{
public override bool ValidateUser(string name, string password)
{
var ret = false;
if (name != null)
if (password != null)
ret = true;
Console.WriteLine("Validação feita em formulário:" + ret);
// encadeia chamada
if (_sucessor != null)
_sucessor.ValidateUser(name, password);
return ret;
}
}
// ConcreteHandler
public class Server : BaseValidate
{
public override bool ValidateUser(string name, string password)
{
bool ret = name == password;
Console.WriteLine("Validação feita em server:" + ret);
// encadeia chamada
if (_sucessor != null)
_sucessor.ValidateUser(name, password);
return ret;
}
}
```
## COMMAND
##### tags: `Padrões de projetos` `Padrões comportamentais`
### Intenção
Encapsular uma requisição como um objeto, desse modo pode-se parametrizar clientes com diferentes requisições, com suporte para enfileirar, logar e desfazer essas requisições.
### Descrição
A chave deste padrão é uma classe abstrata Command, a qual declara uma interface para execução de operações. Na sua forma mais simples, esta interface inclui uma operação abstrata execute. As subclasses concretas de Command especificam uma para receptor ação através do armazenamento do receprtor como uma variável de instância e pela implementação de execute para invocar a solicitação. O receptor tem o conhecimento necessário para poder executar a solicitação.
### Benefícios
Desacopla o objeto que invoca a operação daquele que sabe como executá-lo; é fácil criar novos comandos porque não é necessário mudar classes existentes.
### Frequência de uso
Nível 4
### Participantes
* ***Command*** - Declara uma interface para executar a operação;
* ***ConcreteCommand*** - Define uma vinculação entre o objeto *Receiver* e uma ação; Implementa Execute invocando a operação correspondente em Receiver;
* ***Client*** - Cria um objeto *ConcreteCommand* e configura o seu receptor;
* ***Invoker*** - Solicita ao *Command* a execução da solicitação;
* ***Receiver*** - Sabe como executar as operações associadas a uma solicitação; qualquer classe pode funcionar como um receiver;
### Diagrama

### Exemplo
```csharp=
class Program
{
//Client
static void Main(string[] args)
{
// configura Receiver
Server server = new Server();
// cria comando configurando o receiver
Command cmd = new ServerCommand(server);
// configura o Invoker
Formulario form = new Formulario();
// configura e executar o comando...
form.setCommand(cmd);
form.ClickValidate();
}
}
public abstract class Command
{
public abstract void Execute();
}
// Invoker
public class Formulario
{
private Command _command;
public void setCommand(Command command)
{
this._command = command;
}
public void ClickValidate()
{
Console.WriteLine("Invoker: Validando usuário");
_command.Execute();
}
}
// ConcreteCommand
public class ServerCommand : Command
{
private Server _server;
public ServerCommand(Server server)
{
this._server = server;
}
public override void Execute()
{
Console.WriteLine("ServerCommand - ConcreteCommand: Validando usuário");
_server.ValidateUser();
}
}
// Receiver
public class Server
{
public void ValidateUser()
{
Console.WriteLine("Receiver: Validando usuário");
}
}
```
## INTERATOR
##### tags: `Padrões de projetos` `Padrões comportamentais`
### Intenção
Fornece uma maneira de acessar os elementos de um objeto agregado sequencialmente sem expor sua representação.
### Descrição
Um objeto agregado, com uma lista por exemplo, deveria sempre oferecer uma forma de acessar seus elementos (dados) sem expor sua estrutura interna. Além disso, essa lista poderia ser examinada de diferentes formas, dependendo do que precisa ser realizado (procurar, ordenar etc.) normalmente uma interface para cada operação sobrecarregaria a classe. Nesse caso um padrão uniforme (o Interator) provê uma estratégia conhecida atualmente como "programação genérica", que visa separar explicitamente algoritmos de estruturas de dados.
### Benefícios
Os principais benefícios do padrão é promover a programação baseada em componentes, reutilização e aumento de produtividade.
### Frequência de uso
Nível 5
### Participantes
* ***Interator*** - Define uma interface para acessar e percorrer elementos;
* ***ConcreteInterator*** - Implementa a interface do Iterator; mantém o controle da posição correte no percurso do agregado;
* ***Aggregate*** - Define uma interface para a criação de um objeto interator;
* ***ConcreteAggregate*** - Implementa a interface de criação do interator para retornar uma instância do ConcreteCreator apropriado;
### Diagrama

### Exemplo
```csharp=
class Program
{
static void Main(string[] args)
{
// Cria Concrete Aggregate
Equipe equipe = new Equipe();
equipe[0] = "Stanley";
equipe[1] = "Dias";
equipe[2] = "Paulo";
equipe[3] = "Marinho";
equipe[4] = "Jose";
// Cria Iterator
ConcreteIterator i = new ConcreteIterator(equipe);
// iterar pela coleção
Console.WriteLine("Listando membros da equipe:");
Object item = i.First();
while (item != null)
{
Console.WriteLine(item);
item = i.Next();
}
}
}
// Iterator
public abstract class Iterator
{
public abstract Object First();
public abstract Object Next();
public abstract bool IsDone();
public abstract Object CurrentItem();
}
// Aggregate
public abstract class Aggregate
{
public abstract Iterator CreateIterator();
}
// Concrete Aggregate
public class Equipe : Aggregate
{
private List<string> _items = new List<string>();
public override Iterator CreateIterator()
{
return new ConcreteIterator(this);
}
public int Count
{
get { return _items.Count; }
}
// indexer
public Object this[int index]
{
get { return _items[index]; }
set { _items.Insert(index, (string)value); }
}
}
public class ConcreteIterator : Iterator
{
private Equipe _aggregate;
private int current = 0;
public ConcreteIterator(Equipe aggregate)
{
_aggregate = aggregate;
}
public override object First()
{
return _aggregate[0];
}
public override object Next()
{
Object ret = null;
if (current < _aggregate.Count - 1)
ret = _aggregate[++current];
return ret;
}
public override bool IsDone()
{
return current >= _aggregate.Count ? true : false;
}
public override object CurrentItem()
{
return _aggregate[current];
}
}
```
## MEDIATOR
##### tags: `Padrões de projetos` `Padrões comportamentais`
### Intenção
Definir um objeto que encapsula como um conjunto de objetos interagem. Mediator promove o baixo acoplamento por manter objetos sem se referir um ao outro de forma explícita, e que lhe permite variar sua interação independentemente.
### Descrição
O padrão Mediator pode ser usado quando: um conjunto de objetos se comunica de maneira bem-definida, porém complexas; as interdependência resultantes são desestruturadas e difíceis de entender. A reutilização de um objeto é difícil porque ele referencia e se comunica com muitos outros objetos; um comportamento que está distribuído entre várias classes deveria ser customizável, ou adaptável, sem execessiva especialização em subclasses.
### Benefícios
Limita o uso de subclasses; desacopla colegas; simplifica o protocolo de objetos; abstrai a maneira como os objetos cooperam; ele centraliza o controle
### Desvantagens
* A centralização pode ser uma fonte de gargalos de desempenho e de risco para o sistema em caso de falha;
* Na prática, os mediadores tendem a se tornar mais complexos.
***(Fonte: 2003, Helder L. S da rocha)***
### Frequência de uso
Nível 2
### Participantes
* **Mediator** - Define uma interface para comunicação com objetos Colleague;
* **ConcreteMediator** - Implementa o comportamento cooperativo;
* **Colleague classes** - Cada classe Colleague conhece seu objeto Mediator de outra forma; cada Colleague se comunica com seu Mediator sempre que, de outra forma, teria que se comunicar com outro colega;
### Diagrama

### Exemplo
```csharp=
class Program
{
static void Main(string[] args)
{
ConcreteMediator mediator = new ConcreteMediator();
Suporte suporte = new Suporte(mediator);
Usuario usuario = new Usuario(mediator);
mediator.Suporte = suporte;
mediator.Usuario = usuario;
usuario.Send("Meu Sistema não esta carregando.");
suporte.Send("E preciso reiniciar o sistema.");
}
}
public abstract class Mediator
{
public abstract void Send(string message, Colleague colleague);
}
public abstract class Colleague
{
protected Mediator _mediator;
public Colleague(Mediator mediator)
{
this._mediator = mediator;
}
}
public class Suporte : Colleague
{
public Suporte(Mediator mediator)
:base(mediator)
{}
public void Send(string message)
{
_mediator.Send(message, this);
}
public void Notify(string message)
{
Console.WriteLine($"Suporte recebeu a mensagem: {message}");
}
}
public class Usuario : Colleague
{
public Usuario(Mediator mediator)
:base(mediator)
{
}
public void Send(string message){
_mediator.Send(message, this);
}
public void Notify(string message)
{
Console.WriteLine($"Usuário recebeu a mensagem: {message}");
}
}
public class ConcreteMediator : Mediator
{
private Suporte _suporte;
private Usuario _usuario;
public Suporte Suporte {
set {_suporte = value;}
}
public Usuario Usuario {
set {_usuario = value;}
}
public override void Send(string message, Colleague colleague)
{
if (colleague == _usuario)
_suporte.Notify(message);
else
_usuario.Notify(message);
}
}
```
## MEMENTO
##### tags: `Padrões de projetos` `Padrões comportamentais`
### Intenção
Sem violar o encapsulamento, captura e externaliza o estado interno de um objeto para que o objeto possa ser restaurado para este estado mais tarde.
### Descrição
O padrão pode ser aplicado quando, o estado de um objeto deve ser salvo de maneira que possa ser restaudado para este mesmo estado mais tarde; quando uma interface de estado exporia detalhes de implementação e romperia o encapsulamento do objeto;
### Benefícios
Prevensão das fronteiras de encapsulamento; definição de interfaces mínimas e amplas;
### Frequência de uso
Nível 1
### Participantes
* Memento - Armazena o estado interno do objeto Originador. O Memento pode armazenar um pouco ou muito do estado do Originador, conforme necessário; Protege contra acessos por objetos que não o Originador;
* Originator - Cria um Memento contendo um instantâneo do seu estado interno corrente; usa o Memento para restaurar o seu estado interno;
* Caretaker - É responsável pela custódia do Memento; nunca opera ou examina os conteúdos de um Memento;
### Diagrama

### Exemplo
```csharp
class Program
{
static void Main(string[] args)
{
// cria orignator
Pessoa p = new Pessoa();
p.State = "Stanley";
// Mostra o estado original
Console.WriteLine($"Estado original: {p.State}");
Caretaker c = new Caretaker();
c.Memento = p.CreateMemento();
// trocando o estado...
p.State = "Stanley Dias";
// mostra estado atual
Console.WriteLine($"Estado atual: {p.State}");
// restaurar o estado original
p.SetMemento(c.Memento);
// mostra estado atual
Console.WriteLine($"Estado restaurado: {p.State}");
}
}
public class Memento
{
public string State { get; private set; }
public Memento(string state)
{
State = state;
}
}
public class Pessoa
{
public string State { get; set; }
public Memento CreateMemento(){
return new Memento(State);
}
public void SetMemento(Memento memento){
Console.WriteLine("Restaurando o estado...");
State = memento.State;
}
}
public class Caretaker
{
public Memento Memento { get; set; }
}
```
## OBSERVER
##### tags: `Padrões de projetos` `Padrões comportamentais`
### Intenção
Define uma dependência um-para-muitos entre objetos de modo que quando um objeto muda de estado, todos os seus dependentes são notificados e atualizados automaticamente.
### Descrição
O padrão pode ser aplicado, quando uma abstração tem dois aspectos, um dependente de outro. Encapsulando esses aspectos em objetos separados, permite-se variá-los e reutilizá-los independentemente; quando uma mudança em um objeto exige mudanças em outros, e você não sabe quantos necessitam ser mudados; quando um objeto deveria ser capaz de notificar outros objetos sem fazer hipóteses, ou usar informações, sobre quem são esses objetos. Em outras palavras, você não quer que esses objetos sejam fortemente acoplados;
### Benefícios
Acoplamento abstrato entre Subject e Observer; suporte para comunicação do tipo "broadcast".
### Frequência de uso
Nível 5
### Participantes
* **Subject** - Conhece os seus observadores. Um número qualquer de objetos Observer pode observar um Subject;
* **Observer** - Define uma interface de atualização para objetos que deveriam ser notificados sobre mudanças em um Subject;
* **Concrete Subject** - Armazena estados de interesse para objetos ConcreteObserver; envia uma notificação para os seus observadores quando seu estado muda;
* **ConcreteObserver** - Mantém uma referência para um objeto consistentes com os do Subject; implementa a interface de atualização de Observer, para manter seus estados consistentes com o do Subject;
### Diagrama

### Exemplo
```csharp
class Program
{
static void Main(string[] args)
{
// concrete subject
Balanco balanco = new Balanco();
// Concrete observer
Venda venda = new Venda(balanco);
balanco.Attach(venda);
// add os observadores
balanco.Iniciar();
//balanco.Finalizar();
// pode vender?
venda.Iniciar();
}
}
public abstract class Observer
{
public abstract void Update();
}
public abstract class Subject
{
private List<Observer> _observadores = new List<Observer>();
public void Attach(Observer observer)
{
// add um observador na lista
_observadores.Add(observer);
}
public void Notify()
{
foreach (var o in _observadores)
{
o.Update();
}
}
}
public class Balanco: Subject
{
public bool State {get;set;}
public void Iniciar()
{
State = true;
Console.WriteLine("Balanço iniciado...");
// notifica os observadores
Notify();
}
public void Finalizar()
{
State = false;
Console.WriteLine("Balanço finalizado...");
// notifica os observadores
Notify();
}
}
public class Venda : Observer
{
private bool _state = false;
private Balanco _balanco;
public Venda(Balanco balanco)
{
this._balanco = balanco;
}
public void Iniciar(){
if(!_state)
Console.WriteLine("Venda iniciada...");
else
Console.WriteLine("Não posso iniciar venda pois balanço está em andamento");
}
public override void Update()
{
_state = _balanco.State;
}
}
```
## STATE
##### tags: `Padrões de projetos` `Padrões comportamentais`
### Intenção
Permite que um objeto altere seu comportamento quando seu estado interno muda.
### Descrição
O padrão pode ser aplicado, quando o comportamento de um objeto depende do seu estado e ele pode mudar seu comportamento em tempo de execução, dependendo desse estado; operações têm comandos condicionais grandes, de várias alternativas, que dependem do estado do objeto. Esse estado é normalmente representado por uma ou mais constantes enumeradas. Frequentemente, várias operações conterão essa mesma estrutura condicional. O padrão State coloca cada ramo do comando adicional em uma classe separada. Isto lhe permite tratar o estado do objeto como um objeto propriamente dito, que pode variar independentemente de outros objetos.
### Benefícios
O padrão confina comportamentos específicos de estados e particiona o comportamento para etados diferentes; ele torna explícitas as transações de estado; objetos state podem ser compartilhado.
### Frequência de uso
Nível 3
### Participantes
* Context - Define a interface de interesse para os clientes; mantém uma instância de uma subclasse ConcreteState que define o estado corrente;
* State - Define uma interface para o encapsulamento associado com um determinado estado do Context;
* ConcreteState Subclasses - Cada subclasse implementa um comportamento associado com um estado do Context;
### Diagrama

### Exemplo
```csharp
class Program
{
static void Main(string[] args)
{
Connection con = new Connection(new ConnectionOpened());
con.Open();
con.Close();
}
}
public abstract class ConnectionState
{
public abstract void Open(Connection context);
public abstract void Close(Connection context);
}
public class Connection
{
private ConnectionState _state;
public Connection(ConnectionState state)
{
_state = state;
}
public ConnectionState State{
get {
return _state;
}
set {
_state = value;
Console.WriteLine($"State: {_state.GetType().Name }");
}
}
public void Open(){
_state.Open(this);
}
public void Close(){
_state.Close(this);
}
}
public class ConnectionClosed: ConnectionState
{
public override void Open(Connection context)
{
context.State = new ConnectionOpened();
}
public override void Close(Connection context)
{
context.State = new ConnectionClosed();
}
}
public class ConnectionOpened: ConnectionState
{
public override void Open(Connection context)
{
context.State = new ConnectionOpened();
}
public override void Close(Connection context)
{
context.State = new ConnectionClosed();
}
}
```
## STRATEGY
##### tags: `Padrões de projetos` `Padrões comportamentais`
### Intenção
Definir uma família de algoritmos, encapsular cada um, e torná-los intercambiáveis. Permite que o algoritmo varie independentemente dos clientes que utilizam.
### Descrição
Esse padrão pode ser aplicado quando muitas classes têm propósitos semelhantes e divergem apenas no seu comportamento (implementação). Ou ainda, quando é necessário encapsular a solução para um problema resolvido por um ou mais algoritmos, dos quais classes clientes não deve tomar conhecimento.
### Benefícios
Este padrão traz alguns benefícios, como por exemplo, a eliminação de comandos condicionais para a seleção de um comportamento desejado (algoritmo) para resolver um problema. Ao usar herança, *Strategy* encapsula esses comportamentos em subclasses e usa polimorfismo (que é dinâmico) para substituir as condicionais estáticas, abrindo inclusive a arquitetura para fácil inclusão de novas estratégias para solucionar o mesmo problema.
### Frequência de uso
Nível 4
### Participantes
* **Strategy** - Define uma interface comum para todos os algoritmos suportados. Context usa esta interface para chamar o algoritmo definido por uma ConcreteStrategy;
* **ConcreteStrategy** - Implementa o algoritmo usando a interface Strategy;
* **Context** - Mantém uma referência para o objeto *Strategy*; pode definir uma interface que permite a *Strategy* acessar seus dados;
### Diagrama

### Exemplo
```csharp
class Program
{
static void Main(string[] args)
{
long[] inputArray = new long[20];
Random rnd = new Random();
for (var i = 0; i < inputArray.Length; i++)
{
inputArray[i] = rnd.Next(100);
}
Console.WriteLine("Números originais:");
foreach (var item in inputArray)
Console.WriteLine(item);
Context ctx = new Context(new InsertionSort());
ctx.ContextInterface(inputArray);
Console.WriteLine("Números ordenados:");
foreach (var item in inputArray)
Console.WriteLine(item);
}
}
public abstract class BaseSort
{
public abstract void Sort(long[] inputArray);
protected void Swap(ref long valOne, ref long ValTwo)
{
valOne = valOne + ValTwo;
ValTwo = valOne - ValTwo;
valOne = valOne - ValTwo;
}
}
public class Context
{
BaseSort _strategy;
public Context(BaseSort strategy)
{
this._strategy = strategy;
}
public void ContextInterface(long[] inputArray)
{
_strategy.Sort(inputArray);
}
}
public class BubbleSort : BaseSort
{
public override void Sort(long[] inputArray)
{
for (int iterator = 0; iterator < inputArray.Length; iterator++)
{
for (int index = 0; index < inputArray.Length - 1; index++)
{
if (inputArray[index] > inputArray[index + 1])
{
Swap(ref inputArray[index], ref inputArray[index + 1]);
}
}
}
}
private void SwapWithTemp(ref long valOne, ref long valTwo)
{
long temp = valOne;
valOne = valTwo;
valTwo = temp;
}
}
public class SelectionSort : BaseSort
{
public override void Sort(long[] inputArray)
{
long index_of_min = 0;
for (int iterator = 0; iterator < inputArray.Length - 1; iterator++)
{
index_of_min = iterator;
for (int index = iterator + 1; index < inputArray.Length; index++)
{
if (inputArray[index] < inputArray[index_of_min])
index_of_min = index;
}
Swap(ref inputArray[iterator], ref inputArray[index_of_min]);
}
}
private void Swap(ref long valOne, ref long valTwo)
{
valOne = valOne + valTwo;
valTwo = valOne - valTwo;
valOne = valOne - valTwo;
}
}
public class InsertionSort : BaseSort
{
public override void Sort(long[] inputArray)
{
long j;
long temp = 0;
for (int index = 1; index < inputArray.Length; index++)
{
j = index;
temp = inputArray[index];
while ((j > 0) && (inputArray[j - 1] > temp))
{
inputArray[j] = inputArray[j - 1];
j = j - 1;
}
inputArray[j] = temp;
}
}
}
```
## TEMPLATE METHOD
##### tags: `Padrões de projetos` `Padrões comportamentais`
### Intenção
Define o esqueleto de um algoritmo em uma operação, adiando alguns passos para subclasses. Permite que subclasses redefinam determinadas etapas de um algoritmo sem alterar a estrutura do algoritmo.
### Descrição
Este padrão pode ser aplicado quando existe um algoritmo que resolve um problema a partir de uma série de operações (partes), chamadas da mesma forma, porem estas formas podem variar. Esta variação é então explicitada em subclasses, usando polimorfismo. Um método na classe base nesse caso funciona com um "template", que chama operações em pontos específicos do código, de forma apropriada. Subclasses então apenas se encarregam de dar uma forma concreta a estes pontos já chamados. É uma espécie de inversão de controle, pois nesse caso é a classe base que chama indiretamente métodos das classes filhas, e não o contrário.
### Benefícios
Um benefício de uso do padrão é evitar redundância de código, nesse caso, a chamada a vários métodos em sequência.
### Frequência de uso
Nível 3
### Participantes
* **AbstractClass** - Define as operações primitivas abstratas que as subclasses concretas definem para implementar passos de um algoritmo; implementa um método-template que define o esqueleto de um algoritmo;
* **ConcreteClass** - Implementa as operações primitivas para executar os passos específicos invariantes do algoritmo;
### Diagrama

### Exemplo
```csharp
class Program
{
static void Main(string[] args)
{
Correcao prova = new CorrecaoProva();
prova.Processar();
Correcao redacao = new CorrecaoRedacao();
redacao.Processar();
}
}
public abstract class Correcao
{
public abstract void Corrigir();
public abstract void VerificarPrerequisitos();
public abstract void EnviarDadosParaBancoDeDados();
public abstract void LimparCorrecoesAnteriores();
public abstract void Iniciar();
public void Processar(){
Iniciar();
VerificarPrerequisitos();
LimparCorrecoesAnteriores();
Corrigir();
EnviarDadosParaBancoDeDados();
}
}
public class CorrecaoProva : Correcao
{
private string _prova = "Prova";
public override void Corrigir()
{
Console.WriteLine($"Corrigindo {_prova}");
}
public override void EnviarDadosParaBancoDeDados()
{
Console.WriteLine($"Enviando os dados da {_prova} para o banco de dados");
}
public override void Iniciar()
{
Console.WriteLine($"Iniciando a correção da {_prova}");
}
public override void LimparCorrecoesAnteriores()
{
Console.WriteLine($"Limpando correções da {_prova} anterior");
}
public override void VerificarPrerequisitos()
{
Console.WriteLine($"Verificando os pré-requisitos de correção da {_prova}");
}
}
public class CorrecaoRedacao : Correcao
{
private string _redacao = "Redação";
public override void Corrigir()
{
Console.WriteLine($"Corrigindo {_redacao}");
}
public override void EnviarDadosParaBancoDeDados()
{
Console.WriteLine($"Enviando os dados de {_redacao} para a base de dados");
}
public override void Iniciar()
{
Console.WriteLine($"Iniciando a correção da {_redacao}...");
}
public override void LimparCorrecoesAnteriores()
{
Console.WriteLine($"Limpando dados da {_redacao} anterior...");
}
public override void VerificarPrerequisitos()
{
Console.WriteLine($"Verificando os pré-requisitos de correção da {_redacao}");
}
}
```
## VISITOR
##### tags: `Padrões de projetos` `Padrões comportamentais`
### Intenção
Este padrão tem por objetivo representar uma operação a ser executada nos elementos de uma estrutura de objetos. Visitor permite definir uma nova operação sem mudar as classes dos elementos sobre os quais opera (*Gamma et al., 1955*).
### Descrição
Este padrão pode ser aplicado quando é necessário executar operações em objetos concretos, porém esses objetos contêm uma estrutura com muitas classes com interfaces diferentes. Ou seja, no caso em que essas operações distintas necessitam ser executadas sem causar um acoplamento entre a classe cliente e elementos concretos. A solução proposta por este padrão consiste na criação de duas hierarquias de classes, uma para os elementos que recebem as operações e outra para os visitantes que definem as operações.
### Benefícios
Facilidade na adição de novas operações que dependem de objetos complexos.
### Frequência de uso
Nível 1
### Participantes
* **Visitor** - Declara uma operação *Visit* para cada *ConcreteElement* na estrutura do objeto; o visitante pode acessar o elemento diretamente através da interface específica;
* **ConcreteVisitor** - Implementa cada operação (fragmento do algoritmo) declarada por *Visitor*;
* **Element** - Define a operação *Accept* que aceita o visitante;
* **ConcreteElemente** - Implementa a operação *Accept*;
* **ObjectStructure** - Pode enumerar seus elementos; pode fornecer uma interface para visitações; pode ser uma composição ou coleção;
### Diagrama

### Exemplo
```csharp
class Program
{
static void Main(string[] args)
{
// Configurar a estrutura
ObjectStructure obj = new ObjectStructure();
obj.Attach(new ConcreteElementA());
obj.Attach(new ConcreteElementB());
// criar os visitors
ConcreteVisitor1 v1 = new ConcreteVisitor1();
ConcreteVisitor2 v2 = new ConcreteVisitor2();
// estrutura aceitar visitors
obj.Accept(v1);
obj.Accept(v2);
}
}
public abstract class Visitor
{
public abstract void VisitConcreteElementA(ConcreteElementA concreteElementA);
public abstract void VisitConcreteElementB(ConcreteElementB concreteElementB);
}
public class ConcreteVisitor1: Visitor
{
public override void VisitConcreteElementA(ConcreteElementA concreteElementA)
{
Console.WriteLine($"{concreteElementA.GetType().Name} visitado por {this.GetType().Name}");
}
public override void VisitConcreteElementB(ConcreteElementB concreteElementB)
{
Console.WriteLine($"{concreteElementB.GetType().Name} visitado por {this.GetType().Name}");
}
}
public class ConcreteVisitor2: Visitor
{
public override void VisitConcreteElementA(ConcreteElementA concreteElementA)
{
Console.WriteLine($"{concreteElementA.GetType().Name} visitado por {this.GetType().Name}");
}
public override void VisitConcreteElementB(ConcreteElementB concreteElementB)
{
Console.WriteLine($"{concreteElementB.GetType().Name} visitado por {this.GetType().Name}");
}
}
public abstract class Element
{
public abstract void Accept(Visitor visitor);
}
public class ConcreteElementA: Element
{
public override void Accept(Visitor visitor)
{
visitor.VisitConcreteElementA(this);
}
public void OperationA()
{
}
}
public class ConcreteElementB: Element
{
public override void Accept(Visitor visitor)
{
visitor.VisitConcreteElementB(this);
}
public void OperationB()
{
}
}
public class ObjectStructure
{
private List<Element> _elements = new List<Element>();
public void Attach(Element element){
_elements.Add(element);
}
public void DeAttach(Element element){
_elements.Remove(element);
}
public void Accept(Visitor visitor){
foreach (var element in _elements)
{
element.Accept(visitor);
}
}
}
```