Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Juliano amadeu

Como pensar em Orientação a Objetos

Recommended Posts

Pronto Juliano amadeu, agora você tem a faca e o queijo não mão... bom divertimento...

 

Pessoal, e se aproveitarmos essa faca e queijo para prepararmos um MVC? Acho que vai ser interessante, que acham?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Seria legal, cria um projeto no Github e o pessoal faz o fork :-)

 

Isso é fácil, posso criar o repositório no perfil do iMasters Deveveloper no github :seta: https://github.com/iMastersDev

 

Bora?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Demorou.

 

Agora o que é model ? O que é View ? O que é controller ?

 

Ainda vejo muita gente se confundindo e misturando model com view ou view com controller.

Não seria interessante dar um ou dois passos pra trás e deixar claro esse conceito para prosseguirmos adiante com um entendimento claro e solido também sobre esse conceito ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Agora o que é model ? O que é View ? O que é controller ?

 

Exatamente esse o objetivo do meu post #50, saber até onde sabemos sobre MVC.

 

:)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Conta comigo. \m/

 

Frontend. Do backend eu quero participar só das discussões. :grin:

 

2. Onde podemos usar o que já temos até agora?

 

As classes feitas até agora, Question, ConditionalQuestion, Alternative, Interview, Interviewee e Interviewer (neste caso creio que sejam Entities, right?) seriam a Model, o Controller seria o que iria fazer uma ligação desses dados com a View, por exemplo seria o intermediário dessas ações:

 

$interviewer = new Interviewer();
$interviewer->setName( 'João Batista Neto' );

$interviewee = new Interviewee();
$interviewee->setName( 'Juliano Amadeu' );

$a1_1 = new Alternative( 'Alternativa 1 da questão 1' );
$a2_1 = new Alternative( 'Alternativa 2 da questão 1' );
$a3_1 = new Alternative( 'Alternativa 3 da questão 1' );

$question1 = new Question( 'Questão 1' );
$question1->addAlternative( $a1_1 );
$question1->addAlternative( $a2_1 );
$question1->addAlternative( $a3_1 );

$a1_2a = new Alternative( 'Alternativa 1 da questão 2a' );
$a2_2a = new Alternative( 'Alternativa 2 da questão 2a' );
$a3_2a = new Alternative( 'Alternativa 3 da questão 2a' );

$question2a = new Question( 'Questão 2a que depende da alternativa 1 da questão 1' );
$question2a->addAlternative( $a1_2a );
$question2a->addAlternative( $a2_2a );
$question2a->addAlternative( $a3_2a );

$a1_2b = new Alternative( 'Alternativa 1 da questão 2b' );
$a2_2b = new Alternative( 'Alternativa 2 da questão 2b' );
$a3_2b = new Alternative( 'Alternativa 3 da questão 2b' );

$question2b = new Question( 'Questão 2b que depende da alternativa 2 da questão 1' );
$question2b->addAlternative( $a1_2b );
$question2b->addAlternative( $a2_2b );
$question2b->addAlternative( $a3_2b );

$a1_2c = new Alternative( 'Alternativa 1 da questão 2c' );
$a2_2c = new Alternative( 'Alternativa 2 da questão 2c' );
$a3_2c = new Alternative( 'Alternativa 3 da questão 2c' );

$question2c = new Question( 'Questão 2c que depende da alternativa 3 da questão 1' );
$question2c->addAlternative( $a1_2c );
$question2c->addAlternative( $a2_2c );
$question2c->addAlternative( $a3_2c );

$question2 = new ConditionalQuestion( $interviewer );
$question2->setQuestionForAlternative( $question2a , $a1_1 );
$question2->setQuestionForAlternative( $question2b , $a2_1 );
$question2->setQuestionForAlternative( $question2c , $a3_1 );

