S05 - Atividade em Grupo: Design do Programa de Introspecção
Visão Geral
Reúna-se com seu grupo e prepare um design para a tarefa de programação desta semana.
Sobre "Orientações do Instrutor"
Lembre-se de que, durante toda a atividade, você receberá orientações de um instrutor. Primeiro, vocês devem responder às perguntas em grupo e, depois, consultar a seção Orientações do Instrutor para ter certeza de que estão no caminho certo.
Não deixe de expandir e ler cada seção da Orientações do Instrutor à medida que avança na atividade.
Agenda
Use o seguinte como agenda para sua reunião em grupo. Quem for designado para ser o estudante líder desta reunião deve ajudar a guiar o grupo através destas etapas e fazer as perguntas listadas aqui.
Antes da reunião: verifique o horário, o local e o estudante líder
Isso pode ser tão simples quanto publicar uma mensagem no seu canal do Microsoft Teams dizendo algo como: "Olá, pessoal, ainda estamos planejando nos encontrar amanhã às 19h, Horário de Brasília? Vamos usar o recurso de vídeo do Microsoft Teams de novo." Ou, se outra pessoa já publicou uma mensagem como essa, pode ser tão simples quanto "curtir" a mensagem dela.
Certifique-se de identificar quem será o estudante líder de cada semana. Por exemplo, "Emília, você ainda pode ser a estudante líder desta semana?"
Comece com uma oração
Discuta a atividade de aprendizagem de preparação
Reserve um tempo para falar sobre a atividade de aprendizagem da semana. Fale sobre quaisquer dificuldades que as pessoas tiveram para entender o material ou concluir a atividade.
- Qual parte da atividade de aprendizagem foi a mais difícil para você?
Reveja a especificação do programa
Consulte a Especificação do Programa de Introspecção. Em grupo, revisem os requisitos do programa e como ele deve funcionar.
- O que o programa faz?
- Quais são as entradas do usuário?
- Que saída ele produz?
- Como o programa termina?
Orientações do Instrutor
Olhar o menu do programa pode ser um bom começo.
Reserve um tempo para analisar cada atividade e discutir como ela deve funcionar. O que é necessário que o usuário digite? O que ele exibe para o usuário?
Determine as classes
O primeiro passo para projetar um programa como esse é pensar nas classes que você precisará. Ao pensar em classes, muitas vezes é útil considerar os substantivos fortes na descrição do programa.
- Quais são bons candidatos para classes neste programa?
- Quais são as principais responsabilidades de cada classe?
Orientações do Instrutor
Os principais componentes deste programa são as atividades. Reconhecendo que todas elas terão alguns comportamentos e atributos em comum, faz sentido ter uma classe base e depois classes derivadas para cada tipo específico de atividade, como:
Atividade(A classe base que contém todas as funcionalidades compartilhadas)AtividadeDeRespiracaoAtividadeDeReflexaoAtividadeDeListagem
Observe que todas essas classes passam no teste "é uma", porque uma atividade de Respiração é uma atividade, etc.
Você também pode ter uma classe para manipular o menu e a interação, ou pode optar por manipular isso
diretamente no seu método Main na classe Programa.
Avalie o Design
- Qual é o benefício de ter uma classe base
Atividadeem vez de apenas ter três classes de atividade específicas?
Defina os comportamentos das classes
Agora que você decidiu quais classes serão necessárias e suas responsabilidades, o próximo passo é definir os comportamentos dessas classes. Eles se tornarão métodos para as classes.
Passe por cada uma de suas classes e pergunte:
- Quais são os comportamentos que esta classe terá para cumprir suas responsabilidades? (Em outras palavras, o que essa classe deveria fazer?)
Orientações do Instrutor
O maior truque aqui é que se algum comportamento for usado por todas as atividades, você deve incluí-lo na classe base.
Por exemplo, cada um dos seguintes comportamentos são comuns e devem estar na classe base:
- Exibir a mensagem inicial
- Exibir a mensagem final
- Pausar enquanto mostra um indicador de progresso (spinner) por um certo número de segundos
- Pausar enquanto mostra um cronômetro de contagem regressiva por um certo número de segundos
Os seguintes comportamentos podem ser semelhantes no nome, mas diferentes na maneira como se comportam. Por isso, eles precisariam ser definidos separadamente para cada classe derivada: (Como observação, na próxima unidade você aprenderá uma maneira ainda mais inteligente de lidar com métodos como esse.)
- Executar a atividade
Por fim, há comportamentos para cada atividade que são completamente específicos daquela atividade. Por
exemplo, a AtividadeDeListagem também precisa fornecer comportamentos para:
- Receber uma pergunta aleatória
- Obter uma lista de respostas do usuário
A atividade de Reflexão precisa fornecer o seguinte:
- Obter uma mensagem de reflexão aleatória para exibir
- Obter uma pergunta aleatória sobre a mensagem
- Exibir a mensagem de reflexão
- Exibir perguntas sobre a mensagem e obter respostas
Além disso, à medida que você começa a implementar esses comportamentos, pode ser benéfico ter outras funções "auxiliares" que são usadas internamente para executar parte da tarefa desses comportamentos. Elas se tornam métodos privados da classe.
A conversão dessas ideias em nomes de métodos concisos nos dá o seguinte:
-
Atividade:ExibirMensagemInicial() : voidExibirMensagemFinal() : voidExibirProgresso(segundos : int) : voidExibirContagemRegressiva(segundos : int) : void
-
AtividadeDeRespiracaoExecutar() : void
-
AtividadeDeListagemExecutar() : voidObterPerguntaAleatoria() : stringObterListaDePerguntas() : List<string>
-
AtividadeDeReflexaoExecutar() : voidObterReflexaoAleatoria() : stringObterPerguntaAleatoria() : stringExibirReflexao() : voidExibirPerguntas() : void
Avalie o Design
- Observe que todas as três classes derivadas contêm uma função de execução. Por que isso não pode ser definido na classe base e herdado?
- Um método de classe derivada pode chamar um método de classe base? Por exemplo,
ExibirPerguntas()na classeAtividadeDeReflexaopode chamar o métodoExibirProgresso()? Por que sim ou por que não?
Defina os atributos das classes
Agora que você definiu as classes, suas responsabilidades e seus comportamentos, o próximo passo é determinar quais atributos as classes devem ter ou quais variáveis precisam armazenar.
Passe por cada uma de suas classes e pergunte:
- Quais atributos essa classe precisa para cumprir seus comportamentos? (Em outras palavras, quais variáveis esta classe deve armazenar?)
- Quais são os tipos de dados dessas variáveis membro?
Orientações do Instrutor
Mais uma vez, você precisa pensar nos atributos que são comuns a todas as classes derivadas e incluí-los na classe base. Então, cada classe derivada pode ter seus próprios atributos específicos também.
Os atributos da classe base devem incluir:
- O nome da atividade
- A descrição
- A duração em segundos
A Atividade de Respiração provavelmente não precisa de nenhum atributo, mas a atividade de listagem deve armazenar uma contagem do número de itens listados e uma lista de pergutas. Da mesma forma, a Atividade de Reflexão deve armazenar uma lista de perguntas e uma lista de reflexões para serem utilizadas.
A seguir são mostradas todas as variáveis membro:
-
Atividade:_nome : string_descricao : string_duracao : int
-
AtividadeDeRespiracao- Nenhuma necessária
-
AtividadeDeListagem_contador : int_perguntas : List<string>
-
AtividadeDeReflexao_reflexoes : List<string>_perguntas : List<string>
Avalie o Design
- Observe que duas das três classes de atividades armazenam uma lista de perguntas. Qual é o benefício potencial de defini-la nessas classes em vez de incluí-la na classe base e fazer com que a atividade que não precisa dela simplesmente a ignore e a deixe vazia?
Definir construtores
Agora que você definiu as classes, incluindo seus métodos e atributos, o próximo passo é pensar nos construtores que serão usados para criar novas instâncias dessas classes. Lembre-se de que você pode criar vários construtores com parâmetros diferentes para facilitar o trabalho com suas classes.
Lembre-se de que os construtores ajudam a configurar o estado inicial do objeto, então você deve considerar quais dados são necessários para esse estado inicial.
-
Quais construtores cada classe deve ter?
- Em outras palavras, quais parâmetros você deve passar ao criar um objeto desse tipo.
-
Que outro trabalho precisa ser feito para configurar esses objetos?
- Por exemplo, o construtor precisa executar código para executar tarefas de configuração, como criar listas, percorrer por variáveis, etc.
Orientações do Instrutor
A classe base precisará inicializar todas as suas variáveis membro. Você pode exigir que elas sejam passadas como parâmetros ou pode ter um construtor que defina algumas/todas como valores padrão para serem alterados posteriormente.
Então, o construtor da classe derivada pode ser capaz de definir bons valores na classe base, mesmo que você não passe parâmetros para ela. Por exemplo, um construtor que não tem parâmetros poderia ser assim:
public AtividadeDeReflexao()
{
_nome = "Reflexão";
_descricao = "Esta atividade ajudará você a refletir sobre momentos...";
_duracao = 50;
// Defina outros valores aqui que são exclusivos da Atividade de Reflexão
}
O código acima mostra a maneira mais simples e direta de fazer isso e presume que as variáveis são protegidas (protected) na classe base. Você também pode usar setters ou passá-los diretamente para o construtor da classe base.
Além de inicializar as variáveis, os construtores da AtividadeDeListagem e da
AtividadeDeReflexao precisam inicializar a lista de mensagens (e perguntas para a atividade de
Reflexão) e preenchê-las com valores.
Avalie o Design
- Qual é o benefício de exigir parâmetros para um construtor, em vez de simplesmente usar o construtor sem argumentos e deixar que as pessoas usem setters mais tarde para definir os valores?
Revise o design
Reserve um tempo para revisar seu design final.
- Há alguma classe, método ou variável que você não entende?
Orientações do Instrutor
A seguir está um diagrama de classe final para cada uma das classes que você pode usar como um guia enquanto escreve seu código.
Conclusão
Neste ponto, você tem o design das classes que precisará para este projeto. Se o seu design não estiver "perfeito" ou precisar mudar quando você começar a trabalhar no projeto, tudo bem! À medida que você aprender mais detalhes, naturalmente precisará ajustar seu planejamento. É por isso que os princípios da programação com classes são tão valiosos. Eles permitem que seu programa mude facilmente.
No final da sua reunião:
- Determine quem será o estudante líder na próxima reunião.
Após a reunião: inicie o código
Após a atividade em grupo, cada pessoa precisa concluir individualmente os seguintes passos:
-
Abrir o projeto no VS Code. Criar novos arquivos que contenham os protótipos ou código vazio para todas as classes, variáveis membro e funções em seu design.
- Neste ponto, o corpo dos métodos pode estar vazio, exceto as instruções de retorno necessárias.
- Cada classe deve estar em seu próprio arquivo e o nome do arquivo deve corresponder ao nome da classe.
- Certificar-se de que seu programa possa ser compilado sem erros.
- Confirmar (commit) e enviar (push) seu código para seu repositório no GitHub.
Envio
Assim como fez anteriormente, após concluir esta atividade retorne ao Canvas para responder a dois questionários associados a ela:
- S05 - Atividade em Grupo: Design do Programa de Introspecção
- S05 - Atividade em Grupo: Relatório da Participação