Desenvolvimento - C#

Padrões de Projeto com C# - parte 1

Este material ensina de maneira prática como escrever aplicações em C# fazendo uso de alguns dos mais comuns Design Patterns (Padrões de Projeto).

por José Augusto de Sousa Barroso



Prefácio

Este material ensina de maneira prática como escrever aplicações em C# fazendo uso de alguns dos mais comuns Design Patterns (Padrões de Projeto). Cada demonstração do uso dos padrões será ilustrado com diagramas UML para melhor mostrar a interação entre as classes.

Se você não possui conhecimento sobre UML, não se preocupe, teremos um breve contato com os principais diagramas antes de entrar-mos no foco principal deste material, ou seja, Padrões de Projeto em C#.

Como utilizaremos o C#, é importante salientar que, neste momento, seria melhor que você tivesse conhecimento da sintaxe da linguagem, mas de qualquer forma, estaremos vendo um pouco de C#

Algo que também é considerado muito importante neste momento, a Programação Orientada a Objeto(OOP), mas também teremos uma pequena introdução neste assunto.

Basicamente, este é um material para quem quer aprender o que são Padrões de Projeto e como utilizá-los em seu trabalho.

Neste material você vai aprender que Padrões de Projeto são maneiras de organizar objetos em suas aplicações, de modo a ficar mais fácil codificar e fazer alterações. Sem falar que, a medida em que você for se familiarizando com os Padrões de Projeto, estará adquirindo vocabulário para melhor discutir sobre como suas aplicações são construídas.

Estarei descrevendo os padrões agrupados em 3 partes: criacional, estrutural e comportamental.

Sendo assim, estarei dividindo o material em 4 partes:

Parte I: Uma visão geral
Parte II: Padrões - Criacional
Parte III: Padrões - Estrutural
Parte IV: Padrões - Comportamental

Dividindo em partes, estarei facilitando a criação do material, e além do mais, poderei disponibilizar as partes assim que as mesmas forem finalizadas, de uma em uma, até que a última parte esteja disponível também.

Por fim, estaremos desenvolvendo aplicações em C#, e o melhor de tudo, adotando boas práticas.

O que são Design Patterns?

Primeiramente, Design Patterns é a tradução em inglês para Padrões de Projeto. Pois bem, comunmente, no trabalho, nos flagramos em frente a tela do computador pensando: Como vou escrever esta nova aplicação? Intuitivamente sabemos o que queremos fazer, que tipo de dados e quais objetos deveremos criar, mas sempre vem aquele recentimentozinho incomodando de que existe uma maneira mais bacana, mais legível, ou seja, melhor de se escrever esta aplicação.

A primeira vista, você sente que uma solução bacana seria algo mais reutilizável e com mais facilidade para manutenção, e mesmo que a faça, ainda sim estará incomodado com o que fez!

Uma das principais razões que levam os pesquisadores da ciência do computação a reconhecerem Padrões de Projeto é a satisfação de se criar algo elegante, porém simples e de uma solucão bastante reutilizável.

Padrões de Projeto são apenas convenientes maneiras de se reutilizar códigos orientados a objeto entre projetos, e também, entre programadores.

A idéia por trás de Padrões de Projeto é simples - escrever e catalogar interações comuns entre objetos que programadores na maioria das vezes acharam bastante útil.

Uns dos padrões que mais tem sido citado desde muito tempo atrás é o Model-View-Controller framework para Smaltalk (Krasner e Pope 1988), que divide os problemas que encontramos na camada de apresentação em 3 partes:

- Model, que contém a parte computacional do programa;
- View, que representa a interface de usuário;
- Controller, que interage com o usuário e a View.