$question3a = new Question( 'Questão 3a que depende da alternativa 1 da questão 2a' );
$question3a->addAlternative( new Alternative( 'Alternativa 1 da questão 3a' ) );
$question3a->addAlternative( new Alternative( 'Alternativa 2 da questão 3a' ) );
$question3a->addAlternative( new Alternative( 'Alternativa 3 da questão 3a' ) );

$question3b = new Question( 'Questão 3b que depende da alternativa 2 da questão 2a' );
$question3b->addAlternative( new Alternative( 'Alternativa 1 da questão 3b' ) );
$question3b->addAlternative( new Alternative( 'Alternativa 2 da questão 3b' ) );
$question3a->addAlternative( new Alternative( 'Alternativa 3 da questão 3b' ) );

$question3c = new Question( 'Questão 3c que depende da alternativa 3 da questão 2a' );
$question3c->addAlternative( new Alternative( 'Alternativa 1 da questão 3c' ) );
$question3c->addAlternative( new Alternative( 'Alternativa 2 da questão 3c' ) );
$question3c->addAlternative( new Alternative( 'Alternativa 3 da questão 3c' ) );

$question3d = new Question( 'Questão 3d que depende da alternativa 1 da questão 2b' );
$question3d->addAlternative( new Alternative( 'Alternativa 1 da questão 3d' ) );
$question3d->addAlternative( new Alternative( 'Alternativa 2 da questão 3d' ) );
$question3d->addAlternative( new Alternative( 'Alternativa 3 da questão 3d' ) );

$question3e = new Question( 'Questão 3e que depende da alternativa 2 da questão 2b' );
$question3e->addAlternative( new Alternative( 'Alternativa 1 da questão 3e' ) );
$question3e->addAlternative( new Alternative( 'Alternativa 2 da questão 3e' ) );
$question3e->addAlternative( new Alternative( 'Alternativa 3 da questão 3e' ) );

$question3f = new Question( 'Questão 3f que depende da alternativa 3 da questão 2b' );
$question3f->addAlternative( new Alternative( 'Alternativa 1 da questão 3f' ) );
$question3f->addAlternative( new Alternative( 'Alternativa 2 da questão 3f' ) );
$question3f->addAlternative( new Alternative( 'Alternativa 3 da questão 3f' ) );

$question3g = new Question( 'Questão 3g que depende da alternativa 1 da questão 2c' );
$question3g->addAlternative( new Alternative( 'Alternativa 1 da questão 3g' ) );
$question3g->addAlternative( new Alternative( 'Alternativa 2 da questão 3g' ) );
$question3g->addAlternative( new Alternative( 'Alternativa 3 da questão 3g' ) );

$question3h = new Question( 'Questão 3h que depende da alternativa 2 da questão 2c' );
$question3h->addAlternative( new Alternative( 'Alternativa 1 da questão 3h' ) );
$question3h->addAlternative( new Alternative( 'Alternativa 2 da questão 3h' ) );
$question3h->addAlternative( new Alternative( 'Alternativa 3 da questão 3h' ) );

$question3i = new Question( 'Questão 3i que depende da alternativa 3 da questão 2c' );
$question3i->addAlternative( new Alternative( 'Alternativa 1 da questão 3i' ) );
$question3i->addAlternative( new Alternative( 'Alternativa 2 da questão 3i' ) );
$question3i->addAlternative( new Alternative( 'Alternativa 3 da questão 3i' ) );

$question3 = new ConditionalQuestion( $interviewer );
$question3->setQuestionForAlternative( $question3a , $a1_2a );
$question3->setQuestionForAlternative( $question3b , $a2_2a );
$question3->setQuestionForAlternative( $question3c , $a3_2a );
$question3->setQuestionForAlternative( $question3d , $a1_2b );
$question3->setQuestionForAlternative( $question3e , $a2_2b );
$question3->setQuestionForAlternative( $question3f , $a3_2b );
$question3->setQuestionForAlternative( $question3g , $a1_2c );
$question3->setQuestionForAlternative( $question3h , $a2_2c );
$question3->setQuestionForAlternative( $question3i , $a3_2c );

