You are on page 1of 12

Design

Pattern MVC Arquitetura de Software Coesa e Flexvel


Ryan Bruno C Padilha
ryan.padilha@gmail.com
http://ryanpadilha.com.br
Objetivo deste artigo
O objetivo deste artigo fornecer uma viso geral da utilizao do design pattern MVC -
Model-View-Controller no Object Pascal, que um padro de projeto arquitetural utilizado
como boa prtica na construo de softwares orientados a objetos reutilizveis e eficientes.
Idealizado por Trygve Reenskaug no final dos anos 70, foi na poca uma das maiores
contribuies na rea de desenvolvimento de software de todos os tempos. Objetiva a
organizao da aplicao em camadas separando a lgica de negcio da camada de
apresentao utilizando como mediador um controlador. Na srie de artigos sobre o
paradigma orientado a objetos escrito por mim e publicado nas edies 86 a 88, fora
desenvolvido um mdulo 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 reforaremos novamente a utilizao da notao UML, que oferece uma
documentao padronizada do projeto de software e como seus elementos interagem entre si.
1. Introduo
O conceito padro de projeto foi utilizado pela primeira vez na dcada de 70 pelo arquiteto e
urbanista austraco Christopher Alexander. Ele observou que as construes embora fossem
diferentes em vrios aspectos, todas passavam pelos mesmos problemas na hora de se
construir. Eram problemas que se repetiam em todas elas e na mesma fase de construo.
Com isso Christopher iniciou o processo de documentar estes problemas e as solues que
eram aplicadas para resoluo destes problemas. At nesse ponto na histria, no h nada de
desenvolvimento de software e sim o surgimento de padres de projetos para a engenharia
civil, padres que descrevem os problemas recorrentes em um projeto de engenharia e a
soluo reutilizvel para este problema.
Paralelamente a isso no final da dcada 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 princpio como Model-View-Editor, porm foi
descrito em sua primeira dissertao como Thing-Model-View-Editor an Example from a
planningsystem (Maio de 1979). Aps longas discusses, particularmente com Adele Golberg,
finalmente apresentou o termo acima como Model-View-Controllers, descrito em sua segunda
dissertao (Dezembro de 1979). A primeira verso do padro MVC foi implementada na
biblioteca de classes do Smalltalk-80 logo aps Trygve deixar o Xerox PARC, no trabalhou
diretamente neste projeto, sua contribuio foi atravs das dissertaes. Para ter acesso as
publicaes de Trygve, acesse http://heim.ifi.uio.no/~trygver/themes/mvc/mvc-index.html.
O MVC at aquele momento tinha sido definido como um padro arquitetural para o
desenvolvimento de softwares orientados a objetos, o termo design patterns (padres de
projetos) somente foi definido anos mais tarde dentro da rea da cincia da computao.

Na engenharia de software, os design patterns tiveram origem atravs 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 comearam a descrever e documentar os problemas comuns e
solues recorrentes para o desenvolvimento de software orientado a objetos, assim como
tinha feito o austraco anteriormente. Ao final do trabalho de pesquisa e documentao, em
Outubro de 1994 foi lanado o livro Design Patterns: Elements of Reusable Object -Oriented
Software traduzido para o portugus como Padres de Projetos Solues reutilizveis de
software orientado a objetos.
A partir daquele momento, engenheiros e desenvolvedores de software possuam um livro
sobre padres de projetos que se dividem em trs 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 no algo novo como fora visto no tpico anterior,
mesmo assim vrios desenvolvedores ainda tem dificuldades e dvidas em relao a aplicao
deste conceito. Por conseguinte, interessante explorar o padro 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 diviso de responsabilidades
entre classes, ou seja, pode-se definir vrios pacotes (diretrios) e organizar as classes nestes
levando em considerao sua finalidade. Porm separar as classes em pacotes e organizar em
camadas no promove uma arquitetura MVC, o principal objetivo separar a lgica do negcio
da camada de apresentao utilizando como mediador um controlador. Para ficar mais claro
ao leitor, vamos ilustrar o objetivo do padro MVC atravs da figura 1 as linhas slidas
representam associao direta e as tracejadas associao indireta.


Figura 1 Diagrama simples exemplificando a relao entre Model, View e Controller.
Resumidamente o enfoque na diviso lgica da aplicao em camadas objetivando uma alta
coeso, baixo acoplamento e separao de responsabilidades. Quando dialogamos sobre alta
coeso nos referimos a quanto uma classe coesa, ou seja, ela deve possuir apenas uma
responsabilidade e no fazer coisas demais. Por exemplo, se sua responsabilidade o acesso

