Escolar Documentos
Profissional Documentos
Cultura Documentos
0 Curtiram
... SHARES
Compartilhe!
Antes de iniciar falando de padrões de projetos, vamos falar da base que deu origem aos
mesmos. Vamos falar um pouco sobre os princípios de design ou projeto de software
conhecidos também como boas práticas no desenvolvimento de software.
1. Rigidez – É difícil mudar, porque cada mudança afeta muitas outras partes do sistema;
2. Fragilidade – Quando você faz uma alteração, partes inesperadas do sistema
‘quebram’;
3. Imobilidade – É difícil reutilizar noutra aplicação, porque não pode ser desembaraçada
da aplicação atual.
Existe uma série de princípios comuns de projeto que, assim como os padrões de
projeto, se tornaram as melhores práticas ao longo dos anos e ajudou a formar uma base
sobre a qual a criação e manutenção de software pode ser construída. Vejamos os
princípios mais importantes:
O princípio Tell, Don’t ASK (Diga, não pergunte) está estreitamente alinhado com o
encapsulamento e a atribuição de responsabilidades às suas classes. O princípio, afirma
que você deve dizer aos objetos quais ações você deseja que eles realizem, em vez de
realizar perguntas sobre o estado de um objeto e depois fazer uma decisão sobre a ação
que você deseja realizar. Isso ajuda a alinhar as responsabilidades e evitar forte
acoplamento entre as classes.
A palavra SOLID é um acróstico onde cada letra significa a sigla de um princípio: SRP,
OCP, LSP, ISP e DIP. Os princípios SOLID para programação e projeto orientados a
objeto são de autoria de Robert C. Martin (mais conhecido como Uncle Bob) e datam
do início de 2000.
Obs: Os acrósticos são formas textuais onde a primeira letra de cada frase ou verso
formam uma palavra ou frase.
Na tabela abaixo vemos cada sigla, o seu significado e um resumo do princípio a que se
refere no original e em uma tradução livre.
The Single Responsibility
Uma classe deve ter um, e somente um, motivo para
Principle
SRP mudar.
Principio da Responsabilidade
A class should have one, and only one, reason to change.
Única
O princípio DIP versa sobre como isolar suas classes de implementações concretas e
fazendo-as depender de classes abstratas ou interfaces. Ele promove o mantra de
codificar para uma interface ao invés de fazê-lo para uma implementação, o que
aumenta a flexibilidade dentro de um sistema garantindo que o mesmo não está
fortemente acoplado a um implementação.
Dependency Injection (DI) and Inversion of Control (IoC) – Injeção de dependência e
Inversão de Controle
Padrões de projetos
Infelizmente não existe nenhum framework que aplique de forma automática os padrões
de projetos à sua aplicação. Ao invés disso, você normalmente faz isso refatorando o
seu código e generalizando o seu problema e não abrindo um manual de receitas e
copiando soluções.
Os padrões de projeto não são a panaceia universal ou a bala de prata que vai resolver
tudo para você. Você tem que compreender plenamente o seu problema, generalizá-lo e,
em seguida, aplicar um padrão que se ajuste ao seu cenário. No entanto, nem todos os
problemas requerem um padrão de projeto. É verdade que os padrões de projeto podem
ajudar a tornar simples problemas complexos, mas eles também podem tornar
complexos problemas simples.
Repito mais uma vez: você não é obrigado a usar os padrões de projeto em todos os seus
projetos. Se você chegou a uma solução para um problema que é simples, clara e de
fácil manutenção, mas ela não se encaixa em nenhum dos 23 padrões de projeto
catalogados, não se apavore; você fez a coisa certa. Se você seguir outro caminho,
apenas por modismo, isso vai complicar o seu projeto.
Eu sei que apesar de todo o conhecimento que se pode ter de padrões de projeto sempre
fica aquela dúvida: Como escolher e como aplicar um padrão de projeto? Bem, não
existe uma receita pronta, mas podemos facilitar a nossa decisão seguindo alguns
conselhos.
Você pode escolher dentre muitos padrões de projetos já existentes e catalogados. Como
então identificar aquele que é mais apropriado para o seu problema?
Para saber qual padrão de projeto você pode usar e como aplicar o modelo ao seu
problema específico é importante compreender e utilizar alguns conceitos:
1. Você não pode aplicar padrões sem conhecê-los bem. O primeiro passo a dar é
expandir o seu conhecimento e estudar os padrões e princípios na forma concreta e
abstrata. Você pode implementar padrões de projetos de muitas formas e quanto mais
você conhecer sobre as diferentes implementações possíveis mais você irá
compreender sobre o real objetivo do padrão e de como um padrão pode possuir
diferentes implementações.
5. Encapsule o que varia. Olhe para o que provavelmente vai mudar com a sua aplicação.
Se você sabe que um algoritmo vai mudar ao longo do tempo, olhe para um padrão
que vai ajudar você a alterá-lo sem afetar o resto de sua aplicação.
7. Quando se trata de padrões de projeto, não há substituto para estudar. Quanto mais
você saber sobre cada um dos padrões, melhor equipado você estará em aplicá-los.
Procure captar a intenção de cada padrão para refrescar sua memória para quando
você tiver um problema e estiver procurando uma solução.
8. Um exercício de aprendizado é tentar identificar os padrões aplicados na plataforma
.NET. Por exemplo, o recurso de cache no ASP.NET usa o padrão Singleton, a criação de
um novo GUID usa o padrão Factory, as classes que tratam XML usam o padrão
Factory, etc. Isso ajuda no seu entendimento de como aplicar os padrões.
Estes são alguns conselhos práticos que podem ajudar você a melhor compreender como
usar e aplicar os padrões de projeto, mas existe um caminho mais adequado: sujar as
mãos.
Na segunda parte deste artigo eu vou mostrar um exemplo prático de como podemos
identificar e aplicar padrões de projetos usando um cenário básico de um situação real.
0 Curtiram
... SHARES
Compartilhe!
Na primeira parte deste artigo demos alguns conselhos para ajudar a identificar e aplicar
padrões de projetos. Agora vamos por em prática toda essa teoria em um exemplo
simples e objetivo.
É muito bom falar sobre como os padrões e princípios são importantes e podem nos
ajudar, mas mais importante é vê-los em ação na prática. Com isto em mente, este artigo
examina como um simples pedaço de código ASP.NET que você já deve ter visto
inúmeras vezes antes pode ser melhorado com o uso de padrões de projetos.
Na figura abaixo vemos o diagrama de classe contendo uma classe ProdutoService com
o método GetTodosProduto, uma classe Produto, que representa os produtos da loja, e
uma classe ProdutoRepository que é usada para recuperar os produtos de um banco de
dados.
O trabalho da classe ProdutoService é coordenar a recuperação de uma lista de produtos
a partir do repositório para um dado código (ID) de categoria e depois armazenar os
resultados em cache de forma que a próxima chamada possa ser executada mais
rapidamente.
Vamos, então, criar um projeto usando o Visual Studio Express 2012 for web, criar as
classes e examinar o código.
Abra o VS Express 2012 for web e no menu Start clique em New Project. A seguir
selecione template Other Project Types-> Visual Studio Solutions -> Blank Solution ,
informe o nome ASPNET_PadraoProjeto e clique no botão OK.
A seguir, no menu FILE clique Add -> New Project e selecione o template Visual C# ->
Class Library informando o nome ASPNET_PadraoProjeto_Service e clique no
botão OK.
Vamos incluir uma nova classe, chamada ProdutoRepository, via menu PROJECT ->
Add Class contendo o seguinte código:
Crie agora a classe ProdutoService via menu PROJECT -> Add Class com o código
mostrado a seguir.
Observe que temos que incluir uma referência a System.Web ao projeto pois estamos
usando a classe HttpContext que encapsula todas as informações do HTTP específico
sobre uma solicitação HTTP individual.
Mas então, o que esta errado com o código acima? Você saberia identificar quais os
problemas ele carrega?
Agora que você já sabe o que esta de errado com o código acima vem a pergunta que
não quer calar: quais as providências você deverá tomar para melhorar o código usando
padrões de projetos? Vamos começar com o problema da dependência entre
classe ProductService e a classe ProductRepository.
Este princípio nos diz que não podemos depender de uma classe concreta, mas de uma
interface: programe para uma interface e não para uma implementação (classe concreta).
Devemos criar a interface IProdutoRepository, via menu PROJECT-> Add New Item,
com o código mostrado a seguir:
Finalmente precisamos atualizar a classe ProdutoService para garantir que ele faz
referência a interface ao invés da classe concreta:
O que você conseguiu através da introdução de uma nova interface?
A classe ProductService agora depende apenas de uma abstração em vez de uma classe
concreta, o que significa que a classe agora é completamente ignorante de qualquer
implementação, assegurando que ela é menos frágil e que o seu código base é menos
sujeito a mudanças.
Aqui entra a Injeção de dependência para nos ajudar a solucionar este problema.
5 _produtoRepository = produtoRepository;
Isso permite que um substituto possa ser passado para a classe ProdutoService durante
os testes, o que permite que você teste a classe isoladamente.
A injeção de dependência pode ser aplicada de três maneiras distintas: via Construtor,
Método e Propriedade. Usamos neste nosso exemplo a injeção de dependência via
construtor.
A última coisa que precisamos fazer agora é resolver a dependência do contexto HTTP
para o cache. Para isso, vamos contratar os serviços de um padrão de design simples.
Refatorando o padrão Adapter
Como não temos o código-fonte para a classe de contexto HTTP, não podemos
simplesmente criar uma interface da mesma forma que fizemos para a
classe ProdutoRepository.
Felizmente, esse tipo de problema foi resolvido inúmeras vezes antes, e existe um
padrão de projeto pronto para nos ajudar: o padrão de projeto Adapter.
O padrão Adapter basicamente traduz uma interface para uma classe em uma interface
compatível para que você possa aplicar esse padrão e mudar a API Context cache HTTP
para uma API compatível que você deseje usar. Então, você pode injetá-la através de
uma interface para a classe ProdutoService usando o príncipio da injeção de
dependência.
Vamos criar uma interface chamada ICachePersistencia, via menu PROJECT-> Add
New Item -> Interface, com o seguinte código:
Agora que temos a nova interface, podemos atualizar a classe ProdutoService para usá-
la ao invés de usar a implementação do contexto HTTP.
Como o padrão Adapter pode ser usado para nos salvar desse impasse? Qual o objetivo
do padrão Adapter? É converter a interface de uma classe em outra interface esperada
pelos clientes. E é exatamente isso que precisamos aqui.
fonte: https://www.l2f.inesc-
id.pt/~david/wiki/pt/index.php/Adapter_Pattern_(padr%C3%A3o_de_desenho)
Como vemos na figura, um cliente tem uma referência a uma abstração – o
Target. Neste caso, esta é a interface ICachePersistencia.
Assim, inclua uma nova classe no projeto, via menu PROJECT -> Add Class,
chamada HttpContextCacheAdapter.cs com o seguinte código no projeto:
Agora é mais fácil implementar uma solução de cache nova, sem afetar qualquer código
existente. Por exemplo, se você quiser usar o Velocity, tudo que você precisa fazer é
criar um adaptador que permite que a classe ProdutoService possa interagir com o
provedor de cache de armazenamento através da interface comum ICachePersistencia.
O padrão Adapter também é simples. Seu único propósito é fazer com que as classes
com interfaces incompatíveis trabalhem em conjunto.
O adaptador não é o único padrão que pode nos ajudar com o cache de dados. Existe um
padrão de projeto chamado Proxy que também pode ser usado mas isso é assunto para
outro artigo.
Vimos assim como a aplicação de alguns padrões básicos pode desacoplar o seu código,
tornando-o mais robusto e testável.