Os Padrões de Projetos começaram a serem mais difundidos e reconhecidos por volta de 1990 por Erich Gamma (1992). O auge das discussões e dos encontros técnicos foi com a publicação do Design Patterns - Elements of Reusable Software, por Gamma, Helm, Johnson e Vlissides (1995). Este livro, que normalmente é chamado de "Gang of Four", ou "GoF", no português, "gangue dos quatro", teve um forte impacto no que diz respeito a como usar os Padrões e acabou se tornando um bestseller. Este livro descreve os 23 padrões mais comuns e utilizados geralmente, explicando como e quando usar cada um deles. Claro que surgiram várias outras publicações sobre Design Patterns e com diferentes pontos de vista, ou seja, voltados a Smalltalk, Java, VB e sob o ponto de vista de várias outras linguagens.

Algumas definições vieram surgindo a partir de então, sempre vejo o pessoal perguntando, principalmente em foruns de discussão, como por exemplo o MSDN Brasil, e vejo várias respostas.

Mas vamos ver algumas definições mais comuns:

"Design patterns são repetidas soluções para problemas de projetos que você está sempre se deparando." (Smalltalk)

"Design Patterns é constituído por um conjunto de regras que descreve como fazer certas tarefas no conceito de desenvolvimento de aplicações" (Pree 1994)

E por aí vai, iremos encontrar várias outras definições colocadas de uma forma diferente, mas igualmente corretas. Mas veja bem, na maioria das vezes, quando estamos iniciando os estudos sobre Padrões de Projeto, começamos a pensar somente nos objetos em si, mas também devemos levar em consideração as interações entre este objetos. Que possivelmente pode ser descrito como Padrões de Comunicação.

Alguns Padrões não tratam somente da comunicação mas também das estratégias de Orientação a Objeto. São estes pontos, ou seja, são estas interações, o modo de comunicação entre os objetos, a forma elegante de reutilização e escrita que tornam os Padrões de Projeto tão importantes.

Os padrões não param por aqui, existem centenas de literatura sobre eles, muitas definições e diferentes didáticas sobre como aplicá-los. Lembro que este material é somente uma introdução aos Padrões de Projeto, inclusive sob o ponto de vista do C#, que é a linguagem que vem trabalhando e dedicando meu tempo ultimamente. Neste material, estarei descrevendo os 23 padrões descritos no livro original Design Patterns, e dando foco aos que considero mais importantes, melhor dizendo, os que são mais utilizados, pelo menos por mim (risos).

Os autores costumam dividir este padrões em três tipos, farei da mesma forma neste material, como já mencionei no prefácio, são eles:

- Criacional
- Estrutural
- Comportamental

Detalharei os 23 patterns neste aspecto, inclusive demonstrando cada um deles com a minha linguagem favorita no .Net, ou seja, o C# , e claro, sem esquecer do UML.

Uma rápida observação:

Se você realmente deseja "entrar no mundo dos padrões", aqui vai um conselho, que a princípio, não vem de minha pessoa mas já aderi à bastante tempo. A primeira coisa é aceitar a premissa de que os Padrões de Projeto são importantes no seu trabalho. Então, você vai precisar estudá-los detalhadamente e aprender a saber quando deve ser utilizado cada um deles respectivamente para resolver um determinado problema.

Volto a repetir, este material está muito bom e após sua leitura você estará com uma boa base para poder aplicar alguns dos padrões de maneira correta, mas atento, continue estudando, leia outras livros, entre em foruns específicos, e a propósito, seja sempre bem vindo ao Dot Net Architect User Group - DNAUG (www.dnaug.com), lá você estará sempre que possível sendo informado e até mesmo participando dos encontros e eventos do grupo, será um prazer tê-lo na comunidade.

Notas sobre Orientação a Objeto

Existem várias razões para fazer uso dos Padrões de Projeto, mas a fundamental razão para utilizá-los é deixar as classes separadas e prevenir delas terem conhecimentos demais entre elas. Igualmente importante é, o uso destes padrões no auxílio de você evitar "reinventar a roda" e também, permitir que você descreva suas aplicações de uma forma sucinta, clara e que facilmente possa ser entendida por outros programadores. Sendo assim, porque não utilizar UML não é mesmo.

