Design Pattern MVC – Arquitetura de Software Coesa e Flexível

12
Design Pattern MVC – Arquitetura de Software Coesa e Flexível Ryan Bruno C Padilha [email protected] http://ryanpadilha.com.br Objetivo deste artigo O objetivo deste artigo é fornecer uma visão geral da utilização do design pattern MVC ModelViewController no Object Pascal, que é um padrão de projeto arquitetural utilizado como boa prática na construção de softwares orientados a objetos reutilizáveis e eficientes. Idealizado por Trygve Reenskaug no final dos anos 70, foi na época uma das maiores contribuições na área de desenvolvimento de software de todos os tempos. Objetiva a organização da aplicação em camadas – separando a lógica de negócio da camada de apresentação utilizando como mediador um controlador. Na série de artigos sobre o paradigma orientado a objetos escrito por mim e publicado nas edições 86 a 88, fora desenvolvido um módulo de controle de estoque do qual continha um cadastro de empresa, este cadastro será remodelado aplicando o design pattern MVC e para simplificar o desenvolvimento reforçaremos novamente a utilização da notação UML, que oferece uma documentação padronizada do projeto de software e como seus elementos interagem entre si. 1. Introdução O conceito padrão de projeto foi utilizado pela primeira vez na década de 70 pelo arquiteto e urbanista austríaco Christopher Alexander. Ele observou que as construções embora fossem diferentes em vários aspectos, todas passavam pelos mesmos problemas na hora de se construir. Eram problemas que se repetiam em todas elas e na mesma fase de construção. Com isso Christopher iniciou o processo de documentar estes problemas e as soluções que eram aplicadas para resolução destes problemas. Até nesse ponto na história, não há nada de desenvolvimento de software e sim o surgimento de padrões de projetos para a engenharia civil, padrões que descrevem os problemas recorrentes em um projeto de engenharia e a solução reutilizável para este problema. Paralelamente a isso no final da década de 70, exatamente em 1978 – no Xerox Palo Alto Research Laboratory (PARC), o cientista Trygve Reenskaug iniciou a escrita do mais importante artigo para a engenharia de software intitulado a princípio como ModelViewEditor, porém foi descrito em sua primeira dissertação como “ThingModelViewEditor – an Example from a planningsystem” (Maio de 1979). Após longas discussões, particularmente com Adele Golberg, finalmente apresentou o termo acima como ModelViewControllers, descrito em sua segunda dissertação (Dezembro de 1979). A primeira versão do padrão MVC foi implementada na biblioteca de classes do Smalltalk80 logo após Trygve deixar o Xerox PARC, não trabalhou diretamente neste projeto, sua contribuição foi através das dissertações. Para ter acesso as publicações de Trygve, acesse http://heim.ifi.uio.no/~trygver/themes/mvc/mvcindex.html. O MVC até aquele momento tinha sido definido como um padrão arquitetural para o desenvolvimento de softwares orientados a objetos, o termo design patterns (padrões de projetos) somente foi definido anos mais tarde dentro da área da ciência da computação.

Transcript of Design Pattern MVC – Arquitetura de Software Coesa e Flexível

Page 1: Design Pattern MVC – Arquitetura de Software Coesa e Flexível

Design  Pattern  MVC  –  Arquitetura  de  Software  Coesa  e  Flexível  

Ryan  Bruno  C  Padilha  [email protected]  

http://ryanpadilha.com.br  

Objetivo  deste  artigo  

O   objetivo   deste   artigo   é   fornecer   uma   visão   geral   da   utilização   do   design   pattern   MVC   -­‐  Model-­‐View-­‐Controller   no   Object   Pascal,   que   é   um   padrão   de   projeto   arquitetural   utilizado  como  boa  prática  na   construção  de   softwares  orientados  a  objetos   reutilizáveis   e  eficientes.  Idealizado   por   Trygve   Reenskaug   no   final   dos   anos   70,   foi   na   época   uma   das   maiores  contribuições   na   área   de   desenvolvimento   de   software   de   todos   os   tempos.   Objetiva   a  organização   da   aplicação   em   camadas   –   separando   a   lógica   de   negócio   da   camada   de  apresentação   utilizando   como   mediador   um   controlador.   Na   série   de   artigos   sobre   o  paradigma   orientado   a   objetos   escrito   por   mim   e   publicado   nas   edições   86   a   88,   fora  desenvolvido  um  módulo  de  controle  de  estoque  do  qual  continha  um  cadastro  de  empresa,  este   cadastro   será   remodelado   aplicando   o   design   pattern   MVC   e   para   simplificar   o  desenvolvimento   reforçaremos   novamente   a   utilização   da   notação   UML,   que   oferece   uma  documentação  padronizada  do  projeto  de  software  e  como  seus  elementos  interagem  entre  si.  