$interview = new Interview();
$interview->addQuestion( $question1 );
$interview->addQuestion( $question2 );
$interview->addQuestion( $question3 );

$interviewer->interview( $interview , $interviewee );

 

 

 

E a View iria exibir os dados que o Controller iria reunir, nesse caso:

João Batista Neto - Juliano Amadeu, Questão 1
Juliano Amadeu - João Batista Neto, Alternativa 1 da questão 1
João Batista Neto - Juliano Amadeu, Questão 2a que depende da alternativa 1 da questão 1
Juliano Amadeu - João Batista Neto, Alternativa 1 da questão 2a
João Batista Neto - Juliano Amadeu, Questão 3a que depende da alternativa 1 da questão 2a
Juliano Amadeu - João Batista Neto, Alternativa 3 da questão 3b

 

Mais ou menos isso?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pessoal, por favor, não floodemos o tópico com boas intenções, já sabemos que todos as tem. Vamos, em vez disso, manter o nível técnico do tópico.

 

Alguém poderia, por favor, dizer o que sabemos sobre MVC? Ou, pelo menos, qual é a intenção/motivação de utilizá-lo?

 

As classes fitas até agora, Question, ConditionalQuestion, Alternative, Interview, Interviewee e Interviewer (neste caso creio que sejam Entities, right?) seriam a Model, o Controller seria o que iria fazer uma ligação desses dados com a View, por exemplo seria o intermediário dessas ações:

E a View iria exibir os dados que o Controller iria reunir, nesse caso:

 

Mais ou menos isso?

 

Bom, muito bom.

 

E qual o objetivo disso? Porque não devemos misturar tudo?

Compartilhar este post


Link para o post
Compartilhar em outros sites

qual é a intenção/motivação de utilizá-lo?

 

Resumidamente, separar a parte lógica, da parte de apresentação da aplicação? Assim, se caso eu queira efetuar um teste unitário (apenas um exemplo) do código que guarda uma questão (seguindo o assunto atual) em determinado local (em um BD?), posso fazer isso sem depender de código de layout ou outras dependências. O teste fica restrito apenas à funcionalidade daquela classe.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Resumidamente, separar a parte lógica, da parte de apresentação da aplicação?

 

Tá, mas qual a motivação disso?

 

Assim, se caso eu queira efeutar um teste unitário do código que guarda uma questão (seguindo o assunto atual) em determinado local (em um BD?), posso fazer isso sem depender de código de layout ou outras dependencias.

 

Testes devem ser feitos, independente de 3-tiers, 5-tiers ou quantas você quiser utilizar. Não sei aos outros, mas esse argumento não me convenceu...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Aí foi só um exemplo. :thumbsup:

Poderia trocar o exemplo do Teste, por um Webservice, no qual seria trocado apenas a View e o Controller, o código da Model permaneceria o mesmo.

 

-Edit-

 

Temos o código referente à nossa entidade Question, e um Controller para adicionar novas questões.

 

Digamos que atualmente nós salvamos a questão no nosso BD, que foi modelado seguindo o esquema do Henrique, se de repente nós quisermos mudar a estratégia, e não salvar essa questão no Banco de Dados, mas sim exportar diretamente para um arquivo PDF para que um entrevistador possa usar, apenas seria necessário criar uma nova Action nesse Controller para isso, pois a minha entidade Question (Ou qualquer outra parte da camada de Model) não precisa saber como e onde ela é usada, ela apenas precisa fornecer uma interface bem definida para que ela possa ser manipulada.

 

Melhorou? :)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Esse argumento foi melhor, reutilização é sempre um bom argumento. Pode elaborar um pouco mais? Mas dessa vez esqueça webservice, foque exclusivamente em uma web app como a que vamos desenvolver.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu acredito que seria abstrair a informação, como sempre.

 