Pois bem, existem várias estratégias que programadores OO usam para fazer esta separação de classes que mencionei logo acima, entre elas são a herança e o encapsulamento.

Uma classe que herda de uma classe "pai" tem acesso a todos os métodos desta classe. E também tem acesso a todas as variáveis que não são privadas.

Os Padrões de Projeto sugerem o seguinte:

- Programe para uma interface e não para uma implementação.

Para deixar isto mais claro, você deve definir o topo de qualquer hierarquia de classe como uma classe abstrata ou como uma interface, no qual não implementa nenhum método mas simplesmente define os métodos que a classe suporta. Então, em todas as suas classes derivadas você tem mais liberdade de implementar estes métodos da melhor maneira que desejar.

Outro conceito importante, Object composition. Ou seja, a construção de objetos que contém outros. Encapsulamento de vários objetos dentro de outro. Enquanto muitos dos iniciantes em OO usam herença para resolver qualquer problema. Quando você começa a desenvolver programas mais elaborados, você irá começar a apreciar os méritos da composição de objetos. Seu novo objeto pode ter a interface que é melhor para o que você quer fazer, sem ter todos os métodos da classe pai. Assim, um outro importante mandamento sugerido pelos Padrões de Projeto é:

- Dê preferência a Object composition do que a Herança.

Padrões de Projeto com C#

Discutirei cada um dos 23 padrões. Todos usam classe, interfaces e composição de objetos, usarei exemplos simples, mas que não deixarão de mostrar a fundamental "elegância" dos padrões.

Estes padrões estão agrupados por categorias como já foi mencionado, pois bem, mas alguns destes padrões são mais ou menos independentes, vou usar um exemplo para melhor explicar o que quero dizer:

- Usaremos os padrões Factory e o Command somente depois de falar-mos sobre eles.
- Usaremos o padrão Mediator várias vezes depois de falar-mos sobre ele.
- Usaremos o Memento novamente quando estivermos utilizando o padrão State, o Chain of Responsability na discussão do padrão Interpreter, e o padrão Singleton quando estiver-mos falando do padrão Flyweight.

Mas em nenhum caso utilizaremos um padrão sem que antes tenhamos falado sobre ele.

- Na medida em que formos exemplificando os padrões, veremos várias características do C#, que serão vistos nos padrões Adapter e Bridge.
- Veremos outras características do C# no padrão Abstract Factory.
- Enumeração de interface nos padrões Iterator e Composite.
- Exceptions no padrão Singleton;
- Discutiremos ADO.Net no padrão Façade.
- C# Timers no padrão Proxy.

Resumindo, cobrirei as principais características do C# e mostrarei exemplos simples de como os Padrões de Projetos podem nos ajudar a escrever programas melhores.

Neste ponto, é aconselhável que você tem conhecimento da sintaxe do C#. Facilitaria muito. Usando Classes e Objetos em C#

Usamos classes para que?

Todo programa em C# é composto por classes. Uma classe é um conjunto de métodos públicos e privados e dados privados agrupados em unidades lógicas. Normalmente, escrevemos cada classe em uma arquivo separado, embora não seja a melhor regra. Quando criamos uma classe, a mesma não é uma única entidade, você pode criar cópias ou instâncias da mesma, usando o new. Quando criamos estas instâncias, passamos dados de inicialização para a classe usando o constructor. O construtor (constructor) é um método que tem o mesmo nome da classe. Não tem nenhum tipo de retorno e pode ter zero ou mais parametros que é passado por cada instância da classe. Nos referimos como cada uma destas instâncias como objetos.

O que são Namespaces?

Namespaces é um jeito de organizar código. Ou seja, eles disponibilizam proteção de conflitos de nomes, conhecido como namespace collisions. (Colisão de nomes)

Para se criar um namespace, crie um bloco de namespace.