a banco de dados, a classe deve conter somente mtodos que possuam este propsito, nada
alm disso. Em um projeto de software haver classes com outras responsabilidades, como de
implementar mtodos de regras de negcio, outras com a finalidade de exibir e obter os dados
do usurio, e por fim classes responsveis por controlar (comportando-se como um
middleware) o acesso do usurio a camada de domnio (model), e conseqentemente realizar
acesso a um banco de dados (SGBD). notvel a separao de responsabilidades entre as
diversas classes organizadas logicamente em pacotes, quanto mais coesas forem as classes
mais sero independentes umas das outras, sendo reforado o conceito do baixo acoplamento
isolar as alteraes (manuteno) que so realizadas em uma camada e que no afetam
diretamente as outras. Esta independncia pode proporciona uma maior reutilizao de
cdigo; como esto acopladas de forma fraca, se desejarmos possvel apenas substituir a
camada de visualizao e manter todo o resto em perfeito funcionamento. Um exemplo
prtico disto seria que um mesmo cdigo-fonte pode rodar no ambiente win32 (desktop) e no
intraweb (internet) apenas modificando a camada de visualizao, pois esta ltima faz uso de
uma classe controladora para acessar a regra de negcio, no possui acesso direto as mtodos
que processam a lgica da aplicao. O usurio tem a falsa impresso de acessar e manipular
o domnio da aplicao de forma direta, como exibido na figura 2.


Figura 2 Soluo MVC ideal suporta a iluso de estar acessando o domnio diretamente.
Para proporcionar uma fcil visualizao de como a aplicao est modelada e mapear a
seqencia de atividades processadas quando h interao do usurio com a mesma, visualize o
diagrama de seqencia (documentao UML) apresentado na figura 3 que define o ciclo de
vida de uma solicitao, ou seja, quando o usurio clicar sobre um boto encontrado no
formulrio (view), disparado um evento com a seguinte seqencia de atividades mapeadas
no diagrama.

Figura 3 Diagrama de Seqencia. Interao do usurio com o software.


notado uma complexidade maior na adoo do padro de projeto MVC em relao as duas
camadas vistas na srie sobre orientao a objetos no Delphi (Revista Active Delphi , edio 86
a 88). O propsito deste artigo reutilizar o que fora visto nos artigos citados, aplicar e
implementar o MVC no domnio referente ao cadastro do grupo de empresas. O leitor foi
conduzido a princpio a uma implementao de diagrama de classes de fcil entendimento e
codificao, pois anteriormente possuamos somente duas camadas de software, a de
visualizao (view/formulrio) e a de regra de negcios somada com acesso a dados do SGBD
(model + DAO). Neste artigo definido separadamente, alm 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 responsvel por moderar todos os eventos disparados pelo usurio da
aplicao, ou seja, para visualizar o cadastro de empresa o usurio pode clicar no item de
menu referente ao cadastro desejado, o mesmo ser exibido na tela atravs da instanciao de
um objeto do tipo Controller. Em seu mtodo construtor, a inicializao do formulrio ocorre,
define-se todos os eventos que ele deve possuir. Se o usurio desejar inserir um novo registro
no banco de dados, um evento disparado na view ao clicar no boto gravar, que
posteriormente repassado ao controlador daquela formulrio e s ento decidido o que
fazer em relao aquele evento, pois a partir daqui a regra de negcio pode ser processada e
se necessrio realizar a recuperao/persistncias dos dados no SGBD.
A camada DAO (Data Access Object) responsvel por realizar o acesso ao banco de dados.
Com a definio de uma camada de acesso direto ao SGBD independente, possvel trabalhar
com diversos bancos de dados diferentes, tendo uma classe DAO para cada banco de dados
especfico, tornamos a aplicao multi-banco de forma rpida e fcil.
Entender a lgica simplificada de funcionamento do design pattern MVC fundamental, veja
como possvel implement-lo no Object Pascal no prximo tpico.
2.1 Arquitetura MVC no Delphi

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 formulrio
de cadastro (view - apresentao) invocado pela classe EmpresaCTR (controller - controlador)
que ento instncia um objeto do tipo Empresa (model modelo negcios) e EmpresaDAO
(DAO acesso a dados). Observa-se que o controller o elemento com inteligncia suficiente
para orquestrar o conjunto de classes associadas de alguma forma a ele. Os eventos do tipo
onClick de TButton (botes) do formulrio esto definidos e implementados no controlador,
deixa-se na view apenas os mtodos e eventos referentes ao prprio formulrio. A camada de
visualizao no detm quase nenhum cdigo, sua responsabilidade de fato somente obter e
exibir o estado dos objetos da camada model.