Nesse código do questionário, qualquer um pode ser o entrevistador, desde o Silvio Santos até o Mickey Mouse e qualquer um pode ser o Entrevistado, do Eike Batista ao Chupa Cabra.

 

Eu acho que, num conceito MVC, o Controller seria a Entrevista, as requisições feitas seriam as Perguntas, as Respostas seriam as Models e a View, a saída.

 

Certo?

 

Mas só pelo fato de terem enfiado o GitHub no meio, melou pra mim. Sinto muito.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Imagino que a vantagem do MVC é a independência das camadas. Pode-se trocar toda uma camada sem ter que mexer na implementação das outras. Ao meu ver até segue o OCP dos princípios SOLID.

 

Será que só falei besteira? :upset:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Imagino que a vantagem do MVC é a independência das camadas. Pode-se trocar toda uma camada sem ter que mexer na implementação das outras. Ao meu ver até segue o OCP dos princípios SOLID.

 

Será que só falei besteira? :upset:

 

Absolutamente não Jonas, você não disse nenhuma besteira! Você foi simples, claro e direto, exatamente como deveria ser!

 

:clap:

 

O.C.P. define que um módulo (função, classe, entidade, etc) deve ter seu código inviolável, ou seja, mudanças nas regras de negócio devem ser feitas estendendo funcionalidades, nunca modificando código. Segundo O.C.P., ninguém tem permissão para tocar no código. Conseguimos identificar vários pontos dos princípios S.O.L.I.D. em M.V.C., inclusive S.R.P., poderíamos dizer, por exemplo, que cada camada tem sua responsabilidade bem definida.

 

Consegue elaborar um pouco mais, Jonas? Tente montar uma definição mais formal para nós como as que foram feitas em postagens anteriores, descrevendo a Intenção, Motivação, Aplicabilidade e os Participantes.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Mas só pelo fato de terem enfiado o GitHub no meio, melou pra mim. Sinto muito.

 

Ué Bruno, porque você não tenta? Já é a segunda vez que vejo você desistindo de colaborar por causa do Git.

Tem tanto material ensinando a utilizá-lo, sem contar que se você usar o Windows, tem o TortoiseGit que disponibiliza uma GUI para efetuar as ações.

 

Pro Git

Git Reference

Compartilhar este post


Link para o post
Compartilhar em outros sites

Consegue elaborar um pouco mais, Jonas? Tente montar uma definição mais formal para nós como as que foram feitas em postagens anteriores, descrevendo a Intenção, Motivação, Aplicabilidade e os Participantes.

Bacana, fiquei feliz em acertar o ponto. O que posso contribuir com o pouco que conheço hoje é isso:

 

MVC - Model, View e Controller

 

Intenção

Separar a aplicação em 3 camadas com responsabilidades únicas de forma que sejam seguidos os princípios OCP (Open/Closed Principle) e SRP (Single Responsability Principle).

 

Motivação

O princípio do OCP (Open/Closed Principle) é "entidades de software (classes, módulos, funções, etc.) devem ser abertos para extensão mas fechados para modificação", ou seja, a idéia é que a cada vez que você precise mudar algum comportamento, que seja feito na forma de adição de novas implementações (e abstrações) e não na alteração das implementações já existentes (não mexer em código que já foi testado e está funcionando).

Imagine que você possui uma aplicação MVC já pronta que utilize BD MySQL; aí surge um novo projeto mas será utilizado um BD NoSQL, CouchDB por exemplo. Como suas camadas são bem separadas e independentes, você não terá que mexer nos controllers ou nas views, aí você pode reutilizar as classes estruturais de sua outra aplicação e criar as novas implementações para CouchDB.

 

----

 

