Nenhum comentário Download


Programando em camadas (padrão MVC)

Se você leu o título e ficou pensando que iríamos falar do ASP.NET MVC, se enganou. Vamos falar nesse artigo do padrão de projeto MVC (Model View Controler) e aprender na prática, como fazer isso no Visual Studio. O MVC é um padrão de projeto que tem por finalidade, separar dados ou a lógica da aplicação (regras) da interface que o usuário visualiza.

Uma grande vantagem do MVC, é que não temos dependências entre a camada de dados e a camada de interação com o usuário, ou seja, podemos usar qualquer interface visual para o usuário. A camada do controle (regras) é que define como a aplicação funcionará. Ela que retorna os dados para a interface e que executa as ações na camada de acesso a dados.

Mas claro, temos desvantagens também, pois nesse padrão, necessitamos de uma quantidade maior de análise (tempo) para definir o projeto, além de que os profissionais que trabalham, devem ter uma experiência maior no desenvolvimento. Como também, não é recomendado o uso do MVC para pequenos projetos.

O que pretendo mostrar aqui é apenas uma ideia de como podemos desenvolver aplicações onde as regras fiquem separadas e podemos definir qual a interface visual o usuário pode usar, ou mesmo, usar mais de uma interface (aplicação Windows, Web, mobile etc).

Deixaremos uma camada apenas para trabalhar com o banco, para retornar dados e executar comandos SQL. Na Figura 1, temos um exemplo simples, de como funciona um modelo MVC.

Figura 1. Conhecendo o padrão de projeto MVC. Fonte: www.oficinadanet.com.br

Neste artigo, teremos uma camada (um projeto Class Library), responsável pelos dados, onde usaremos o Entity Framework. Outra camada (Class Library) terá os métodos que buscam os dados da camada do banco e retornam para a camada de apresentação.

 

Além disso, é responsável por executar as ações de manipulação de dados do cadastro. Outra dica importante, as validações, regras da aplicação, serão feitas nessa camada.

Qual a vantagem disso? Independente a plataforma que utilizarmos (Windows ou Web) é nessa camada que os dados serão validados, verificado a sua consistência, e não na apresentação. Por fim, a camada de apresentação, dependerá da necessidade do desenvolvedor em utilizar.

Criando o projeto

Vamos criar o projeto. Caso você queira usar a versão comercial do Visual Studio, todos os projetos podem ficar na mesma Solution. Usarei aqui, as versões Express do Visual Studio 2012, assim, são duas ferramentas separadas (Web e desktop). O fonte pode ficar organizado nos mesmos diretórios.

Crie um novo projeto Class Library no Visual Studio 2012 Express for Desktop. Dê o nome de “DataAccess” ao projeto. Crie um novo Class Library e dê o nome de “Business”. Crie um projeto Windows Forms e dê o nome de “DesktopApp”. Comparando com o padrão MVC, o DataAccess seria o Model, o Bussiness o Controller e a aplicação Windows seria a nossa View.

Veja na Figura 2 o Solution Explorer (arquivos Class1.cs removidos).


Figura 2.
Solution Explorer com os projetos de exemplos

No projeto DataAccess vamos conectar com o banco de dados e usar o Entity Framework. Acesse Add>New Item no menu de contexto do projeto e no editor escolha ADO.NET Entity Data Model.

Nota: se você não tem experiência com o EF, indico dois artigos publicados na The Club sobre o assunto, que estão na seção Links.

Não vou me apegar ao banco de dados, você pode usar um de sua preferência, ou até mesmo pode criar um modelo do zero e gerar o banco de dados. Depois de criado o modelo com o banco de dados teremos algo semelhante ao da Figura 3.


Figura 3.
Modelo do EF criado

O EF mapeia as tabelas do banco e com isso podemos trabalhar com entidades. O DataAccess será nosso Model do padrão, responsável pela conexão com os dados, ou seja, sua responsabilidade é: disponibilizar os dados quando solicitados e realizar as ações de atualização, inserção e exclusão.

Criando a camada de dados

Temos o modelo criado, agora, vamos criar as classes para manipular esse modelo criando os métodos de inserção/atualização, exclusão e pesquisas. Primeiramente, vamos criar uma classe para ser a base de todas as outras.

Clique com o botão direito no projeto e escolha Add>New Item. No editor, escolha Class, dando o nome de “BaseClass.cs”. Na Listagem 1 temos a classe base.

Listagem 1. Classe base para o projeto DataAccess

namespace DataAccess
{

  public class BaseClass<T>

  {

    public virtual bool Salvar(bool Insert, T objeto)

    {

      return false;

    }

    public virtual bool Excluir(T objeto)

    {

      return false;

    }

    public virtual T Pesquisar(int codigo)

    {

      return default(T);

    }

    public virtual List<T> PesquisarTodos()

    {

      return new List<T>();

    }

    public virtual List<T> PesquisarTexto(string descricao)

    {

      return new List<T>();

    }

  }

}

Criamos métodos virtuais que serão implementados nas classes que herdarem de BaseClass. O T indica o tipo de objeto que vamos manipular, por exemplo, para a classe de Produtos, o T será nosso mapeamento de produtos.

Vamos agora, criar uma classe que herde da base. Crie uma classe, conforme a anterior, com o nome de “dalProduto.cs”.

