Neste artigo vou mostrar como podemos aplicar os conceitos da programação orientada a objetos (POO) na prática para criar um código limpo e fácil de manter. |
Os conceitos da programação orientada a objetos (POO) já não são novidades para quem atua na área de TI. O mínimo que se espera de um bom desenvolvedor que atue na área é que ele conheça bem os conceitos da POO e saiba aplicá-los no seu dia a dia.
Pensando nisso resolvi escrever este artigo e mostrar como podemos aplicar os conceitos da POO para realizar uma tarefa simples.
Nosso objetivo será criar um projeto que permita de forma simples e rápida carregar, ler e salvar informações de configurações personalizadas.
A primeira questão que pode vir a sua mente quando você se debruçar sobre essa tarefa é procurar saber qual o tipo de informações pretendemos acessar : XML, JSON , arquivos INI, etc. ?
Na verdade, o objetivo é criar um projeto genérico que possa tratar com quaisquer tipo de informações, incluindo tipos de dados que ainda não conhecemos.
Você agora pode estar pensando: "Essa tarefa esta ficando complicada...", e, você tem toda a razão, se a abordagem adotada para resolver o problema não usar os conceitos da POO.
Se você estiver pensando em criar classes concretas para carregar, ler e salvar informações de configuração então eu já lhe adianto que você vai conseguir concluir o projeto mas com certeza o código vai te dar muito trabalho.
Aplicando os conceitos da POO podemos usar Generics e Interfaces, e, nessa tarefa é isso o que faremos para mostrar todo o poder da POO.
Então vamos ao código...
Recursos usados:
Nota: Baixe e use a versão Community 2015 do VS ela é grátis e é equivalente a versão Professional.
Criando o projeto no VS Community
Abra o VS Community 2015 e clique em New Project;
Selecione a linguagem Other Project Types -> Visual Studio Solutions;
Selecione o template Blank Solution e informe o nome Aplicando_Conceitos_OOP e clique no botão OK;
Será criada uma solução vazia onde iremos incluir nossos projetos.
Criando o projeto para a definição do Gerenciador de Configurações
Vamos criar um projeto do tipo Class Library em nossa solução e neste projeto definir o nosso Gerenciador de Configurações.
Fazendo assim teremos ao final uma DLL que pode ser distribuída.
No menu File clique em Add -> New Project ;
Selecione o template Class Library e informe o nome Gerenciador_Configuracoes e clique em OK;
Se pensarmos em um gerenciado de configurações que realize as tarefas básicas então teremos que implementar as seguintes funcionalidades:
Vamos iniciar criando uma interface chamada ISerializeTool que importa e exporta dados para string e arquivos.
No Project clique em Add -> New Item e selecione o template Interface e informe o nome ISerializeTool e digite o código abaixo nesta interface:
public interface ISerializeTool
{
string ExportarParaString<T>(T obj);
T ImportarDeString<T>(string obj);
void ExportarParaArquivo<T>(T obj, string arquivo);
T ImportarDoArquivo<T>(string caminho);
}
|
Vamos definir outra interface chamada ISettings que dever definir um contrato para carregar e salvar informações. O código pode ser visto a seguir:
public interface ISettings<out T>
{
T Atual { get; }
void Salvar(string destino = "");
void Carregar(string localizacao = "");
}
|
Aqui usamos a premissa da POO : "Programe para uma interface e não para uma implementação"
Definimos as funcionalidades em interfaces distintas para estar aderente ao princípio ISP (Princípio da segregação da interface).
Assim já temos um contrato que permite implementar funcionalidades para serializar objetos e strings e arquivos e também carregar e salvar informações.
A utilização de interfaces permite que o nosso código fique com um baixo acoplamento, ou seja, com poucas dependências, e, isso é uma boa prática.
Implementando a interface ISettings : Carregando e Salvando informações
Vamos implementar as funcionalidades para carregar e salvar informações criando a classe concreta GerenciaConfiguracao() via menu Project -> Add Class;
A seguir inclua o código abaixo nesta classe :
using System.IO;
namespace Gerenciador_Configuracoes
{
public class GerenciaConfiguracao<T> : ISettings<T>
{
public T Atual { get; set; }
public string CaminhoPadrao { get; set; }
public ISerializeTool SerializarConfiguracoes { get; set; }
public void Carregar(string localizacao = "")
{
try
{
if (string.IsNullOrEmpty(localizacao))
localizacao = CaminhoPadrao;
if (!File.Exists(CaminhoPadrao))
throw new FileNotFoundException("Dados de configuração não existem.");
Atual = SerializarConfiguracoes.ImportarDoArquivo<T>(CaminhoPadrao);
}
catch
{
throw;
}
}
public void Salvar(string destino = "")
{
try
{
if (string.IsNullOrEmpty(destino))
destino = CaminhoPadrao;
SerializarConfiguracoes.ExportarParaArquivo(Atual, destino);
}
catch
{
throw;
}
}
}
}
|
A classe concreta implementa a interface ISettings e possui o método para converter de json para object e de object para json.
Implementando a interface ISerializeTool : Serializando informações XML
Agora vamos implementar a interface ISerializeTool que cuida da serialização das informações.
Vamos fazer uma implementação considerando a abordagem XML e para isso vamos criar a classe concreta XmlSerializeTool e definindo o código abaixo nesta classe:
using System.IO;
using System.Text;
using System.Xml.Serialization;
namespace Gerenciador_Configuracoes
{
public class XmlSerializeTool : ISerializeTool
{
public void ExportarParaArquivo<T>(T obj, string arquivo)
{
using (var gravarArquivo = new StreamWriter(arquivo, false, Encoding.UTF8))
{
gravarArquivo.Write(ExportarParaString(obj));
}
}
public string ExportarParaString<T>(T obj)
{
var serializer = new XmlSerializer(typeof(T));
using (var gravarString = new StringWriter())
{
serializer.Serialize(stringWriter, obj);
return gravarString.ToString();
}
}
public T ImportarDeString<T>(string obj)
{
var serializer = new XmlSerializer(typeof(T));
using (var gravarString = new StringReader(obj))
{
return (T)serializer.Deserialize(gravarString);
}
}
public T ImportarDoArquivo<T>(string arquivo)
{
using (var leitorArquivo = new StreamReader(arquivo, Encoding.UTF8))
{
return ImportarDeString<T>(leitorArquivo.ReadToEnd());
}
}
}
}
|
Testando a implementação em um projeto Console
Vamos criar um projeto Console Application para testar a nossa implementação
No menu File clique em Add -> New Project ;
Selecione o template Console Application e informe o nome Testando_Projeto e clique em OK;
Clique com o botão direito sobre o nome do projeto e a seguir em Add Reference;
Vamos marcar uma referência ao projeto Gerenciador_Configuracoes conforme mostra a figura a seguir:
Agora vamos definir o código que usa os recursos implementados para um tipo definido que chamamos GeradorConfiguracaoAleatorio para um arquivo XML de configurações com nomes e sobrenomes.
Digite o código abaixo no arquivo Program.cs do projeto Console :
using System;
using System.Collections.Generic;
using Gerenciador_Configuracoes;
namespace Testando_Projeto
{
public static class Program
{
public static ISettings<GeradorConfiguracaoAleatorio> GerenciaConfiguracao { get; set; }
static void Main(string[] args)
{
// cria as configurações com nomes e sobrenomes
var configuracoes = new GerenciaConfiguracao<GeradorConfiguracaoAleatorio>
{
SerializarConfiguracoes = new XmlSerializeTool(),
CaminhoPadrao = @"c:\dados\xml\MacTeste.xml",
Atual = new GeradorConfiguracaoAleatorio
{
Nomes = new List<string> { "José Carlos", "Miriam", "Jessica" },
SobreNomes = new List<string> { "Macoratti", "Siqueira","" }
}
};
// Define ISettings com nossa implementação
GerenciaConfiguracao = configuracoes;
// Salva as configurações para o arquivo e as carrega do arquivo
GerenciaConfiguracao.Salvar();
GerenciaConfiguracao.Carregar();
// Exibe os nomes da configuração atual
foreach (var config in GerenciaConfiguracao.Atual.Nomes)
{
Console.WriteLine(config);
}
// Adiciona um nome na configuração
GerenciaConfiguracao.Atual.Nomes.Add("Janice");
// Salva para o arquivo novamente
GerenciaConfiguracao.Salvar();
// Limpa os nomes atuais
GerenciaConfiguracao.Atual.Nomes.Clear();
// Carrega as configurações novamente do arquivo padrão
// que nos dará os novos dados que foram alterados
GerenciaConfiguracao.Carregar();
// Verifica
Console.WriteLine("---------------------------------------");
foreach (var configuracao in GerenciaConfiguracao.Atual.Nomes)
{
Console.WriteLine(configuracao);
}
Console.ReadKey();
}
}
public class GeradorConfiguracaoAleatorio
{
public List<string> Nomes { get; set; }
public List<string> SobreNomes { get; set; }
}
}
|
|
Abaixo do código vemos o resultado da aplicação Console o arquivo XML MacTeste.xml gerado na pasta c:\dados\xml.
Podemos conferir a flexibilidade do código implementado usando os recursos das interfaces e Generics.
Deixo para você fazer a implementação para arquivos INI ou JSON como um exercício.
Pegue o projeto completo aqui : Aplicando_Conceitos_POO.zip
Jesus Cristo é o mesmo, ontem, e hoje, e
eternamente.
Hebreus 13:8
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a Objetos com VB .NET