Figura 4 Diagrama de Classe. Domnio: Cadastro de Empresa. Contexto: Controle de Estoque.

No formulrio da aplicao de controle de estoque (FrmPrincipal), ao clicar no menu principal


Cadastros Grupo de Empresas, o cadastro exibido conforme apresentado na figura 5. Este
formulrio fora construdo anteriormente, sendo necessrio neste momento a remoo de
todo o cdigo referente aos eventos onClick de TButton dos botes: salvar, cancelar, excluir
e pesquisar repassando est responsabilidade para a camada controller, ou seja, para a
classe EmpresaCTR. Esta classe possui mtodos para cada evento retirado da camada de
visualizao.

Figura 5 Camada de Apresentao (view). Formulrio: Cadastro Grupo de Empresa.

Conforme citado anteriormente, ao clicar no menu principal o formulrio da figura 5 exibido,


porm fizemos uma pequena modificao no procedimento deste item de menu, logo a
responsabilidade do controlador em instanciar e exibir o formulrio na tela. Note que sem o
padro MVC o formulrio era invocado diretamente. Agora com a adoo do MVC, deve-se
instanciar um objeto do tipo TEmpresaCTR. A grande mgica est no mtodo construtor do
objeto EmpresaCTR, responsvel por instanciar objetos associados e inicializar o formulrio
atribuindo os eventos onClick de TButton. Veja como realizada a instanciao do objeto
EmpresaCTR logo abaixo:
procedure TFrmPrincipal.GrupodeEmpresas1Click(Sender: TObject);
var
EmpresaCTR : TEmpresaCTR;
begin

{
-- Invocao de Formulrio sem o Padro MVC

if NOT Assigned(FrmCadastroEmpresa) then
FrmCadastroEmpresa := TFrmCadastroEmpresa.Create(Application);
FrmCadastroEmpresa.ShowModal;
}

// Aplicao do Padro de Projeto MVC
// controller - Empresa
EmpresaCTR := TEmpresaCTR.Create;
end;

No mtodo construtor Create de TEmpresaCTR realizado a chamada ao mtodo Inicializar().
instanciado um objeto do tipo TEmpresa e TEmpresaDAO, que so utilizados durante o clico de
vida do controlador, e o formulrio associado. Veja o cdigo-fonte referente ao mtodo
Inicializar():
procedure TEmpresaCTR.Inicializar;
begin
// Instanciao do objeto Empresa e EmpresaDAO na memria HEAP!
Empresa := TEmpresa.Create;
EmpresaDAO := TEmpresaDAO.Create;

// Camada de Visualizao - Formulrio
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 definio completa, com
seus atributos e mtodos, nada alm disto. As operaes CRUD (acrnimo de Create, Retrieve,
Update, Delete) que so operaes com acesso ao banco de dados estiveram anteriormente
misturadas com mtodos de regras de negcio, ou seja, a classe possua duas
responsabilidades em sua implementao. Argumentamos, quando h em uma classe mais do
que uma responsabilidade, ela no est coesa. O recomendado deixar somente a regra de
negcios na classe Empresa, da camada model, e as operaes CRUD devem ser
implementadas na classe EmpresaDAO, da camada DAO. Para que a interao entre os objetos
esteja precisa, devemos alterar a assinatura dos mtodos que realizam o CRUD. Para maiores
detalhes veja novamente o diagrama de classe da figura 4.

O procedimento SalvarClick declarado anteriormente na camada view, est agora sob a


