Oi pessoal! Como estão os estudos? Até agora não recebi dúvidas a respeito do conteúdo. De qualquer forma, gostaria de deixar algumas dicas para a prova com base no que vi em alguns dos trabalhos entregues (e com base no que costuma ser pedido numa primeira prova de ES):
1) OO + Java
Estudem os conceitos-chave de orientação a objetos, tais como abstração, encapsulamento e polimorfismo. Saibam aplicar encapsulamento e polimorfismo usando classes abstratas e interfaces. A primeira tarefa que o Gerosa passou (implementação da folha de pagamento) é extremamente importante. Notei que alguns fizeram implementações muito boas e/ou deram peer-reviews muito bons! Outros tiveram mais dificuldade. Algumas coisas importantes:
- Se uma classe existe no modelo, ela precisa existir no seu código. Para qualquer sistema, salvo raras exceções, uma boa prática é sempre alocar cada classe para uma unidade de compilação separada (em outras palavras, cada classe num arquivo .java separado)
- Os relacionamentos estruturais presentes numa diagrama de classe precisam se materializar no seu código. Para tal, é importante saber a sintaxe e a semântica dos vários tipos de relacionamento UML (minimamente: associações, heranças e implementação de interface).
- Um conceito-chave em orientação a objetos, é a troca de mensagens entre objetos. Os objetos tem atributos (estado) e comportamento. Num jogo de tabuleiro, seria perfeitamente comum encontrar um método "rolar" na classe "Dado". Você pede para um dado rolar e ele "rola sozinho". Analogamente, no exercício de vocês, havia a operação "calculaSalario" na classe Funcionario. É assim que o paradigma de objetos funciona.
- Fiquem atentos às assinaturas das operações (nome, parâmetros e tipo de retorno) definidas no modelo. Elas devem ser respeitadas na hora de implementar o modelo.
- Eu não sei o que vocês combinaram com o Gerosa, mas é provável que vocês precisem ter destreza suficiente com Java para eventualmente poder implementar modelos UML
2) Sobre requisitos e casos de uso
Essa é uma área bastante particular da Engenharia de Software. Talvez seja uma das partes mais "socio-técnicas". Vocês precisam saber escrever bons casos de uso e boas histórias. Algumas coisas importantes:
- Você precisa saber dizer o que é um requisito e saber diferenciar requisitos funcionais e não-funcionais.
- Vocês precisam saber interpretar e elaborar modelos de caso de uso. Um bom resumo da parte UML da coisa está abaixo.