1.  Introdução    

O  conceito  padrão  de  projeto  foi  utilizado  pela  primeira  vez  na  década  de  70  pelo  arquiteto  e  urbanista   austríaco  Christopher   Alexander.   Ele   observou   que   as   construções   embora   fossem  diferentes   em   vários   aspectos,   todas   passavam   pelos   mesmos   problemas   na   hora   de   se  construir.   Eram   problemas   que   se   repetiam   em   todas   elas   e   na  mesma   fase   de   construção.  Com   isso  Christopher   iniciou   o   processo   de   documentar   estes   problemas   e   as   soluções   que  eram  aplicadas  para  resolução  destes  problemas.  Até  nesse  ponto  na  história,  não  há  nada  de  desenvolvimento  de   software  e   sim  o   surgimento  de  padrões  de  projetos  para  a  engenharia  civil,   padrões   que   descrevem   os   problemas   recorrentes   em   um   projeto   de   engenharia   e   a  solução  reutilizável  para  este  problema.    

Paralelamente   a   isso   no   final   da   década   de   70,   exatamente   em   1978   –   no   Xerox   Palo   Alto  Research  Laboratory  (PARC),  o  cientista  Trygve  Reenskaug  iniciou  a  escrita  do  mais  importante  artigo  para  a  engenharia  de  software  intitulado  a  princípio  como  Model-­‐View-­‐Editor,  porém  foi  descrito   em   sua   primeira   dissertação   como   “Thing-­‐Model-­‐View-­‐Editor  –   an   Example   from   a  planningsystem”  (Maio  de  1979).  Após  longas  discussões,  particularmente  com  Adele  Golberg,  finalmente  apresentou  o  termo  acima  como  Model-­‐View-­‐Controllers,  descrito  em  sua  segunda  dissertação   (Dezembro   de   1979).   A   primeira   versão   do   padrão   MVC   foi   implementada   na  biblioteca   de   classes   do   Smalltalk-­‐80   logo   após   Trygve   deixar   o   Xerox   PARC,   não   trabalhou  diretamente   neste   projeto,   sua   contribuição   foi   através   das   dissertações.   Para   ter   acesso   as  publicações  de  Trygve,  acesse  http://heim.ifi.uio.no/~trygver/themes/mvc/mvc-­‐index.html.    

O   MVC   até   aquele   momento   tinha   sido   definido   como   um   padrão   arquitetural   para   o  desenvolvimento   de   softwares   orientados   a   objetos,   o   termo   design   patterns   (padrões   de  projetos)  somente  foi  definido  anos  mais  tarde  dentro  da  área  da  ciência  da  computação.  

Page 2: Design Pattern MVC – Arquitetura de Software Coesa e Flexível

Na  engenharia  de  software,  os  design  patterns  tiveram  origem  através  do  GoF  (Gang  of  Four  –  Gangue  dos  quatro),  composta  por  Erich  Gamma,  Richard  Helm,  Ralph  Johnson  e  John  Vlissides  que   iniciaram   suas   pesquisar   com   base   no   trabalho   de   Christopher   Alexander.   Este   foi   um  importante   processo   pois   começaram   a   descrever   e   documentar   os   problemas   comuns   e  soluções   recorrentes   para   o   desenvolvimento   de   software   orientado   a   objetos,   assim   como  tinha  feito  o  austríaco  anteriormente.  Ao  final  do  trabalho  de  pesquisa  e  documentação,  em  Outubro  de  1994  foi  lançado  o  livro  “Design  Patterns:  Elements  of  Reusable  Object  -­‐Oriented  Software”  –  traduzido  para  o  português  como  “Padrões  de  Projetos  –  Soluções  reutilizáveis  de  software  orientado  a  objetos”.  

A   partir   daquele  momento,   engenheiros   e   desenvolvedores   de   software   possuíam   um   livro  sobre   padrões   de   projetos   que   se   dividem   em   três   categorias:   criacional,   estrutural   e  comportamental   somando   23   no   total,   e   que   podem   ser   adotados   no   desenvolvimento   de  software   orientado   a   objetos,   resultando   em   uma   maior   qualidade   nos   produtos  desenvolvidos.    

2.  Design  Pattern  MVC  

