Páginas

terça-feira, 6 de agosto de 2013

Law of Demeter(Lei de Demeter)

O paradigma da orientação a objetos (OO) existe a muitos anos e é utilizado em grande parte dos projetos em desenvolvimento hoje, porém até hoje encontramos dificuldades no desenvolvimento de sistemas OO. Isso se deve principalmente a falta de conhecimento sobre OO e tudo que engloba esse poderoso paradigma.

O que podemos concluir é que muitos profissionais não conhecem nada ou sabem pouco sobre OO. Mas será que a culpa é realmente deles? Na graduação onde deveríamos ver tudo sobre OO, acabamos vendo apenas os conceitos básicas como classe, atributos, herança, polimorfismo, encapsulamento e etc.. Mas isso é apenas a base para o desenvolvimento de um projeto orientado a objetos, existem ainda os princípios, leis, patterns e técnicas que merecem muito a nossa atenção.





O objetivo desse post é apresentar a “Law of Demeter”(Lei de Demeter), que foi criada em 1987 por Karl Lieberherr e Ian Holland, da Northeastem Univerity, para reduzir as dependências entre objetos, e também é conhecido como o principio do mínimo conhecimento, ou seja, “nunca converse com estranhos”.


Definição da Lei de Demeter

Para todos os métodos que estão no objeto X somente podem se comunicar com :

  • Métodos de X;
  • Parâmetros do próprio método;
  • Por objetos criados ou instanciados pelo próprio método;
  • Atributos de X;

Uma metáfora bastante usada na internet que exemplifica muito bem esse caso é a metáfora do cachorro:


“Quando você precisa que um cachorro ande, você dá a ordem para as pernas diretamente, ou para o cachorro? Obviamente que para o cachorro e este sabe o que precisa ser acionado para andar.”






Vantagens

As vantagens do uso da Lei de Demeter são:

  • Diminuição das dependências (Baixo Acoplamento)
  • Mais fácil de manter
  • Mais fácil evoluir

Exemplo

Dado eu sou usuário de uma loja online,
Quando eu quero saber o total das minhas compras,
Então eu verifico no carrinho de compras.

Considere o trecho de código abaixo:

No exemplo apresentado acima para realizar o cálculo do valor total das compras é necessário o carrinho percorrer todos os itens e solicitando a produto qual é o seu valor, violando assim totalmente a Lei de Demeter, uma vez que, estamos fazendo uma solicitação ao produto que é um objeto que não faz parte dos argumentos do método ou membros da própria classe.
A abordagem mais correta seria:




Agora podemos verificar que nossa classe esta seguindo a lei e se comunicando apenas com objetos que ela tem o conhecimento, diminuindo assim a sua dependência (Baixo acoplamento).

Conclusão

É logico que a lei não se refere apenas a isso, este exemplo foi apenas uma breve introdução sobre o assunto, para quem quiser se aprofundar no assunto tem alguns links nas referências, porem podemos concluir o quanto é poderosa a OO e como pequenos ajustes podem deixar nossos projetos muita mais robustos e escaláveis.

Apresentação



Referencias




sábado, 20 de outubro de 2012

Software não é Prédio, Ponte ou qualquer outra Obra da Engenharia Civil

Sou aluno de Pós-Graduação Engenharia de Software de uma instituição renomada no RS e hoje escutei um dos maires absurdos que poderia ter escutado em curso de pós-graduação, um dos meus professores na aula de hoje depois de um questionamento que lhe fiz sobre desenvolver todo o projeto antes para depois codificar me respondeu que: "..imagina construirmos um prédio sem projetarmos encanamento, sem projetarmos a fiação elétrica, sem projetarmos estacionamentos e cômodos...".

Foi o maior absurdo que ouvi nos últimos tempos, e olha que faz um certo tempo que ouço e vejo absurdos no desenvolvimento de software.

Não quis e não quero imaginar um software como um prédio, um SOFTWARE não é uma obra de ENGENHARIA CIVIL, um SOFTWARE pode ser comparado a um organismo vivo que ira evoluir ao longo do tempo, ou alguém já projetou um software todo antes e no fim do projeto aquele software era exatamente como o projeto inicial, acho pouco provável, até mesmo esse querido professor( é claro se ele já fez algum software profissionalmente).