Realmente não sei se está certo, inclusive se tem besteira fiquem à vontade para alterar, já que pode confundir o pessoal que frequenta o fórum. Quanto aos outros itens (aplicabilidade, participantes e diagramas) eu vou ficar devendo por falta de conhecimento mesmo. :blush:

Compartilhar este post


Link para o post
Compartilhar em outros sites

Quanto aos outros itens (aplicabilidade, participantes e diagramas) eu vou ficar devendo por falta de conhecimento mesmo.

 

Okay, sem problemas.

 

Só deixa eu esclarecer um ponto importante aqui, S.O.L.I.D. são princípios de design de objetos. M.V.C. é um padrão de arquitetura, ou seja, apesar de podermos transferir conhecimentos adquiridos com S.O.L.I.D. para o M.V.C., esses princípios não foram feitos especificamente para isso.

 

MVC :seta: Padrão de arquitetura

Intenção

Isolar a interface de usuário das regras de negócio da aplicação, permitindo que o desenvolvimento seja independente e desacoplado. Com a separação das camadas, mudanças na interface de usuário não afetarão as regras de negócio definidas na Model.

Motivação

Uma aplicação pode ter diversas interfaces de usuário. Podemos ter uma interface para uma aplicação mobile nativa, um site otimizado para dispositivos móveis, um site para ser visualizado em um navegador desktop. Independentemente do número de interfaces de usuários que tenhamos, as regras de negócio serão sempre as mesmas. Com M.V.C., as Views e Controllers trabalham em conjunto para oferecer acesso e renderizar a Model e, com isso, podemos oferecer diversas aparências e comportamentos para uma aplicação.

 

As Views de uma aplicação web são as páginas que montamos utilizando HTML para marcação, Javascript para comportamento e CSS para estilo.

 

Os Controllers de uma aplicação web são os responsáveis por receber as requisições
HTTP
, identificar o objetivo dessas requisições, transformá-las em ações, utilizar a Model para validar essa requisição e acionar a View adequada para responder essa requisição.

 

A(s) Model(s) de uma aplicação web são um conjunto de objetos, tanto de acesso a dados, como regras do domínio da aplicação.

Aplicabilidade

Podemos utilizar M.V.C. quando

  • As regras de negócio não variam, independente da interface de usuário utilizada.
  • Precisamos ter variações na interface de usuário para permitir diversos fluxos, aparências e comportamentos diferentes para a aplicação.
  • Precisamos utilizar a aplicação em dispositivos diferentes ou por clients diferentes.
  • Precisamos derivar as Views e Controllers de diferentes classes.

Estrutura

gallery_94216_5_6899.png

Participantes:

Model

Encapsula as regras de negócio e oferece uma interface para que a View e Controller possam acessá-las. Também oferece uma interface para acesso aos dados da aplicação, permitindo criar, editar, atualizar e excluir esses dados segundo as regras definidas.

 

A Model nunca conversa com a View. De fato, a Model sequer deve ter conhecimento da View que a representa.

View

Define um conjunto de elementos que, juntos, formam a interface gráfica de usuário e renderiza a Model de forma que o usuário possa interagir com a aplicação. Através dessa interface, o usuário tem acesso aos dados da aplicação e pode manipulá-los segundo as regras definidas na Model.

 

A View representa, visualmente, a aplicação e seus dados. Ela sempre terá conhecimento de seu Controller e saberá como renderizar a Model utilizando sua interface.

Controller

Recebe as entradas do usuário e coordena as Views segundo as respostas obtidas através do acesso aos objetos da Model.

De uma forma simplista, a View são os olhos onde, com eles, podemos ver aquilo a que a aplicação se propõe. A Model é o cérebro que pensa e rege as regras de negócio da aplicação. O Controller é o elo de ligação entre as ações do usuário e as consequências dessas ações, transformando requisições em respostas, segundo as regras da Model.

 