Para mais de uma classe em um mesmo namespace, especifique o mesmo nome de namespace.

namespace DNAUG
{
	class Exemplo
{
	…
}
}

Vejamos alguns exemplos com hierarquia de namespaces em aplicações WEB:

System.Web
System.Web.SessionState
System.Web.Services
System.Web.UI
System.Web.UI.WebControls
System.Web.UI.HTMLConstrols
System.Web.Caching
System.Web.Mail
System.Web.Security

Todos possuem classes com finalidades específicas. Por exemplo, a System.WebServices possui classes para criação e utililização de Web services.

No C#, todos os códigos estão contidos em classes, se você quer criar métodos ou propriedades que possam ser chamados sem primeiro criar o objeto, declare-os como static (estáticos).

Veja os principais conceitos de OO:

  • Definition (Definição): Define classes usando o nome class. Todo o código executável é parte de uma classe.

  • Access (Acesso): Existem 5 níveis de acesso a classes e seus membros: public, protected, internal, protected internal e private.

  • Inheritance (Herança): Classes que herdam membros de classes base e override (sobrescrevem) ou overload (sobrecarregam) membros da classe herdada.

  • Constructors e Destructors (construtores e destrutores): Classes possuem constructors e destructors que são chamados quando um objeto de uma classe é criado ou destruído. Métodos construtores possuem o mesmo nome de sua classe e os destrutores são precedidos por um ~

  • Abstract classes e Interfaces (Classes abstratas e Interfaces): Você pode definir interfaces e classes abstratas, métodos e propriedades. Interfaces define os membros e parâmetros para classes que usam a interface. Membros abstratos disponibilizam os itens a serem herdados por classes derivadas deles.

Níveis de acesso a classes:

  • public: Todos os membros em todas as classes e projetos.

  • internal: Todos os membros do atual projeto.

  • protected: Todos os membros da classe atual e classes derivadas. Pode ser usado apenas nas definições dos membros, não para definição de classes.

  • protected internal: Todos os membros da classe atual e classes derivadas no projeto atual. Pode ser usada apenas em definições de membros, não para definição de classes.

  • private: Disponível apenas na classe atual.

Pois bem, o foco principal deste material é a utilização de padrões de projeto com C#.

Mas como foi dito, existem alguns pré-requisitos para melhor ser a absorção do conteúdo deste material.

É extremamente necessário que você aprofunde seus conhecimentos sobre OOP, o que descrevi acima, costumo dizer que é somente para estigar o leitor e insentivá-lo. Da mesma maneira com UML. Mas estarei assim mesmo fazendo uma breve descrição sobre cada um dos diagramas mais utilizados.

OOP está além do escopo deste material, aconselho um bom estudo sobre o assunto. Porém, estarei falando um pouco mais. Acredito que seja bastante útil e que desta maneira, funcione como mais um incentivo.

Diagramas UML

Para ilustrar os padrões, estaremos utilizando UML. Os diagramas UML foram desenvolvidos por Grady Booch, James Rumbaugh e Ivar Jacabson.

A UML pode ser utilizada para:

  • Mostrar as fronteiras de um sistema e suas principais funções utilizando atores e casos de uso.;
  • Ilustrar a realização de casos de uso com diagramas de interação;
  • Representar uma estrutura estática de um sistema utilizando diagramas de classe, como pode ser observado em um exemplo bem simples anteriormente.
  • Modelar o comportamento de objetos com diagramas de transição de estado;
  • Revelar a arquitetura física de implementação com diagramas de componente e de implantação;
  • Estender sua funcionalidade através de estereótipos.
A UML é uma linguagem padrão para especificar, visualizar, documentar, construir artefatos de um sistema e pode ser utilizada com todos os processos ao longo do ciclo de desenvolvimento e através de diferentes tecnologias de implementação.

Obs.: A UML é uma linguagem de modelagem, não uma metodologia.