Essa explicação dada por esse senhor me fez refletir muito sobre quanto um comentário como esse tem um impacto em nossos projetos de software, pois todos que estavam na sala e que ouviram o que foi dito podem levar para suas empresas e times essa metáfora que lhes foi dita.

No inicio do desenvolvimento de software acredito que essa metáfora tenha sido de grande valia, uma vez que projetávamos e desenvolvíamos softwares bastante simples em comparação aos desenvolvidos atualmente, porem nos tempos de hoje onde os negócios mudam em um piscar de olhos, onde os sistemas são imensamente mais complexos que antes e que nossos softwares a cada dia que passa tentam imitar mais os seres humanos é IMPOSSÍVEL projetar um sistema inteiro antes do desenvolvimento.

O software tem que evoluir ao longo do tempo isso não sou eu quem esta dizendo isso já é discutido a tempos, Craig Larman em artigo recente escreveu sobre isso.


"A metáfora do edifício [aplicada ao desenvolvimento de software] já perdeu sua utilidade; é hora de mudar novamente. As estruturas conceituais que hoje construímos são complexas demais para serem especificadas detalhadamente com antecedência; são também complexas demais para serem construídas sem defeitos. Devemos, portanto, adotar uma abordagem radicalmente diferente. Vamos nos voltar à natureza e estudar a complexidade das coisas vivas, em vez dos trabalhos mortos do homem.

Nesse contexto, encontramos estruturas com uma complexidade imensa: o cérebro, por exemplo, é mais complexo do que é possível mapear e mais poderoso do que se pode imitar; é rico em diversidade, autoprotetor e auto-renovador. O segredo é que o cérebro evolui; não é construído. O mesmo deve acontecer com nossos sistemas de software; alguns anos atrás, Harlan Mills propôs que qualquer sistema de software deve ser evoluído através do desenvolvimento incremental."[Fred Brooks, 1986 
]


O trecho do artigo  "Não Existe Bala de Prata – Essência e Acidente em Engenharia de Software" [Brooks 1986], é de 1986 e isso mostra que esse pensamento não é algo recente, porem ainda nos tempos atuais ainda temos que escutar que o software é um "trabalho morto" feito pelo homem, para encerrar só tenho mais uma afirmação para fazer, SOFTWARE NÃO É PRÉDIO, PONTE OU QUALQUER OUTRA OBRA DE ENGENHARIA CIVIL.




domingo, 23 de setembro de 2012

Testes de Unidade, porque não usamos?


Em 1997 quando Kent Beck apresentou ao mundo a primeira versão do JUnit não imaginava que 15 anos depois muitos programadores Java não sabem como criar um simples teste com o framework dele. O objetivo é procurar trazer ao debate o porquê de nossos desenvolvedores não conhecerem, ou não utilizarem os testes de unidade para garantir a qualidade do nosso código ao invés de repassarem a responsabilidade aos analistas de teste, testando assim a qualidade do código que estamos produzindo.

Os testes de unidade são tão antigos quando a programação orientada a objetos e mesmo assim nos tempos atuais a maioria dos desenvolvedores não utiliza essa poderosa ferramenta que pode nos auxiliar a desenvolver um produto com muito mais qualidade, em praticamente todas as linguagens existem frameworks baseado na plataforma XUnit para testes de unidade, sito os exemplos do JUnit para Java, PHPUnit para o PHP, QUnit para Jquery, NUnit para .Net e etc...
Ao conversar com desenvolvedores escutei diversas explicações ou justificativas da não utilização dos testes de unidade em suas empresas:

  • A falta de cultura para criação de testes;
  • Na graduação aprendemos a testar com Main ao invés de Teste Unitário;
  • Desenvolvedor não testa;
  • Não temos tempo para Testes;


1º A falta de cultura para criação de testes: como assim falta de cultura para criação dos testes. Os testes de unidade tem origem junto com o a orientação a objetos e mesmo assim não temos a “cultura” para criar nossos testes, essa é uma justificativa nos mínimo estranha para se dar pela não criação de testes. Isso é um problema do nosso ego, todo o desenvolvedor acha que não precisa disso, porque ele se garante sozinho, a velha cultura do Super Homem, o de fazer o certo da primeira vez, “vulgo” falta de HUMILDADE.