Na tarefa, vi que vários cometeram erros ao elaborar o diagrama:
Em primeiro lugar, há basicamente 4 tipos possíveis de relacionamentos em um diagrama de casos de uso: herança entre atores, aquele que liga o ator ao caso de uso e outros dois que definem possíveis relações entre casos de uso ("include" e "extend"). Cada relacionamento possui uma semântica e uma sintaxe específica. Fiquem atentos a isso.
Muitos, muitos mesmo, esqueceram de definir a "system boundary". Os casos de uso devem ficar la dentro e os atores fora.
Alguns alunos mandaram a tarefa em um arquivo de texto puro. Embora eu entenda o lado geek de vocês, essa não é uma boa prática para esse curso. Por exemplo, quando vocês fazem isso, não é possível saber se vocês usaram a sintaxe correta para os tipos de relacionamento UML. Fazendo isso, vocês não treinam escrever e ler UML. Sempre usem uma ferramenta case, que pode ser tão leve (e.g., Astah ou alguma outra web-based) ou tão pesada quanto queiram (e.g., Rational Software Architect).
Outro erro comum: um ator NUNCA pode ser chamado de usuário. Todo ator que interage com o sistema, por definição, é um usuário (incluindo outros sistemas). Portanto, "usuário" é o pior nome possível que você pode dar para um ator. Um ator é uma entidade externa ao sistema e que tem um papel bem definido (bons nomes para atores, portanto, dependem de uma boa análise do domínio). Um ator sempre utiliza o sistema para alcançar uma meta ou objetivo.
- Dito tudo isso, o mais importante de um caso de uso é o texto e não o diagrama. O caso de uso em si é o texto.
- Não se esqueçam dos principais itens de um caso de uso: ator, descrição, pré-condições, pós-condições, fluxo principal e fluxos alternativos. Sigam o formato dos slides do Gerosa.
- Um erro comum no trabalho de vocês foi a inclusão de "passos tecnológicos". Estes devem sempre ser evitados.
- Seguir o check-list abaixo é a melhor recomendação que eu posso dar:
| Field | Question |
|---|---|
| Use Case Title | 1. Is it an active-verb goal phrase that names the goal of the primary actor? 2. Can the system deliver that goal? |
| Primary Actor | 8. Does he/she/it have behavior? 9. Does he/she/it have a goal against the SuD that is a service promise of the SuD? |
| Preconditions | 10. Are they mandatory, and can they be set in place by the SuD? 11. Is it true that they are never checked in the use case? |
| Main Success Scenario |
15. Does it have 3-9 steps? 16. Does it run from trigger to delivery of the success guarantee? 17. Does it permit the right variations in sequencing? |
| Each Step in Any Scenario |
18. Is it phrased as a goal that succeeds? 19. Does the process move distinctly forward after its successful completion? 20. Is it clear which actor is operating the goal--who is "kicking the ball"? 21. Is the intent of the actor clear? 22. Is the goal level of the step lower than the goal level of the overall use case? Is it, preferably, just a bit below the use case goal level? 23. Are you sure the step does not describe the user interface design of the system? 24. Is it clear what information is being passed in the step? 25. Does it "validate" as opposed to "check" a condition? |
| Extension Condition | 26. Can and must the system both detect and handle it? 27. Is it what the system actually needs? |
| Overall Use Case Content |
29. To the sponsors and users: "Is this what you want?" 30. To the sponsors and users: "Will you be able to tell, upon delivery, whether you got this?" 31. To the developers: "Can you implement this?" |
3) Sobre requisitos e user stories
User stories é uma forma alternativa de escrever casos de uso. É uma especificação de alto nível de um requisito. O formato tradicional é "Como um PAPEL, eu quero ALGO para BENEFÍCIO/META.
Note que a ideia de o usuário ter um Papel continua existindo em User Stories. Portanto, é errado escrever "Como um USUARIO, eu ...". Esse erro também foi comum no exercício de vocês.
- User stories geralmente são usadas no contexto de processos ágeis de desenvolvimento. É importante, portanto, listar a prioridade e a estimativa de esforço em cada história (cartão). Poucos fizeram isso.
- Em geral, é interessante listar confirmações ou testes de aceitação (isto é, o tipo de informação que encontraria no "verso" de um cartão). Nem todos fizeram isso.
- O mais importante sobre user stories é a sua ampla adoção na prática (principalmente no contexto de métodos ágeis de desenvolvimento). Vale a pena dar uma revisada na parte prática da coisa (uso de cartões, mapa de histórias, etc.)
4) Análise e Modelo Conceitual
Modelos conceituais são uma parte fundamental da atividade de "Análise" em Engenharia de Software. Conforme o Gerosa colocou, os passos comuns são: (i) identificação de substantivos, (ii) identificação de classes, atributos, operações e (iii) elaboração do diagrama de classes. Portanto, aqui há duas competências distintas e igualmente importantes: (a) saber identificar conceitos chave e o relacionamento entre eles e (b) escrever isso na forma de uma diagrama de classes UML. Dêem uma revisada nos slides do Gerosa (incluindo a parte de “padrões de análise”).
Alguns erros comuns que encontrei na atividade de vocês foram:
- Diagramas que não são UML. Algumas pessoas mandaram um diagrama de classes que não usa a sintaxe UML (em alguns casos, parece ser um diagrama entidade-relacionamento usado em BD). Novamente, é importante saber ler e escrever UML, porque assim todo mundo se entende. E não é frescura. Em um diagrama UML, há sintaxe específica para definir multiplicidade, visibilidade de operações (privada, protected, public, default), navegabilidade e etc.
- Mostrando coisa demais. Em um modelo conceitual, não é necessário mostrar operações das classes. Foquem nos atributos e os relacionamentos entre as classes. Não precisa mostrar a visibilidade dos atributos. Se mostrar, mostre sempre com - (private) ou # (protected, se for o caso).
- Poucas classes. “Pouco” significa algo em torno de 3 ou 4. Neste caso, a sua análise provavelmente está deficiente. Provavelmente faltou identificar outros elementos-chave (muitos dos quais estão, ou deveriam estar, nos casos de uso). Portanto, aqui, o problema não foi UML, mas sim a própria análise. Outra hipótese é que o seu sistema é simples demais.
- Poucas classes com muitos atributos. Novamente, “poucas classes” significa algo em torno de 3 ou 4. Nesse caso, as classes estão sobrecarregadas. Provavelmente é possível desmembrar algumas classes. Outro caso que encontrei foi o de relacionamentos “escondidos” na forma de atributos. Em um diagrama conceitual, os relacionamentos devem ser explicitados. A gente quer saber os atributos e operações de todas as classes do domínio.
- Classes tecnológicas. Em um modelo de domínio, deve-se evitar classes tecnológicas (e.g., XXXMapper, YYYController). Essas classes vem depois, na etapa de design. Você não vai ganhar muito mostrando classes tecnológicas para um stakeholder (salvo raríssimas exceções). O seu João da padaria não quer saber se você usou Hibernate, SQL ou JSF (ele nem sabe o que é isso).
- Classes com nome inadequado. Se você tem uma classe com nome Usuario, considere fortemente trocar esse nome pelo papel que este usuário desempenha no sistema (vide recomendação na definição dos atores do sistema em diagramas de casos de uso). Uma classe com nome Usuario agrega pouquíssimo valor. Esse erro foi bastante comum. Ainda, se você tem uma classe cujo nome é um verbo, então esse conceito deveria ser uma operação de uma classe e não uma classe (salvo raríssimas exceções).
- Pouca clareza nos relacionamentos. As vezes o propósito de um relacionamento num modelo de domínio pode não ser óbvio. Nesses casos, vale a pena incluir o “role name” na(s) extremidade(s) do relacionamento. Outras vezes vale a pena nomear o relacionamento (uma frase curta com uma setinha preta no meio do relacionamento de associação). A figura abaixo é um bom resumo (embora não inclua relacionamentos nomeados). Note que não existe uma classe chamada “User” e sim uma classe chamada “Customer”.

