Por que eu devo ler este artigo:Há situações onde classes se encontram fortemente acopladas, pois precisa comunicar-se entre si, de forma que uma precise conhecer diretamente a estrutura da outra.

Porém, essa “intimidade inapropriada” gera diversos problemas no design do sistema, como duplicação e rigidez no código, resultando em maior custo de manutenção e menor poder de expansão, uma vez que certas classes foram projetadas para trabalhar com outra bem definida, sem possibilidade de substituição desta por outra semelhante.

Portanto este artigo apresentará uma técnica de comunicação para um design flexível do sistema utilizando o padrão de projeto Event Aggregator, que diminui o acoplamento entre as classes e facilita a manutenção.

Construir um sistema de qualidade não significa apenas construir boas interfaces gráficas ou possuir diversas funcionalidades.

Um sistema de qualidade deve possuir por trás de suas funcionalidades e estética um código flexível, maleável, que seja altamente adaptativo, não sofrendo muito com mudanças que possam surgir futuramente.

Para que tal código seja obtido, existem diversos conceitos e técnicas prontas chamadas padrões de projeto (design patterns).

Padrões de projeto são modelos orientados a objeto que em geral visam o chamado desacoplamento entre classes utilizando os quatro pilares principais da orientação a objetos: encapsulamento, herança, polimorfismo e principalmente abstrações. Abstrações são extremamente importantes e fundamentais em um sistema orientado a objetos porque o torna flexível, eliminando fortes acoplamentos entre partes de um sistema.

Tais acoplamentos podem surgir de diversas formas: você pode criar um forte acoplamento entre duas e mais classes através de novas instâncias, de uma chamada a um método que está em outra classe, de uma programação voltada para implementações, de eventos, entre outros.

Eventos? Você deve estar se perguntando como eventos geram acoplamentos se os mesmos são muitos utilizados para o desacoplamento entre classes. O evento gera o desacoplamento da classe publicadora, o Publisher, pois a mesma não conhece as classes que assinarão seu evento, mas o assinante do evento, Subscriber, precisa de alguma maneira acessar o evento da classe publicadora para assiná-lo com seu método, gerando um acoplamento na classe assinante com a classe publicadora.

Tal acoplamento se torna ainda pior se o evento a ser disparado precisa ser replicado em outras classes publicadoras para determinada sincronização depois de certo procedimento, precisando portanto serem assinados na classe assinante com o mesmo método.

Com isso, a cada classe publicadora que necessite surgir, essa classe terá que ser referenciada na classe assinante para que o evento seja assinado, gerando mais um acoplamento, como ilustra a Figura 1.


abrir imagem em nova janela
Figura 1.
Representação do acoplamento na classe assinante.

Este bad-smell (BOX 1) fere um bom princípio de desenvolvimento do conjunto S.O.L.I.D., que é a segunda letra da sigla que significa Open-Closed Principle ou o Princípio do Aberto-Fechado. Este princípio sugere que uma classe deve ser fechada para mudanças, mas aberta para ser estendida. No ilustrado, novas funcionalidades não são adicionadas dinamicamente porque o código é rígido.

O Event Aggregator é um padrão de projeto que visa desacoplar as classes assinantes das classes publicadoras, resolvendo além desse problema, a temida duplicação de código.

A linguagem C#, juntamente com o .NET Framework fornece diversas ferramentas que serão utilizadas na implementação do padrão. Neste artigo serão abordados os usos de genéricos ou tipos parametrizados, reflexão, métodos anônimos e coleções.

Será abordado também o uso de Singletons para instância única e algumas outras funcionalidades da linguagem que serão explicadas ao longo do artigo.

BOX 1. Bad smells no código

Este termo, aparentemente criado por Kent Beck, se refere a toda má pratica no código criando acoplamentos, duplicação de código, má interpretação no código-fonte, entre outros problemas que necessitam de técnicas de refatoração.

Para melhor entendimento do Event Aggregator, um exemplo prático será apresentado ao leitor. Este exemplo irá se iniciar com um sistema de estoque de três forms apenas, onde haverá um form inicial responsável por exibir os produtos, que irá invocar os outros dois forms: um de cadastro de produtos e o outro para modificações em um produto selecionado.

Será montado o cenário onde o problema de acoplamento ocorre na classe assinante (que será o form inicial) e futuramente tal acoplamento será banido pelo uso do padrão que será implementado desde o início.

O artigo tem como objetivo não somente mostrar e ensinar ao leitor um novo padrão de projeto, mas apresentar as ferramentas da linguagem C# em uma perspectiva diferente do que leitor pode estar acostumado, incentivando-o a usufruir melhor das poderosas armas de desenvolvimento da linguagem em seus futuros projetos. A seguir serão mostradas e explicadas todas as ferramentas da linguagem para a construção do padrão.

Genéricos ou tipos parametrizados

Tipos genéricos ou tipos parametrizados são uma poderosa ferramenta da linguagem C# que possibilita o reaproveitamento de código onde o programador especifica um tipo como parâmetro para um campo, método ou até mesmo uma classe ou interface.

Como um argumento em um método, esse tipo será definido pelo código cliente, e todo o código genérico será substituído pelo tipo recebido do código cliente, formando um código fortemente tipado e seguro.

Para melhor compreensão, imagine que você fosse implementar a coleção List. Ao implementar o método Add você percebe que o mesmo necessita receber um parâmetro que você não sabe o tipo, pois pode ser qualquer um.

Então, para formar um código mais genérico possível você fornece um tipo padrão, ancestral de todos os tipos em .NET: o tipo object. Com isso a declaração do método Add fica: Add(object value). Com este método, o código cliente poderá adicionar qualquer tipo de dado. Strings, inteiros, doubles, e até mesmo outro List, por exemplo. O problema se encontra ao consumir o conteúdo do List, como mostra a Listagem 1.

Listagem 1. Consumindo uma lista não genérica

    1.  for (i = 0, i < lista.Count; i++)  
  2.   ... 

Quer ler esse conteúdo completo? Seja um assinante e descubra as vantagens.
  • 473 Cursos
  • 10K Artigos
  • 100 DevCasts
  • 30 Projetos
  • 80 Guias
Tenha acesso completo