2º Na graduação aprendemos a testar com Main ao invés de Teste Unitário: no período mais critico, que é a nossa formação invés de testarmos nossos códigos com Testes Unitários testamos com o Main, chegar soar como brincadeira isso, escutei um dia de um professor “Usamos o Main porque é mais didático”. Didático? Isso quer dizer mais fácil para você ensinar. O profissional que esta sendo formado que se vire em aprender sobre Testes de Unidade, não é de responsabilidade sua né meu querido professor. Pois o dia em que começarem a ensinar os alunos a fazer um assertEquals ao invés de um System.out.println() de um “Hello Word”, vai ser o primeiro passo para acabar com a justificativa anterior.

3° Desenvolvedor não testa: pois é, já escutei muito essa justificativa também, qual é a função do desenvolvedor então? Não é entregar um produto com o máximo possível de qualidade (para Kent Beck esse possível esta dividido em dois níveis excelente e o insanamente excelente), e como eu consigo isso sem testar o que estou entregando, eu não tenho a resposta, e você tem?

4° Não temos tempo para Testes: eu li uma metáfora certa vez que é mais ou menos assim, “se você estiver em uma sala de cirurgia e passando muito mal, o médico chega e ira fazer todo aquele ritual de lavagem das mãos, você é o cliente, e mesmo que você solicite que ele não faça aquilo e venha logo lhe atender pois você não esta bem, ele não ira atende-lo(não é o cliente quem manda?), porque a lavagem das mãos é essencial para que o trabalho dele seja bem feito e por isso ele nunca ira atende-lo”. Os Testes de Unidade são essências para a qualidade do nosso trabalho e é nossa função mostrar isso a nossos clientes e gerentes.

Acho que os motivos para não testarmos nosso código são diversos e esta na hora de começarmos a ataca-los pois é inadmissível depois de tanto tempo ai estarmos discutindo um assunto tão antigo como esse, mas como vimos, isso vai precisar do envolvimento de todos nesse trabalho para podermos realizar essa mudança. 

terça-feira, 11 de setembro de 2012

Apresentação no TDC2012 Florianopolis



 The Developers Conference 2012, um evento organizado pela GlobalcodeNo mês passado  participei do TDC 2012 Floripa, fiquei impressionado com a quantidade de assuntos debatidos e apresentados sobre TI, eram 21 trilhas diferentes dividida em 3 dias de apresentação foi com certeza um evento grandioso e bastante valioso. Eu tive a honra de apresentar uma palestra na trilha de arquitetura. O titulo da minha palestra era Como Salvar o Coração do Sistema, abaixo está um resumo.


Resumo:
Quando nosso coração esta muito grande, ou com seus vasos entupidos por gorduras acumuladas durante anos, é bem provável que teremos problemas na nossa velhice. Pois no software isso também pode acontecer, só que o coração do nosso software é o nosso domínio, onde esta toda nossa regra de negocio, e muitas vezes ao longo do tempo não cuidamos bem dele. O objetivo dessa palestra é mostrar técnicas que podem nos ajudar a salvar nosso coração, como os padrões GRASP que nos ajudaram a organizar e limpar nosso domínio e sempre utilizando o TDD para garantir a qualidade do nosso código.

Descrição:
O coração é o órgão mais importante do corpo humano e ao longo dos anos não cuidamos muito bem dele, comendo gorduras em excesso causando assim no futuro problemas de artérias entupidas, ou comendo sal em excesso acarretando assim em uma pressão sanguínea alta, esses e outros problemas provavelmente se não forem tratados levaram a um enfarto e até a morte da pessoa, no software isso não é diferente, muitas vezes a regra de negócio encontra-se espalhada por diversos lugares na nossa aplicação (Controller, Dominio, Banco, DAOs,Visão, ...), encontra-se confusa e complexa de forma que não temos coragem de refatorar.
Erick Evans, no livro Domain-Driven Design: Tackling Complexity in the Heart of Software, diz que “Quando um software traz consigo um comportamento complexo e é desprovido de um bom design, torna-se difícil refatorar ou combinar elementos. Começam a aparecer duplicações a partir do momento em que o desenvolvedor não mostra confiança em prever todas as implicações de uma mudança”.
Os padrões GRASP não são tão difundidos como os do GoF, porem são tão importantes quanto, são conceitos que nos auxiliam muita na montagem de um modelo de domínio robusto e flexível e sempre baseados na responsabilidade, Martin Fowler, no prefacio livro Domain-Driven Design: Tackling Complexity in the Heart of Software, diz que "Entender responsabilidades é essencial para o bom projeto orientado a objetos". 
Vamos apresentar como os padrões GRASP podem nos auxiliar a limpar as artérias do nosso sistema mantendo assim o nosso coração sempre saudável e limpo, evitando a debito técnico (o infarto), pois em algum momento ele sempre é cobrado.
Utilizaremos exemplos reais de problemas que tivemos e como resolvemos, utilizando o TDD e os padrões GRASP, mostraremos como a utilização dessas duas técnicas pode salvar o nosso software de um enfarte.