O modo para descrever os vários aspectos de modelagem pela UML é através da notação definida pelos seus vários tipos de diagramas. Um diagrama é uma apresentação gráfica de uma coleção de elementos de modelo.

Modelar um sistema complexo é uma tarefa extensiva sendo necessária a descrição de vários aspectos diferentes incluindo o funcional, não funcional e organizacional. Cada visão é descrita em um número de diagramas que contém informação enfatizando um aspecto particular do sistema.

Vejamos os principais diagramas:

  1. Diagrama de classe
  2. Diagrama de caso de uso
  3. Diagramas de interação
    1. Diagrama de sequência
    2. Diagrama de colaboração
  4. Diagrama de estado
    1. Diagrama de atividade
  5. Diagrama de implementação
    1. Diagrama de componente
    2. Diagrama de implantação

Vejamos agora alguns exemplos:

Diagrama de classe

Diagrama de caso de uso

Diagrama de sequência

Diagrama de atividades

Diagrama de estados

Basicamente, utilizando como exemplo um diagrama de classes, o diagrama UML consiste de caixas que representam as classes.

Considerando uma classe

Veja código:

public class Monstro
{
	private string nome;
	private int idade;
	
	public Monstro(string nm, int ida)
{
	nome = nm;
	idade = ida;
}
public string TipoMonstro()
{
	return "domado";
}
public int getIdade()
{
	return idade;
}
public void separaMonstros() { }
}

Representação da classe em UML:

Exemplo de Herança

Veja código:

public class Monstro
{
	private string nome;
	private int idade;
	
	public Monstro(string nm, int ida)
{
	nome = nm;
	idade = ida;
}
public string TipoMonstro()
{
	return "domado";
}
public int getIdade()
{
	return idade;
}
public void separaMonstros() { }
public abstract string getHabitat(); //para Override
}

Agora, derivamos a classe BichoPapao desta e preenchemos algum código para o método getHabitat.

public class BichoPapao : Monstro
{
	public BichoPapao(string nm, int ida):base(nm, ida) {}
	
	public override string getHabitat() 
{
	return "Assustador de crianças";
}
}

Representação em UML:

A UML está além do escopo deste material, aconselho um bom estudo sobre o assunto. Porém, estarei sempre utilizando-a para podermos visualizar os padrões. Acredito que seja bastante útil e que desta maneira, funcione como mais um incentivo.

A parte I do material termina por aqui, em breve estarei disponibilizando a parte II. Divirta-se!

Para saber mais sobre o autor ou ver outros artigos, visite o DNAUG:
http://www.dnaug.com

Tire a sua dúvida na lista de discussão do DNAUG:
http://groups.yahoo.com/group/dnaug/

Fonte:

- MSDN Library
- Padrões de Projeto - Soluções Reutilizáveis de software Orientado a Objetos
- Utilizando UML e Padrões
- Design Patterns - Elements of Reusable Software
- Introduction to Design Patterns in C#

Conheça o Curso Padrões de Projeto com C# da DevMedia

José Augusto de Sousa Barroso

José Augusto de Sousa Barroso - Fundador do DNAUG e INETA - DNAUG Leader
Atualmente é colaborador da Politec Informática, trabalha como arquiteto e desenvolvedor de aplicações em C#. Participou de grandes projetos, citando como exemplo, sistemas para o Banco do Brasil, Caixa Econômica Federal, Agência Nacional de Energia Elétrica, Banco Central do Brasil entre outros.
Vem participando de projetos em .NET desde o início de 2003. Hoje está envolvido na criação e implementação da arquitetura em camadas para os sistemas do Governo do Distrito Federal, este em .NET
Tem publicado vários artigos sobre arquitetura, padrões, segurança, .NET Framework e C#.

Certificações:
. Microsoft Certified Professional - MCP . Microsoft Certified Application Developer - MCAD

Áreas de interesse:
· Arquitetura e Padrões de Projeto
· Segurança de aplicações
. Framework .NET / C#