Nota: Dê a nomenclatura que quiser, de acordo com seus padrões de desenvolvimento.

Vamos modificar a classe, conforme o código a seguir, para herdar da BaseClass.

public class dalProduto: BaseClass<PRODUTO>

Note que precisamos especificar qual a classe que vamos usar (o T da classe base). Isso é obrigatório. Agora, temos que redeclarar os métodos virtuais da classe base, para que possamos implementar as funcionalidades da classe Produto.

Digite "public override " e será aberto um menu com os métodos virtuais da classe base. Escolha o Salvar e o Visual Studio completa a declaração do método, alterando o T pela classe indicada anteriormente (PRODUTO). Faça isso para todos os métodos.

Claro, precisamos codificar os métodos, pois como estão no momento, não executam nada. Veja na Listagem 2 a implementação de todos os métodos.

Listagem 2. Implementação dos métodos virtuais da classe base

using System.Collections.Generic;

using System.Data;

using System.Linq;

namespace DataAccess

{

  public class dalProduto: BaseClass<PRODUTO>

  {

    public override bool Salvar(bool Insert, PRODUTO objeto)

    {

      using (EntityTheClubEntities db = new EntityTheClubEntities())

      {               

        if (Insert)                   

          db.AddToPRODUTO(objeto);

        else

        {

          db.PRODUTO.Attach(objeto);                   

          db.ObjectStateManager.ChangeObjectState(objeto,

            EntityState.Modified);

        }

        return (db.SaveChanges() > 0);

      }

    }

 

    public override bool Excluir(PRODUTO objeto)

    {

      using (EntityTheClubEntities db = new EntityTheClubEntities())

      {

        PRODUTO produto = (from p in db.PRODUTO

          where p.nCdProduto == objeto.nCdProduto

          select p).FirstOrDefault();

        db.DeleteObject(produto);

 

        return (db.SaveChanges() > 0);

      }

    }

 

    public override PRODUTO Pesquisar(int codigo)

    {

      using (EntityTheClubEntities db = new EntityTheClubEntities())

      {

        return (from p in db.PRODUTO where p.nCdProduto == codigo

          select p).FirstOrDefault();

      }

    }

 

    public override List<PRODUTO> PesquisarTodos()

    {

      using (EntityTheClubEntities db = new EntityTheClubEntities())

      {

        return db.PRODUTO.ToList();

      }

    }

 

    public override List<PRODUTO> PesquisarTexto(string descricao)

    {

      using (EntityTheClubEntities db = new EntityTheClubEntities())

      {

        return (from p in db.PRODUTO

          where p.sNmProduto.ToUpper().Contains(descricao.ToUpper())

          select p).ToList();

      }   

    }

  }

}

Usamos LINQ para os métodos de pesquisa. Para o Salvar usamos os métodos do EF para inserção ou atualização do objeto Produto. O Excluir possui funcionalidade semelhante, apenas alterando o método que executa a ação. Fizemos uma pesquisa para confirmar que estamos retornando o objeto certo para a exclusão, realizando uma pesquisa pelo código, assim o objeto que passamos como parâmetro precisa ter apenas o código para excluir corretamente.

Faça o mesmo para as outras entidades do modelo. Para as entidades VENDA e VENDA_ITEM, não temos necessidade de uma funcionalidade para pesquisa de descrição, então, retorne apenas null nesses métodos. Como eles estão na classe base, devem ser declarados na classe herdade e precisam de um retorno.

Criando a camada de negócio

Agora, vamos entender o funcionamento do Business (Controller), o mais importante desse projeto em camadas. Nele vamos criar as classes que vão invocar os métodos para manipular o banco (classes criadas anteriormente no DataAccess) e também responsável por gerenciar as regras, validações etc.

Nota: precisamos adicionar ao projeto a referência ao DataAccess e na seção using adicionar “DataAccess”.

Crie uma nova classe no projeto Business (dê o nome de “balProduto.cs”) e veja na Listagem 3 o código da classe.

Nota: caso queira, você também pode fazer uma classe base com os métodos padrões e usar o mesmo conceito apresentado anteriormente.

Listagem 3. Classe para o projeto Business (Controller)

using DataAccess;

using System.Collections.Generic;

namespace Business

{

    public class balProduto

    {

        private dalProduto produto { get; set; }

 

        public balProduto()

        {

            produto = new dalProduto();

        }

 

        public bool Salvar(bool Insert, PRODUTO objeto)

        {

            return produto.Salvar(Insert, objeto);

        }

 

        public bool Excluir(PRODUTO objeto)

        {

            return produto.Excluir(objeto);

        }

 

        public PRODUTO Pesquisar(int codigo)

        {

            return produto.Pesquisar(codigo);

        }

 

        public List<PRODUTO> PesquisarTodos()

        {

            return produto.PesquisarTodos();

        }

 

        public List<PRODUTO> PesquisarTexto(string descricao)

        {

            return produto.PesquisarTexto(descricao);

        }

    }

}

Temos nesse exemplo, uma classe que apenas invoca métodos do DataAccess, usando uma propriedade privada que instanciamos no construtor da classe. Após, temos que implementar as classes de todos os objetos do EF mostrados anteriormente. Veja na Figura 4 todas as classes criadas nos dois projetos. 


Figura 4.
Classes criadas nos projetos