Cada uma dessas camadas podem utilizar de padrões e princípios de design de objetos para seus próprios objetivos. A Model, por exemplo, não comunica-se com a View, mas a View pode ser atualizada pela Model caso uma atualização em determinada informação tenha ocorrido. O padrão de design Observer pode ser utilizado para permitir que a Model atualize seus observadores em caso de modificação de estado ou de dados que estão sendo exibidos. Command pode ser utilizado para transformar as requisições HTTP em ações executáveis, Chain of Responsibility pode ser utilizado para criar um encadeamento de responsabilidade, onde um ou mais objetos terão a oportunidade de manipular determinada ação do usuário.

 

:seta: Algum front-end developer se habilita a nos ajudar no desenvolvimento das Views?

gallery_94216_5_6899.png

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pronto Juliano amadeu, agora você tem a faca e o queijo não mão... bom divertimento...

 

kkkk. Muitíssimo obrigado pelas diversas aulas que tive neste post. Desculpem por não ter voltado antes para responder.

 

Bom, como já comecei o projeto de outra maneira (bem mais simplista) vou finalizar dessa forma (tenho prazo curtíssimo), mas as aulas foram excelentes embora eu ainda tenha MUITAS dúvidas. A principal, e como o João falou, é como deixar de pensar SQL.

 

Por exemplo. Na classe Interview criada pelo João, eu teria que pegar a pergunta e passar ao objeto. Essa pergunta vem do DB. A aquisição das informações do DB ficariam na página da aplicação?

 

Eu tenho uma série de classes que fazem o tratamento da string SQL e retornam o resultado. Faço uma composição/agregação entre a classe SQL e a classe interview para resgatar as perguntas?

 

Maldito SQL!!!

 

Juliano, esse fragmento que você nos passou é insuficiente para qualquer sugestão, não há como lhe dizer se é uma boa ou má solução, apenas vendo o esqueleto de três classes, é preciso algo que represente, de fato, o problema.

 

Vamos analisar seu problema:

 

 

A descrição do seu problema também é insuficiente, teremos:

 

1. Perguntas e respostas

2. O pesquisador informará as respostas, pelo que entendi, será uma pesquisa de campo, o pesquisador irá até o entrevistado e, depois de coletar as informações de que precisa, preencherá um formulário com os dados.

 

Coisas que faltaram:

 

1. Seu sistema terá várias pesquisas acontecendo simultaneamente?

2. Uma determinada pesquisa será restrita ao pesquisador, ou seja, apenas ele terá acesso?

3. As respostas das perguntas serão sempre fixas, A, B, C ou D? Não haverá a possibilidade de uma resposta dissertativa?

4. O pesquisador informou as alternativas, e ai? O que acontece depois disso?

 

Percebe amigo, não há a menor possibilidade de se "pensar orientado a objetos" se você não "pensar em resolver um problema antes". A base da orientação a objetos é definir o relacionamento entre os participantes e delegar responsabilidades. Coesão e coerência são duas palavras chave da orientação a objetos, e você só alcançará a coesão e coerência quando você compreender o propósito da sua aplicação e como as coisas devem acontecer.

 

João, desculpe pela brevidade das informações.

Como é um sistema um pouco complexo, tentei ser mais simplista para tentar buscar a essência da Orientação a Objetos e nem tanto buscar a resposta para meu problema por completo. Achei que seria um abuso da minha parte, mas sua adivinhação para descrever o projeto foi bastante fiel à minha necessidade. Alguns pequenos ajustes e ficaria perfeito. Assim que tiver tempo vou reescrever alguma coisa no código para ficar mais adequado.

 

Percebe amigo, não há a menor possibilidade de se "pensar orientado a objetos" se você não "pensar em resolver um problema antes".

 

Também acho que uma grande parte da minha dificuldade está no planejamento. Eu normalmente já me jogo no Eclipse e começo a escrever código. Vou refletir mais antes de codificar. Acho que isso vai resolver muitos problemas.

 

Mais uma vez, obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.