A  arquitetura  de   software  em  camadas  não  é   algo  novo   como   fora   visto  no   tópico   anterior,  mesmo  assim  vários  desenvolvedores  ainda  tem  dificuldades  e  dúvidas  em  relação  a  aplicação  deste   conceito.   Por   conseguinte,   é   interessante   explorar   o   padrão   de   projeto  MVC   e   como  implementá-­‐lo   no   Object   Pascal,   analisando   as   suas   vantagens   e   desvantagens.   Com   a  arquitetura  do  software  organizada  em  camadas,   resultando  na  divisão  de  responsabilidades  entre  classes,  ou  seja,  pode-­‐se  definir  vários  pacotes  (diretórios)  e  organizar  as  classes  nestes  levando  em  consideração  sua  finalidade.  Porém  separar  as  classes  em  pacotes  e  organizar  em  camadas  não  promove  uma  arquitetura  MVC,  o  principal  objetivo  é  separar  a  lógica  do  negócio  da  camada  de  apresentação  utilizando  como  mediador  um  controlador.  Para   ficar  mais  claro  ao   leitor,   vamos   ilustrar   o   objetivo   do   padrão   MVC   através   da   figura   1   –   as   linhas   sólidas  representam  associação  direta  e  as  tracejadas  associação  indireta.  

 Figura  1  –  Diagrama  simples  exemplificando  a  relação  entre  Model,  View  e  Controller.  

Resumidamente  o  enfoque  é  na  divisão  lógica  da  aplicação  em  camadas  objetivando  uma  alta  coesão,  baixo  acoplamento  e  separação  de  responsabilidades.  Quando  dialogamos  sobre  alta  coesão   nos   referimos   a   quanto   uma   classe   é   coesa,   ou   seja,   ela   deve   possuir   apenas   uma  responsabilidade  e  “não  fazer  coisas  demais”.  Por  exemplo,  se  sua  responsabilidade  é  o  acesso  

Page 3: Design Pattern MVC – Arquitetura de Software Coesa e Flexível

a  banco  de  dados,  a  classe  deve  conter  somente  métodos  que  possuam  este  propósito,  nada  além  disso.  Em  um  projeto  de  software  haverá  classes  com  outras  responsabilidades,  como  de  implementar  métodos  de  regras  de  negócio,  outras  com  a  finalidade  de  exibir  e  obter  os  dados  do   usuário,   e   por   fim   classes   responsáveis   por   controlar   (comportando-­‐se   como   um  middleware)  o  acesso  do  usuário  a  camada  de  domínio  (model),  e  conseqüentemente  realizar  acesso   a   um   banco   de   dados   (SGBD).   É   notável   a   separação   de   responsabilidades   entre   as  diversas   classes   organizadas   logicamente   em   pacotes,   quanto  mais   coesas   forem   as   classes  mais  serão  independentes  umas  das  outras,  sendo  reforçado  o  conceito  do  baixo  acoplamento  –   isolar   as   alterações   (manutenção)   que   são   realizadas   em   uma   camada   e   que   não   afetam  diretamente   as   outras.   Esta   independência   pode   proporciona   uma   maior   reutilização   de  código;   como   estão   acopladas   de   forma   fraca,   se   desejarmos   é   possível   apenas   substituir   a  camada   de   visualização   e   manter   todo   o   resto   em   perfeito   funcionamento.   Um   exemplo  prático  disto  seria  que  um  mesmo  código-­‐fonte  pode  rodar  no  ambiente  win32  (desktop)  e  no  intraweb  (internet)  apenas  modificando  a  camada  de  visualização,  pois  esta  última  faz  uso  de  uma  classe  controladora  para  acessar  a  regra  de  negócio,  não  possui  acesso  direto  as  métodos  que  processam  a  lógica  da  aplicação.  O  usuário  tem  a  “falsa  impressão”  de  acessar  e  manipular  o  domínio  da  aplicação  de  forma  direta,  como  exibido  na  figura  2.  

 Figura  2  –  Solução  MVC  ideal  suporta  a  ilusão  de  estar  acessando  o  domínio  diretamente.  

Para   proporcionar   uma   fácil   visualização   de   como   a   aplicação   está   modelada   e   mapear   a  seqüencia  de  atividades  processadas  quando  há  interação  do  usuário  com  a  mesma,  visualize  o  diagrama  de   seqüencia   (documentação  UML)   apresentado   na   figura   3   que   define   o   ciclo   de  vida   de   uma   solicitação,   ou   seja,   quando   o   usuário   clicar   sobre   um   botão   encontrado   no  formulário   (view),  é  disparado  um  evento  com  a  seguinte  seqüencia  de  atividades  mapeadas  no  diagrama.  

Page 4: Design Pattern MVC – Arquitetura de Software Coesa e Flexível

 Figura  3  –  Diagrama  de  Seqüencia.  Interação  do  usuário  com  o  software.  