responsabilidade do controlador, e apresenta a seguinte implementao:
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;

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 cdigo que foi alterada acima a chamada do mtodo Merge,
pois sua implementao encontra-se agora na classe EmpresaDAO. Atravs deste mtodo
persistido o estado do objeto Empresa instanciado e utilizado pela camada de visualizao
para a recepo/atualizao dos dados. Antes da serializao dos dados no banco, atribumos
os valores dos campos do formulrio para os respectivos atributos do objeto Empresa. Logo
devemos passar o mesmo como parmetro para ser persistido no SGBD. O mtodo
Merge(Empresa: TEmpresa), recebe o objeto Empresa como argumento e verifica se o
atributo cdigo est setado, caso no esteja, significa que um objeto sem ID (ainda no
persistido), o mesmo deve ser serializado no banco de dados atravs da invocao do mtodo
Insert. Um objeto somente ter um ID, aps ser inserido no banco, pois a coluna cdigo da
tabela relacional do qual o objeto serializado do tipo auto-incremento. A implementao
do mtodo 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 mtodo Insert(Empresa: TEmpresa), recebe o objeto Empresa como
argumento, repassado pelo mtodo Merge; devemos serializar o mesmo para as colunas da
tabela relacional do SGBD. O processo de serializao j fora comentado no artigo sobre
orientao a objetos, precisamos agora realizar apenas uma pequena alterao na
implementao do mtodo Insert que exibida abaixo:

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

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
manuteno na implementao do cdigo-fonte em uma determinada camada no afeta
diretamente a implementao contida em outra camada, confirma-se assim na prtica que
atravs do MVC possvel desenvolver software de qualidade com o mnimo de impacto
possvel, provocado pela manuteno das rotinas.
Agora que chegamos ao ponto da persistncia do objeto em um SGBD, passando pelas
camadas View, Controller, Model e DAO completa-se uma parte da seqencia de atividades
que esto claramente representadas na figura 3, atravs da interao do usurio com o
sistema. O retorno da camada DAO d-se atravs do mtodo Insert(Empresa: TEmpresa):
boolean que retorna true/false para a camada Model que realizou a invocao do mtodo. Na
implementao apresentada neste artigo o objeto Empresa da camada Model est sendo
referenciado dentro do escopo da camada Controller que ento notificada do retorno
booleano citado anteriormente e este repassa para a camada View o resultado do
processamento solicitado pelo usurio, atravs de uma notificao visual uma mensagem.
Foi mostrado neste artigo somente o Create (Insert) do acrnimo CRUD, as demais operaes
podem
ser
visualizadas
no
cdigo-fonte
disponibilizado
em
https://github.com/ryanpadilha/coding4fun.
Esta aplicao utiliza componentes TEdit que no possuem vnculo direto com um DataSet em
particular, ou seja, com acesso direto ao banco de dados tal como os componentes do estilo
TDBEdit. Ento voc est livre para alter-lo conforme a sua necessidade e vontade.
3. Concluso
Dado o exposto, atravs do design pattern MVC divide-se logicamente a arquitetura da
aplicao em quatro camadas, objetivando uma alta coeso e baixo acoplamento entre as
unidade de software, porm com uma alta granularidade. Anteriormente a adoo deste
padro tnhamos uma arquitetura simples em duas camadas, porm com uma granularidade
satisfatria. Quanto maior for a granularidade, mais trabalho temos ao implementar um
diagrama de classes anotado utilizando a UML, como fora apresentado na figura 4. Porm a
flexibilidade transparente, poder trocar, qualquer elemento de determinada camada e
manter o cdigo de outras camadas ainda assim em perfeito funcionamento e com um certo
nvel de robustez incontestvel. Um exemplo disto seria a criao de vrias classes dentro do
pacote DAO, cada uma com acesso para um determinado banco de dados especfico, como
Oracle, Firebird, PostgreSQL, e assim por diante. Tornando a aplicao multi-banco de forma

simples. A modificao aqui somente na camada de acesso a dados, pois a regra de negcios,
formulrio e controlador j esto implementados e testados.
Apesar do conceito RAD que a IDE Delphi proporciona, sem sombra de dvidas somos capazes
de aplicar design patterns e boas prticas da engenharia de software em projetos de software
desenvolvidos utilizando o Delphi. Como os padres de projetos esto documentados fica fcil
a difuso deles dentro de times de desenvolvimento, sem muito esforo podemos acrescentar
uma tima qualidade no software desenvolvido, alm de ter alcanado um arquitetura flexvel
ao ponto de ser realizado de forma menos dolorosa a manuteno da mesma.
Seria interessante a criao de um framework que aplicasse o padro de projeto MVC sem
muito esforo. Outras linguagens como o Java e C#.NET, possuem frameworks com esta
finalidade, aumentando admiravelmente a produtividade do desenvolvimento de software e
levando em considerao a obteno de uma qualidade de software inquestionvel. Acredito
que as vantagens que o padro MVC nos proporciona muito maior que as desvantagens, pois
o que deixa a desejar a falta de produtividade ao implement-lo.
Caso tenha alguma dvida entre em contato. Ser um prazer ajudar.
Forte Abrao a todos os leitores que acompanharam meus artigos sobre engenharia de
software em geral.

You might also like