5) Design
- Saiba a diferença entre análise e design. Em resumo, análise é fazer a coisa certa e design é fazer certo a coisa.
- Revisem os princípios básicos de design, o que eles significam e como aplica-los. Lembrem-se sempre da relação entre eles e a manutenibilidade de um sistema.
- Uma boa forma de avaliar um design é ficar atento aos seus “maus cheiros”. Revisem os conceitos de “Rigidez”, “Fragilidade”, “Imobilidade”, “Viscosidade”, “Complexidade Desnecessária” e “Repetição Desnecessária”. Nos slides do Gerosa está bem resumido. Sugiro fortemente ler o artigo que ele colocou no PACA (http://www.objectmentor.com/resources/articles/Principles_and_Patterns.pdf), ao menos até a página 16.
- Disclaimer: Criar (e principalmente, manter) um bom design é bastante difícil. É um dos principais desafios da Engenharia de Software, pois exige diversas competências (muito conhecimento técnico, criatividade e até alguma arte). Vocês não vão se tornarem mestres em design depois de uma ou duas aulas de Engenharia de Software. Isso exige bastante prática e experiência. Portanto, se vocês aprenderem bem os princípios de design e como aplica-los em alguns cenários mais “straighforward”, já ficaremos (Gerosa e eu) contentes
E é isso! Boa sorte na prova!!!