É  notado  uma  complexidade  maior  na  adoção  do  padrão  de  projeto  MVC  em  relação  as  duas  camadas  vistas  na  série  sobre  orientação  a  objetos  no  Delphi  (Revista  Active  Delphi  ,  edição  86  a   88).   O   propósito   deste   artigo   é   reutilizar   o   que   fora   visto   nos   artigos   citados,   aplicar   e  implementar   o   MVC   no   domínio   referente   ao   cadastro   do   grupo   de   empresas.   O   leitor   foi  conduzido  a  princípio  a  uma   implementação  de  diagrama  de  classes  de  fácil  entendimento  e  codificação,   pois   anteriormente   possuíamos   somente   duas   camadas   de   software,   a   de  visualização  (view/formulário)  e  a  de  regra  de  negócios  somada  com  acesso  a  dados  do  SGBD  (model  +  DAO).  Neste  artigo  é  definido  separadamente,  além  das  camadas  citadas,  a  camada  do  controlador  (controller)  e  a  de  acesso  ao  banco  de  dados  (DAO).  Os  detalhes  das  duas  novas  camadas  introduzidas  com  a  arquitetura  MVC  neste  contexto  é  explicada  logo  em  seguida.  

O   controlador   é   responsável   por   moderar   todos   os   eventos   disparados   pelo   usuário   da  aplicação,   ou   seja,   para   visualizar   o   cadastro   de   empresa   o   usuário   pode   clicar   no   item   de  menu  referente  ao  cadastro  desejado,  o  mesmo  será  exibido  na  tela  através  da  instanciação  de  um  objeto  do  tipo  Controller.  Em  seu  método  construtor,  a  inicialização  do  formulário  ocorre,  define-­‐se  todos  os  eventos  que  ele  deve  possuir.  Se  o  usuário  desejar  inserir  um  novo  registro  no   banco   de   dados,   um   evento   é   disparado   na   view   ao   clicar   no   botão   gravar,   que  posteriormente   é   repassado   ao   controlador   daquela   formulário   e   só   então   decidido   o   que  fazer  em  relação  à  aquele  evento,  pois  a  partir  daqui  a  regra  de  negócio  pode  ser  processada  e  se  necessário  realizar  a  recuperação/persistências  dos  dados  no  SGBD.  

A  camada  DAO   (Data  Access  Object)  é   responsável  por   realizar  o  acesso  ao  banco  de  dados.  Com  a  definição  de  uma  camada  de  acesso  direto  ao  SGBD  independente,  é  possível  trabalhar  com  diversos  bancos  de  dados  diferentes,   tendo  uma  classe  DAO  para  cada  banco  de  dados  específico,  tornamos  a  aplicação  multi-­‐banco  de  forma  rápida  e  fácil.    

Entender  a   lógica  simplificada  de  funcionamento  do  design  pattern  MVC  é  fundamental,  veja  como  é  possível  implementá-­‐lo  no  Object  Pascal  no  próximo  tópico.  

2.1  Arquitetura  MVC  no  Delphi  

Page 5: Design Pattern MVC – Arquitetura de Software Coesa e Flexível

O  diagrama  de   classes  apresentado  na   figura  4   representa  a  modelagem  de  um  cadastro  de  grupo  de  empresa,  cada  classe  está  contida  dentro  de  um  determinado  pacote.  O  formulário  de  cadastro  (view  -­‐  apresentação)  é  invocado  pela  classe  EmpresaCTR  (controller  -­‐  controlador)  que   então   instância   um   objeto   do   tipo   Empresa   (model   –  modelo   negócios)   e   EmpresaDAO  (DAO  –  acesso  a  dados).  Observa-­‐se  que  o  controller  é  o  elemento  com  inteligência  suficiente  para  “orquestrar”  o  conjunto  de  classes  associadas  de  alguma  forma  a  ele.  Os  eventos  do  tipo  onClick  de   TButton   (botões)   do   formulário   estão  definidos   e   implementados  no   controlador,  deixa-­‐se  na  view  apenas  os  métodos  e  eventos  referentes  ao  próprio  formulário.  A  camada  de  visualização  não  detêm  quase  nenhum  código,  sua  responsabilidade  de  fato  é  somente  obter  e  exibir  o  estado  dos  objetos  da  camada  model.  

 Figura  4  –  Diagrama  de  Classe.  Domínio:  Cadastro  de  Empresa.  Contexto:  Controle  de  Estoque.    

Page 6: Design Pattern MVC – Arquitetura de Software Coesa e Flexível

No  formulário  da  aplicação  de  controle  de  estoque  (FrmPrincipal),  ao  clicar  no  menu  principal  “Cadastros  –  Grupo  de  Empresas”,  o  cadastro  é  exibido  conforme  apresentado  na  figura  5.  Este  formulário   fora   construído   anteriormente,   sendo   necessário   neste   momento   a   remoção   de  todo  o  código  referente  aos  eventos  onClick  de  TButton  –  dos  botões:    salvar,  cancelar,  excluir  e   pesquisar   –   repassando   está   responsabilidade   para   a   camada   controller,   ou   seja,   para   a  classe   EmpresaCTR.   Esta   classe   possui   métodos   para   cada   evento   retirado   da   camada   de  visualização.  

 Figura  5  –  Camada  de  Apresentação  (view).  Formulário:  Cadastro  Grupo  de  Empresa.  

