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

3.234 visualizações

Publicada em

Publicada em: Software
0 comentários
2 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

Sem downloads
Visualizações
Visualizações totais
3.234
No SlideShare
0
A partir de incorporações
0
Número de incorporações
1.521
Ações
Compartilhamentos
0
Downloads
131
Comentários
0
Gostaram
2
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

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

  1. 1. Design  Pattern  MVC  –  Arquitetura  de  Software  Coesa  e  Flexível   Ryan  Bruno  C  Padilha   ryan.padilha@gmail.com   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.  
  2. 2. 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  
  3. 3. 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.  
  4. 4.   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  
  5. 5. 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.    
  6. 6. 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  
  7. 7.    {      -­‐-­‐  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.    
  8. 8. 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;    
  9. 9.    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:          
  10. 10. 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  
  11. 11.            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  
  12. 12. 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.      

×