Repositório com os fontes clique aqui.

sábado, 14 de julho de 2012

Princípios SOLID - parte 1

Um dos princípios ágeis é a resposta rápida a mudança, porem muitas vezes o sistema encontra-se tão acoplado que não conseguimos dar uma resposta rápida a mudança solicitada e em consequência a isso ferimos um dos quatro valores do XP, "Coragem", pois não vamos querer mexer no que esta funcionando, para garantir o que esta funcionando vamos copiar, colar e dar uma alterada no que precisamos, muito bem você conseguiu atender rápido a solicitação do teu cliente, porem acaba de criar um debito técnico no projeto, e como tal em algum momento ele será cobrado e os juros cobrados serão bastante altos pode ter certeza.

Pois bem, o que fazer então? Utilizar boas praticas de desenvolvimento de software (sei que na moiraria das vezes a pressão pela entrega é tanta, que as boas praticas que se %$%$@%$**(@#, mas garanto a vocês elas podem nos salvar de problemas muitas vezes impossíveis de resolver), o benefícios de um código limpo e organizado, com baixas dependências fara com que você abrace a mudança, e com certeza não vai te faltar coragem quando a próxima solicitação do cliente chegar (aquelas mudanças que mudam tudo que se tinha pensado). Os princípios SOLID de desenvolvimento foram introduzidos por Robert C. Martin, são cinco princípios que podem nos auxiliar a desenvolver um projeto orientado a objetos bastante robusto e faram com que possamos alcançar os benefícios sitados anteriormente. 
  
Princípios SOLID

  • S  -  Silge Responsability Principle (Responsabilidade Unica)
  • O -  Open Close Principle
  • L  -  Liskov Substitution Principle
  • I   -  Interface Segregation Principle
  • D  - Dependency Inversion Principle



Vou fazer um breve resumo de Silge Responsability Principle e Open Close Principle, e depois apresentar um exemplo onde possamos ver na pratica um pouco de cada um.

1. Silge Responsability Principle (Responsabilidade Unica)



Todas as classes do nosso sistema devem ter um unica responsabilidade, pois elas não podem ter mais de uma razão para existir. Porque cada responsabilidade a mais que a classe venha a ter pode se tornar um eixo de mudança, tornando essas responsabilidades acopladas. Muitas vezes alterações em uma das responsabilidades pode impactar ou inutilizar a outra, tornando assim nosso projeto frágil e difícil de dar manutenção. 
O princípio da responsabilidade unica é extremamente simples, porem na pratica é um dos mais difíceis de implementar, definir o principio como fiz anteriormente é algo natural e simples de fazer, porem implementa-lo vai alem de um simples projeto de software orientado a objetos, temos que entender os conceitos do domínio para podermos criar os nossos objetos com uma unica responsabilidade.

2. Open Close Principle(Aberto e Fechado)

Quando uma mudança em um sistema resulta em uma cascata de mudanças em módulos dependentes, o projeto do sistema possui características indesejáveis. A cascata de alterações torna o sistema mais frágil e torna suas partes mais difíceis de reutilizar O princípio “open-closed” sugere que se construam classes que
nunca mudem. Quando os requisitos mudarem, o comportamento das classes deve ser estendido pela adição de código novo, não pela alteração do código existente.

Estudo de Caso:(Esse exemplo foi pego de um teste que um amigo meu recebeu para entrar em um empresa)

Em um sistema de ingressos de um cinema, possuímos a classe ingresso que possui informações de sala, horário e valor do ingresso. Ela estava atendendo muito bem a responsabilidades que foram definidas a ela, porem nosso cliente fez uma alteração dos requisitos iniciais e que pode impactar em nosso projeto pois não tinha sido previsto. Ele precisava que o ingresso tivesse um valor 'X', porem dependendo do tipo de pessoa e dia da semana deveria ser dado um desconto na compra do ingresso. Abaixo estão os requisitos da nova funcionalidade que deveremos projetar e implementar usando os dois princípios SOLID descritos anteriormente.


Valor do Ingresso Normal: R$ 10.00
Crianças: R$ 5.50
Estudantes: R$ 8.00
Idosos: R$ 6.00

Descontos de acordo com o dia de semana
Segunda-Feira:
      - 10% para todos(crianças, idosos, estudantes)
Terça-Feira:
      - 15% idosos e crianças;
      - 5% estudantes;
Quarta-Feira:
      - 40% idosos
      - 30% crianças
      - 50% estudantes
Quinta-Feira
      - 30% idosos e estudantes
Sexta-Feira
      - 11% crianças
Domingo/Sábados/Feriados
      - 5% Idosos
OBS: Todo estudante mediante apresentação da carteirinha de estudante possui desconto para todos os 
dias da semana, exceto finais de semana 35% de desconto em todos os ingressos;

Solução Proposta:

Podemos criar um método que retorna o valor, passando o dia da semana e a pessoa que está comprando( duas Enum)  retornarValorComDesconto(diaSemana,Pessoa), se ele tivesse entregue assim com certeza ele estaria desempregado no momento, não sei a solução dele mas ele conseguiu a vaga, hahahaha. 

Pois bem vamos a solução que desenvolvi para esse problema, criei a classe DescontoDoDia que é abstrata onde implementei os métodos para retorno do desconto de acordo com o tipo de ingresso, para cada dia da semana criei uma classes que estende DescontoDoDia, elas fazem sua implementação do desconto dado de acordo com a pessoa. A classe ingresso eu mantive e apenas fiz extends dos novos tipos definidos e cada um com o seu valor de ingresso característico.

E onde fica o método para calcular o desconto? Em Ingresso ou nos DescontosDoDia? Não coloquei em nenhuma e sim em uma classe de serviço(padrões do DDD), que faz esse calculo para mim, pois analisando o problema achei que não era responsabilidade de nenhuma das classes criadas o calculo do desconto, em padrões GRASP vou falar o que devemos fazer quando surgir problemas semelhantes a esse, mas por enquanto basta saber que usei o padrão Pure Fabrication.

A solução achada contempla os dois princípios definidos anteriormente, uma vez que foram criadas classes com uma unica responsabilidade, e criamos classes que nunca mudaram, Ingresso e DescontoDoDia, se precisarmos de implementações futuras devido a novas categorias de desconto ou algo parecido provavelmente criando classes que estendam elas estaremos atendendo os requisitos. 

Pois bem, se os princípios passados forem entendidos e implementados, nossos projetos estarão bem menos acoplados e bem mais robustos para manutenções futuras que possam surgir. O código fonte e os  artefatos do exemplo estão no GiHub clique aqui. Obrigado e até a próxima.








Código Limpo de Robert C. Martin

Para quem deseja ser um desenvolvedor que preza acima de tudo pela qualidade do código que esta criando, a leitura do livro de Robert C. Martin é quase que uma leitura obrigatória. Abaixo está um texto que tirei da orelha do livro, CÓDIGO LIMPO é a minha #dicadelivro.


"Há duas vertentes para se obter habilidade profissional: conhecimento e trabalho. Você deve adquirir o conhecimento dos princípios, padrões, praticas e heurísticas que um profissional habilidoso sabe, e também esmiuçar esse conhecimento com seus dedos , olhos e corpo por meio do trabalho árduo e da prática.

Posso lhe ensinar a mecânica para se andar de bicicleta. Na verdade, a matemática clássica é relativamente direta. Gravidade, atrito, momento angular, centro de massa e assim por diante, podem ser demonstrados com menos de uma pagina cheia de equações. Dada essas formulas, eu poderia provar pra você que é prático andar de bicicleta e lhe dar todo o conhecimento necessário para que você. E mesmo assim você cairá na primeira vez que tentar.

Programar não é diferente. Poderíamos pôr no papel todos os princípios necessários para um código limpo e, então, confiar que você fará as tarefas (isto é, deixar você cair quando subir na bicicleta), mas que tipo de professor e estudante isso faria de nós?

Aprender a criar códigos limpos é uma tarefa árdua e requer mais do que o simples conhecimento dos princípios e padrões. Você deve usar a camisa; praticar sozinho e ver que cometeu erros; assistir a outros praticarem e errarem; vê-los tropeçar e refazer seus passos; vê-los agonizar para tomar uma decisão e o preço que pagarão pro as terem tomado da maneira errada.

Esteja preparado para trabalhar duro enquanto lê esse livro. Esse não é um livro fácil e simples que você pode ler num avião e terminar antes de aterrissar. Este livro lhe fará trabalhar, e trabalhar duro. Que tipo de trabalho você fará? Você deverá descobrir o que está correto e errado nos códigos. Você terá de seguir o raciocínio conforme dividirmos módulos e os unirmos novamente. Isso levará tempo e esforço, mas achamos que valerá a pena".

Eu também acho que essa leitura vale muito a pena, e não é a toa que é a minha primeira indicação, boa leitura a todos e até o próximo.

terça-feira, 1 de maio de 2012

Padrões GRASP - parte 1

Após conhecer os padrões GRASP começamos a desenvolver muito mais claro e os "maus cheiros" diminuem consideravelmente, a minha intensão escrevendo este post é tentar explicar um pouco dos padrões ou conceitos GRASP, pois acredito que eles não são tão difundidos quanto os do GoF, porem são tão importante quanto.
Para começar devemos entender o que é responsabilidade, sendo assim devemos entender a responsabilidade pelo seu tamanho, por exemplo, uma grande responsabilidade pode envolver diversas classes e métodos, um exemplo disso é "gerenciar provas em um sistema de vestibular", isso pode envolver diversas classes ( sala, prova, candidato, etc ...) e diversos métodos, já se a responsabilidade for pequena isso pode envolver um único método, por exemplo, "imprimir lista de candidatos" isso talvez envolva um único método de uma classe , o entendimento de responsabilidade é importante pois assim começamos a entender a programação orientada a objetos,  para Craig Larman " uma responsabilidade não é a mesma coisa que um método - é uma abstração - porém métodos satisfazem as responsabilidades.", e Martin Fowler diz que "Entender responsabilidades é essencial para o bom projeto orientado a objetos".
As responsabilidades de um projeto podem ser divididas em “conhecer” e “fazer”

  1. As responsabilidades “conhecer” estão relacionadas à distribuição das características do sistema entre as classes;
  2. As responsabilidades “fazer” estão relacionadas com a distribuição do comportamento do sistema entre as classes;

A função principal dos padrões ou princípios GRASP é nos ajudar a projetar Orientado a Objetos com responsabilidade, pois como Craig Larman diz após entendermos os princípios e fundamentos os termos que veremos a seguir como especialista da informação, criador, e etc.., deixam de ser relevantes pois aprendemos o essencial que é como projetar guiados por responsabilidade.
Ao longo de 9 artigos pretendo explicar um pouco de cada padrão, e para isso vou usar o domínio sitado anteriormente, gerenciar as provas em um sistema de gerenciamento de vestibulares, para explicar o domínio vou utilizar a maneira bastante interessante que eu vi no livro DDD de Eric Evans, então vamos dar inicio ao trabalho.

Dialogo entre o Time e o Cliente para modelar o gerenciamento das provas:
...
Time: Bom dia, vamos começar pelas características da prova.

Cliente: Eu preciso definir qual o período de realização da prova, eu defino a data de realização e o horário de inicio e fim.

Time: Tem mais alguma coisa que você pretende definir ou diferenciar da prova?

Cliente: Sim, estava esquecendo já, as provas devem ser diferenciadas por tipos, hoje realizamos dois tipos de prova, Digital que são provas realizadas em nossos laboratórios de informatica, e as Presencias que são feitas em sala de aula.

Time: Notamos que você falou que 'hoje' vocês realizam essas provas, vocês pretendem inserir um novo tipo de prova?

Cliente: Sim, uma prova somente de Redação, que deve ser realizada nas fases posteriores ao processo, as fases de complementação de vagas.

Time: Então para esse primeiro momento não pretendem usar a prova de Redação?

Cliente: Não, isso é só para a 2º parte do processo.

Time: As provas podem ser realizadas ao mesmo tempo?

Cliente: Sim, porem em salas diferentes, para as provas digitais usamos bastante isso.

Time: Ok. Então vamos retomar para ver se o time entendeu o contesto, você precisa criar uma prova, definindo o período de inscrição e diferencia-las por um tipo que podem ser Digital e Presencial, e não precisamos nos preocupar se elas estarão no mesmo período, porem não podem usar as mesma salas correto? 

Cliente: Sim.

Time: Tem alguma coisa que diferencia as duas provas alem da escolha das salas?

Cliente: Sim, para quem faz prova digital eu posso definir se vai fazer a prova de redação ou não.

Time: Blz, e para quem faz prova digital, o sistema tem que restringir que as salas escolhidas sejam sempre os laboratórios?

Cliente: Não é necessário, pois as vezes temos que fazer alguns ajuste pois nem todos os laboratórios estarão disponíveis. 

Time: Ok, e tem mais algumas características sobre as salas que devemos levar em consideração? 

Cliente: Sim, precisamos diferenciar se elas vão ser usadas por deficientes físicos ou não, preciso colocar a capacidade máxima de candidatos em cada uma também.

Time: É preciso diferenciar por deficiência?

Cliente: Não, pois alocamos todos os deficientes na mesma sala, eles não são muitos por isso deixamos todos no mesmo ambiente, e assim conseguimos agilizar a logística também.

Time: Ok.

Cliente: Porem preciso que o candidato deficiente tenha uma descrição do que precisa para realizar a prova, pois assim agilizamos a logística. 

Time: Ok, e sobre as salas tem algo mais a ser dito?

Cliente: Sim, preciso imprimir a lista de porta, com todos os candidatos de cada sala, com nome, CPF, também tem que ter a lista de presença com o nome, CPF e local para assinatura do candidato.

Time: Ok, vamos retomar então: você precisa criar uma prova, definindo o período de inscrição e diferencia-las por um tipo que podem ser Digital e Presencial, e não precisamos nos preocupar se elas estarão no mesmo período, porem não podem usar as mesma salas, a diferença entre elas inicialmente é que para as provas digitais você poderá definir se vai ter redação ou não, as salas vão ser de dois tipos para quem possui uma deficiência e para quem não possui, para ambas as salas vamos gerar duas listas, uma de presença e outra de porta que a unica coisa que diferencia entre elas é o local para assinatura, os candidatos com deficiência devem conter a informação do que necessitam para realizar a prova, esta correto?

Cliente: Sim exatamente isso.

Portanto, em cima do dialogo mostrado vou apresentar os padrões GRASP, abaixo está um primeiro esboço do diagrama de classe, mas com o tempo esse diagrama deve mudar pois vamos trabalhar bastante ele até o fim desses post, vamos começar pelo Information Expert (Especialista da Informação).



Nome : Especialista da Informação (Expert)

Problema : Qual é o principio básico pelo qual atribuir responsabilidade a objetos?

Solução : Atribua responsabilidade a classe que tenha informação necessária para satisfazê-la.

Vantagens:

  • Fácil manutenção;
  • Facilita a criação dos teste unitários;
  • Código Limpo;
  • Reaproveitamento de funcionalidades;
  • Mais fácil de refatorar;

Para um objeto possuir determinada responsabilidade ele necessita de informação, sobre si próprio, sobre os objetos que estão relacionados com ele, sobre o mundo que esta em torno e assim por diante. No domínio apresentado sabemos que a sala tem uma capacidade de candidatos e se ela for ultrapassada o candidato naturalmente deve ir para outra sala disponível, pois bem, quem deve ser o responsável por isso?
Como a prova possui a informação das salas que estão vinculadas ela vai possuir a responsabilidade de adicionar o candidato, porem quem possui a informação sobre capacidade e de quantos candidatos estão alocados é a sala, pois bem ela vai ter a responsabilidade de nos informar se ainda a vagas disponíveis, e por ultimo como a lista de candidatos esta em sala a prova deve adicionar o candidato nela, por isso teremos mais um método adicionar Candidato em Sala. Abaixo está o diagrama de sequencia e o novo diagrama de Classes.

Diagramas Classes Original Expandido:
Diagrama de Sequencia:


Diagrama de Classes:


Pois bem, acho que nesse primeiro post aprendemos bastante sobre o padrão Expert, que no meu ponto de vista é o mais importante, no decorrer dos próximos post vou apresentar um por um dos padrões GRASP, até a próxima.