Conforme  citado  anteriormente,  ao  clicar  no  menu  principal  o  formulário  da  figura  5  é  exibido,  porém   fizemos   uma   pequena   modificação   no   procedimento   deste   item   de   menu,   logo   a  responsabilidade  é  do  controlador  em  instanciar  e  exibir  o  formulário  na  tela.  Note  que  sem  o  padrão  MVC  o   formulário   era   invocado   diretamente.   Agora   com  a   adoção   do  MVC,   deve-­‐se  instanciar  um  objeto  do  tipo  TEmpresaCTR.  A  grande  “mágica”  está  no  método  construtor  do  objeto   EmpresaCTR,   responsável   por   instanciar   objetos   associados   e   inicializar   o   formulário  atribuindo   os   eventos   onClick   de   TButton.   Veja   como   é   realizada   a   instanciação   do   objeto  EmpresaCTR  logo  abaixo:  

procedure  TFrmPrincipal.GrupodeEmpresas1Click(Sender:  TObject);  var      EmpresaCTR  :  TEmpresaCTR;  begin  

Page 7: Design Pattern MVC – Arquitetura de Software Coesa e Flexível

   {      -­‐-­‐  Invocação  de  Formulário  sem  o  Padrão  MVC        if  NOT  Assigned(FrmCadastroEmpresa)  then          FrmCadastroEmpresa  :=  TFrmCadastroEmpresa.Create(Application);      FrmCadastroEmpresa.ShowModal;      }        //  Aplicação  do  Padrão  de  Projeto  MVC      //  controller  -­‐  Empresa      EmpresaCTR  :=  TEmpresaCTR.Create;  end;    No  método  construtor  Create  de  TEmpresaCTR  é  realizado  a  chamada  ao  método  Inicializar().É  instanciado  um  objeto  do  tipo  TEmpresa  e  TEmpresaDAO,  que  são  utilizados  durante  o  clico  de  vida   do   controlador,   e   o   formulário   associado.   Veja   o   código-­‐fonte   referente   ao   método  Inicializar():  

procedure  TEmpresaCTR.Inicializar;  begin      //  Instanciação  do  objeto  Empresa  e  EmpresaDAO  na  memória  HEAP!      Empresa  :=  TEmpresa.Create;      EmpresaDAO  :=  TEmpresaDAO.Create;        //  Camada  de  Visualização  -­‐  Formulário      if  NOT  Assigned(FrmCadastro)  then          FrmCadastro  :=  TFrmCadastroEmpresa.Create(Application);        FrmCadastro.sppSalvar.OnClick  :=  SalvarClick;      FrmCadastro.sppCancelar.OnClick  :=  CancelarClick;      FrmCadastro.sppExcluir.OnClick  :=  ExcluirClick;      FrmCadastro.sppCancelar.OnClick  :=  CancelarClick;      FrmCadastro.ShowModal;  //  exibir  na  tela  end;    É  importante  observar  no  diagrama  que  o  elemento  Empresa  tem  sua  definição  completa,  com  seus  atributos  e  métodos,  nada  além  disto.  As  operações  CRUD  (acrônimo  de  Create,  Retrieve,  Update,  Delete)  que  são  operações  com  acesso  ao  banco  de  dados  estiveram  anteriormente  “misturadas”   com   métodos   de   regras   de   negócio,   ou   seja,   a   classe   possuía   duas  responsabilidades  em  sua  implementação.  Argumentamos,  quando  há  em  uma  classe  mais  do  que  uma  responsabilidade,  ela  não  está  coesa.  O   recomendado  é  deixar   somente  a   regra  de  negócios   na   classe   Empresa,   da   camada   model,   e   as   operações   CRUD   devem   ser  implementadas  na  classe  EmpresaDAO,  da  camada  DAO.  Para  que  a  interação  entre  os  objetos  esteja  precisa,  devemos  alterar  a  assinatura  dos  métodos  que  realizam  o  CRUD.  Para  maiores  detalhes  veja  novamente  o  diagrama  de  classe  da  figura  4.    

Page 8: Design Pattern MVC – Arquitetura de Software Coesa e Flexível

O   procedimento   SalvarClick   declarado   anteriormente   na   camada   view,   está   agora   sob   a  responsabilidade  do  controlador,  e  apresenta    a  seguinte  implementação:  

