Patterns de Estrutura na vida real
Bem, agora que sabemos a origem, e aprendemos sobre os patterns de estrutura, vamos começar a estruturar as coisas (tum ta..), e deixar de apenas cuspir códigos no Android Studio. Caso não esteja entendo nada, pode iniciar no artigo anterior.
Pattern de estrutura, eles lidam com a maneira como objetos e classes que estão dispostos, para fins de formar estruturas mais complexas, como o nome já deixa implícito. Tem como foco obter uma maior flexibilidade no código, alterando e adicionando funcionalidades em tempo de execução.
Assim como nos padrões comportamentais, a utilização de interface e classes abstratas em heranças é também muito comum. E então foi criado os patterns abaixo.
Adapter
Adapter é bem comum no android, utilizamos normalmente em listas, mas vou dar um exemplo um pouco diferente. Este padrão vem para fornecer um link entre dois tipos incompatíveis, envolvendo o “adapter” com uma classe que suporta a interface exigida pelo cliente.
Uso o exemplo dos dados de RPG, o contrato que é feito para um D20 (Dado de 20 lados), começa a ser utilizado em um D100 (dado de 100 lados).
Como construir a solução:
- Deve criar a interface, que sera nosso contrato;
- Crie seus objetos, eles podem ser do tipo object, class e data class, utilizando nossa interface;
- Agora criaremos nosso converter ou adaptador, neste caso são os, convertD20ToD100 e convertD100toD20 ;
- Pronto agora é só testar.
Composite
Bem, ele acaba por compor os objetos em estrutura de árvore, desta forma representando hierarquia. Assim podemos tratar de maneira uniforme os objetos individualmente.
O problema que este padrão tenta resolver é da instanciação na existência de uma família de produtos ou classes.
O exemplo dado é o seguinte: você vai adicionar possiveis loots para uma dungeon.
Como construir a solução:
- Neste momento a open class Equipment, que sera nosso contrato;
- A classe Composite é o nosso gerenciador, das demais classes, parecido com um Builder;
- Agora pode ser criadas diversas classes diferentes das quais estendem nosso "contrato";
- Pronto agora é só testar.
Decorator
DINAMICAMENTE, ele agrega responsabilidades adicionais a um objeto. Ele fornece uma alternativa flexível ao uso de subclasse para extensão de funcionalidades. As vezes queremos adicionar funções individuais, e não toda uma classe.
Trocando um pouco do mundo RPG, mas vamos usar algo muito comum para o programador CAFÉÉÉ.
Como construir a solução:
- Devemos criar a interface, que sera nosso contrato.
- Vamos criar as classes Normal e Enhanced que utiliza nossa interface.;
- Mas perceba que a Enhanced recebe uma classe do tipo da interface;
- Agora criaremos nossas funções e/ou extender o que vem da interface;
- Neste casso dei override na fun de Large, e criei uma nova CoffeWithMilk, mas tem algo diferente, pois estou chamando dentro dela a fun Small….. Vamos entender;
- Pronto agora é só testar.
Facade
Bem este é claramente o nosso GRANDE contrato, ele pode ser fornecido em uma interface unificada para um conjunto de interfaces, assim como uma classe. Ela é o contrato mais alto tornando o subsistema mais fácil de utilizar. Pensa comigo que você cria um software que tem que se comunicar com outros. Não vai expor todo seu código e se for mais de uma comunicação, teria que codificar para todos… Nossa ideia aqui é criar o contrato que vai enviar e receber dados para dentro do seu software.
Vamos imaginar que precisamos expor informações dos nossos personagens da campanha para "N" provedores, desta forma vamos utilizar o nosso Repository para servir de contrato.
Como construir a solução:
- Vamos criar as classes para montar a lógica interna do nosso subsistema;
- Agora podemos criar as classes que vão ser expostas para receber no contrato, nosso caso é o User;
- Agora criamos o repository, ele vai ser o contrato para que outros sistemas possam pegar ou enviar informações;
- Pronto agora é só testar.
ProtectionProxy
Ele cria um substituto (surrogate), fornece controle a outro objeto, para controlar o acesso a este objeto. Ele é muito utilizado para adiar o custo de sua criação e inicialização até o momento que deve ser usado. Imaginem renderizar imagens, ele deveria ser rápido, mas são muito custosos, mas para que isso ocorra é necessário ser faseado a sua abertura.
Vamos dizer que como criamos o FACEDE para exportar informações dos personagens, agora precisamos enviar todos os stats do mesmo e com credencial, mas seria muito pessado ficar lendo este arquivo a todo momento, com isso criamos o nosso proxy.
Como construir a solução:
- Deve criara interface, que sera nosso contrato;
- Em nosso exemplo a classe CharStatsFile é nossa classe mais "pesada" e agora criamos SecuredFile que vai ser o nosso proxy;
- Na função read temos algumas validações, e então quando der sucesso, ou seja, o momento de executar o momento mais pessada da classe vai ser disparado;
- Desta forma só vai ser utilizado em nosso software esta classe apenas quando necessário;
- Pronto agora é só testar.
Bem chegamos ao final dos patterns de estrutura, no próximo artigo vamos ver os mais utilizados de comportamento.
Para ajudar em seus estudos podem utilizar o projeto com todos os patterns que falamos aqui.