procedure  TEmpresaCTR.SalvarClick(Sender:  TObject);  var      Operacao:  String;  begin      Operacao  :=  'U';      Empresa.Codigo  :=  Self.FrmCadastro.edtCodigo.Text;      Empresa.Razao  :=  Self.FrmCadastro.edtRazao.Text;      Empresa.Fantasia  :=  Self.FrmCadastro.edtFantasia.Text;      Empresa.DtAbertura  :=  StrToDate(Self.FrmCadastro.mskAbertura.Text);      Empresa.DtCadastro  :=  StrToDate(Self.FrmCadastro.mskCadastro.Text);      Empresa.Status  :=  Self.FrmCadastro.cmbStatus.ItemIndex;      Empresa.Alias  :=  Self.FrmCadastro.edtAlias.Text;        //  telefones      Empresa.Telefone  :=  Self.FrmCadastro.mskTelefone.Text;      Empresa.FoneFax  :=  Self.FrmCadastro.mskFoneFax.Text;        //  documentos      Empresa.CNPJ  :=  Self.FrmCadastro.mskCNPJ.Text;      Empresa.IE  :=  Self.FrmCadastro.edtIE.Text;      Empresa.IM  :=  Self.FrmCadastro.edtIM.Text;      Empresa.IEST  :=  Self.FrmCadastro.edtIEST.Text;        Empresa.Email  :=  Self.FrmCadastro.edtEmail.Text;      Empresa.Pagina  :=  Self.FrmCadastro.edtPagina.Text;      Empresa.Crt  :=  Self.FrmCadastro.cmbCRT.ItemIndex;      Empresa.Cnae  :=  Self.FrmCadastro.edtCNAE.Text;      Empresa.Contato  :=  Self.FrmCadastro.edtContato.Text;      Empresa.Observacao  :=  Self.FrmCadastro.memoObservacao.Text;      Empresa.Contato  :=  Self.FrmCadastro.edtContato.Text;        //  endereco      Empresa.Endereco.Correspondencia  :=  Self.FrmCadastro.chkEnderecoCorresp.Checked;      Empresa.Endereco.Logradouro  :=  Self.FrmCadastro.edtLogradouro.Text;      Empresa.Endereco.Numero  :=  Self.FrmCadastro.edtNumero.Text;      Empresa.Endereco.Complemento  :=  Self.FrmCadastro.edtComplemento.Text;      Empresa.Endereco.Bairro  :=  Self.FrmCadastro.edtBairro.Text;      Empresa.Endereco.Cidade  :=  Self.FrmCadastro.edtCidade.Text;      Empresa.Endereco.Cep  :=  Self.FrmCadastro.mskCEP.Text;      Empresa.Endereco.Referencia  :=  Self.FrmCadastro.edtPontoReferencia.Text;      Empresa.Endereco.Tipo  :=  Self.FrmCadastro.cmbTipoEndereco.ItemIndex;    

Page 9: Design Pattern MVC – Arquitetura de Software Coesa e Flexível

   if  TUtil.Empty(Empresa.Codigo)  then          Operacao  :=  'I';        if  Empresa.Validar()  then          if  EmpresaDAO.Merge(Empresa)  then  begin              TUtil.LimparFields(Self.FrmCadastro);                if  Operacao  =  'I'  then                  ShowMessage('Registro  Gravado  com  Sucesso!')              else                  ShowMessage('Registro  Atualizado  com  Sucesso!');                Self.FrmCadastro.edtFantasia.SetFocus;          end;  end;    Observe  que  a  única   linha  de  código  que  foi  alterada  acima  é  a  chamada  do  método  Merge,  pois   sua   implementação   encontra-­‐se   agora   na   classe   EmpresaDAO.   Através   deste  método   é  persistido   o   estado   do   objeto   Empresa   instanciado   e   utilizado   pela   camada   de   visualização  para  a  recepção/atualização  dos  dados.  Antes  da  serialização  dos  dados  no  banco,  atribuímos  os  valores  dos   campos  do   formulário  para  os   respectivos  atributos  do  objeto  Empresa.   Logo  devemos   passar   o   mesmo   como   parâmetro   para   ser   persistido   no   SGBD.   O   método  Merge(Empresa:   TEmpresa),   recebe   o   objeto   Empresa   como   argumento   e   verifica   se   o  atributo   código  está   “setado”,   caso  não  esteja,   significa  que  é  um  objeto   sem   ID   (ainda  não  persistido),  o  mesmo  deve  ser  serializado  no  banco  de  dados  através  da  invocação  do  método  Insert.  Um  objeto   somente   terá  um   ID,   após   ser   inserido  no  banco,  pois   a   coluna   código  da  tabela   relacional  do  qual  o  objeto  é  serializado  é  do  tipo  auto-­‐incremento.  A   implementação  do  método  Merge  é  definida  abaixo:    function  TEmpresaDAO.Merge(Empresa:  TEmpresa):  Boolean;  begin      if  TUtil.Empty(Empresa.Codigo)  then  begin          Result  :=  Self.Insert(Empresa);      end      else          Result  :=  Self.Update(Empresa);  end;      Ao   ser   invocado   o   método   Insert(Empresa:   TEmpresa),   recebe   o   objeto   Empresa   como  argumento,   repassado  pelo  método  Merge;  devemos   serializar  o  mesmo  para  as   colunas  da  tabela   relacional   do   SGBD.   O   processo   de   serialização   já   fora   comentado   no   artigo   sobre  orientação   a   objetos,   precisamos   agora   realizar   apenas   uma   pequena   alteração   na  implementação  do  método  Insert  que  é  exibida  abaixo:          

Page 10: Design Pattern MVC – Arquitetura de Software Coesa e Flexível

function  TEmpresaDAO.Insert(Empresa:  TEmpresa):  Boolean;  begin      Try          Result  :=  False;            with  Conexao.QryCRUD  do  begin              Close;              SQL.Clear;              SQL.Text   :=   'INSERT   INTO   '+   TABLENAME   +'   (EMP_RAZAO,   EMP_FANTASIA,  EMP_DT_CADASTRO,  EMP_DT_ABERTURA,  EMP_STATUS,  EMP_ALIAS,  '+                                      '   EMP_TELEFONE,   EMP_FONEFAX,   EMP_CNPJ,   EMP_IE,   EMP_IEST,   EMP_IM,  EMP_CRT,  EMP_CNAE,  EMP_EMAIL,  EMP_PAGINA,  '+                                      '  EMP_MENSAGEM,  EMP_CONTATO)  '+                                      '  VALUES(:RAZAO,  :FANTASIA,  :CADASTRO,  :ABERTURA,  :STATUS,  :ALIAS,  :TELEFONE,  :FONEFAX,  :CNPJ,  :IE,  :IEST,  :IM,  '+                                      '  :CRT,  :CNAE,  :EMAIL,  :PAGINA,  :MENSAGEM,  :CONTATO)  ';                ParamByName('RAZAO').AsString  :=  Empresa.Razao;              ParamByName('FANTASIA').AsString  :=  Empresa.Fantasia;              ParamByName('CADASTRO').AsDateTime  :=  Empresa.DtCadastro;              ParamByName('ABERTURA').AsDateTime  :=  Empresa.DtAbertura;              ParamByName('STATUS').AsInteger  :=  Empresa.Status;              ParamByName('ALIAS').AsString  :=  Empresa.Alias;              ParamByName('TELEFONE').AsString  :=  Empresa.Telefone;              ParamByName('FONEFAX').AsString  :=  Empresa.FoneFax;              ParamByName('CNPJ').AsString  :=  Empresa.CNPJ;              ParamByName('IE').AsString  :=  Empresa.IE;              ParamByName('IEST').AsString  :=  Empresa.IEST;              ParamByName('IM').AsString  :=  Empresa.IM;              ParamByName('CRT').AsInteger  :=  Empresa.Crt;              ParamByName('CNAE').AsString  :=  Empresa.Cnae;              ParamByName('EMAIL').AsString  :=  Empresa.Email;              ParamByName('PAGINA').AsString  :=  Empresa.Pagina;              ParamByName('MENSAGEM').AsString  :=  Empresa.Observacao;              ParamByName('CONTATO').AsString  :=  Empresa.Contato;              ExecSQL;          end;            //  getCodigo  para  Insert  Endereco          Empresa.Codigo  :=  getMaxId();            if  NOT  Empresa.Endereco.Insert(Empresa.Codigo,  'EMPRESA')  then  begin              ShowMessage('erro  ao   inserir   endereco');   //  mensagem   temporaria,  melhorar   controle  de  transacao              //  deletar  registro  da  empresa,  pois  houve  erro  ao  inserir  empresa  

Page 11: Design Pattern MVC – Arquitetura de Software Coesa e Flexível

           Result  :=  False;          end;            Result  :=  True;      Except          on  E  :  Exception  do              ShowMessage('Classe:  '+  e.ClassName  +  chr(13)  +  'Mensagem:  '+  e.Message);      end;  end;    Com   a   arquitetura   do   software   logicamente   separada   em   camadas,   percebe-­‐se   que   a  manutenção   na   implementação   do   código-­‐fonte   em   uma   determinada   camada   não   afeta  diretamente   a   implementação   contida   em   outra   camada,   confirma-­‐se   assim   na   prática   que  através   do   MVC   é   possível   desenvolver   software   de   qualidade   com   o   mínimo   de   impacto  possível,  provocado  pela  manutenção  das  rotinas.  

Agora   que   chegamos   ao   ponto   da   persistência   do   objeto   em   um   SGBD,   passando   pelas  camadas  View,  Controller,  Model   e  DAO   completa-­‐se   uma   parte   da   seqüencia   de   atividades  que   estão   claramente   representadas   na   figura   3,   através   da   interação   do   usuário   com   o  sistema.   O   retorno   da   camada   DAO   dá-­‐se   através   do   método   Insert(Empresa:   TEmpresa):  boolean  que  retorna  true/false  para  a  camada  Model  que  realizou  a  invocação  do  método.  Na  implementação   apresentada   neste   artigo   o   objeto   Empresa   da   camada  Model   está   sendo  referenciado   dentro   do   escopo   da   camada   Controller   que   é   então   notificada   do   retorno  booleano   citado   anteriormente   e   este   repassa   para   a   camada   View   o   resultado   do  processamento  solicitado  pelo  usuário,  através  de  uma  notificação  visual  –  uma  mensagem.  

Foi  mostrado  neste  artigo  somente  o  Create  (Insert)  do  acrônimo  CRUD,  as  demais  operações  podem   ser   visualizadas   no   código-­‐fonte   disponibilizado   em  https://github.com/ryanpadilha/coding4fun.  

Esta  aplicação  utiliza  componentes  TEdit  que  não  possuem  vínculo  direto  com  um  DataSet  em  particular,  ou  seja,  com  acesso  direto  ao  banco  de  dados  tal  como  os  componentes  do  estilo  TDBEdit.  Então  você  está  livre  para  alterá-­‐lo  conforme  a  sua  necessidade  e  vontade.              

3.  Conclusão  

Dado   o   exposto,   através   do   design   pattern   MVC   divide-­‐se   logicamente   a   arquitetura   da  aplicação   em   quatro   camadas,   objetivando   uma   alta   coesão   e   baixo   acoplamento   entre   as  unidade   de   software,   porém   com   uma   alta   granularidade.   Anteriormente   a   adoção   deste  padrão  tínhamos  uma  arquitetura  simples  em  duas  camadas,  porém  com  uma  granularidade  satisfatória.   Quanto   maior   for   a   granularidade,   mais   trabalho   temos   ao   implementar   um  diagrama  de  classes  anotado  utilizando  a  UML,  como   fora  apresentado  na   figura  4.  Porém  a  flexibilidade   é   transparente,   poder   trocar,   qualquer   elemento   de   determinada   camada   e  manter  o  código  de  outras  camadas  ainda  assim  em  perfeito  funcionamento  e  com  um  certo  nível  de  robustez  é  incontestável.  Um  exemplo  disto  seria  a  criação  de  várias  classes  dentro  do  pacote  DAO,   cada   uma   com   acesso   para   um  determinado   banco   de   dados   específico,   como  Oracle,  Firebird,  PostgreSQL,  e  assim  por  diante.  Tornando  a  aplicação  multi-­‐banco  de   forma  

Page 12: Design Pattern MVC – Arquitetura de Software Coesa e Flexível

simples.  A  modificação  aqui  é  somente  na  camada  de  acesso  a  dados,  pois  a  regra  de  negócios,  formulário  e  controlador  já  estão  implementados  e  testados.    

Apesar  do  conceito  RAD  que  a  IDE  Delphi  proporciona,  sem  sombra  de  dúvidas  somos  capazes  de  aplicar  design  patterns  e  boas  práticas  da  engenharia  de  software  em  projetos  de  software  desenvolvidos  utilizando  o  Delphi.  Como  os  padrões  de  projetos  estão  documentados  fica  fácil  a  difusão  deles  dentro  de  times  de  desenvolvimento,  sem  muito  esforço  podemos  acrescentar  uma  ótima  qualidade  no  software  desenvolvido,  além  de  ter  alcançado  um  arquitetura  flexível  ao  ponto  de  ser  realizado  de  forma  menos  dolorosa  a  manutenção  da  mesma.  

Seria   interessante   a   criação   de   um   framework   que   aplicasse   o   padrão   de   projeto  MVC   sem  muito   esforço.   Outras   linguagens   como   o   Java   e   C#.NET,   possuem   frameworks   com   esta  finalidade,   aumentando  admiravelmente  a  produtividade  do  desenvolvimento  de   software  e  levando  em  consideração  a  obtenção  de  uma  qualidade  de  software  inquestionável.  Acredito  que  as  vantagens  que  o  padrão  MVC  nos  proporciona  é  muito  maior  que  as  desvantagens,  pois  o  que  deixa  a  desejar  é  a  falta  de  produtividade  ao  implementá-­‐lo.  

Caso  tenha  alguma  dúvida  entre  em  contato.  Será  um  prazer  ajudar.    

Forte   Abraço   a   todos   os   leitores   que   acompanharam   meus   artigos   sobre   engenharia   de  software  em  geral.