Módulo 01 — Exercícios
Os exercícios a seguir são baseados exclusivamente no conteúdo do material deste módulo. Eles foram elaborados para que você coloque em prática o que estudou: configuração do ambiente, fundamentos do Flutter, null safety em Dart e controle de versão com Git. Não existe um único caminho correto para resolver cada exercício — o que importa é que você entenda o raciocínio por trás de cada decisão que tomar.
Leia cada enunciado com atenção antes de começar. Se encontrar dificuldade, releia a seção correspondente no material antes de buscar ajuda externa.
Exercício 1 — Nível Básico
Explorando o Ambiente e o Primeiro Projeto Flutter
Contexto
Você acabou de configurar o ambiente de desenvolvimento e criou o seu primeiro projeto Flutter usando o comando flutter create. O projeto gerado contém o aplicativo de contador padrão, que você viu detalhadamente no material.
Agora, antes de começar a trabalhar no Projeto Integrador, é importante que você compreenda com precisão o que esse projeto padrão já contém — tanto nos arquivos quanto na estrutura de diretórios — e que você seja capaz de realizar mudanças simples e verificar seu efeito imediato.
Parte A — Análise do projeto padrão
Crie um novo projeto Flutter com o nome explorador_flutter e abra-o no VS Code. Examine o arquivo pubspec.yaml e responda, por escrito em um arquivo docs/analise.md dentro do próprio projeto:
Qual é a versão declarada do projeto e o que significam os dois números separados pelo sinal de +? Quais são as dependências de produção listadas e para que serve cada uma? Qual é a diferença, no contexto do pubspec.yaml, entre dependencies e dev_dependencies? Por que flutter_lints está em dev_dependencies e não em dependencies?
Parte B — Modificação com hot reload
Sem fechar o emulador com o aplicativo em execução, realize as três modificações a seguir, uma de cada vez, salvando o arquivo após cada alteração e observando o efeito no emulador:
Primeira modificação: altere a cor de fundo do ColorScheme (parâmetro seedColor) para Colors.deepPurple e registre o que mudou na interface. Segunda modificação: altere o texto do floatingActionButton (o parâmetro tooltip) para 'Adicionar um ao contador' e verifique onde essa alteração é visível na interface. Terceira modificação: dentro da lista children do Column, adicione um novo widget Text com o conteúdo 'Aplicativo de demonstração' imediatamente antes do texto existente, e registre o resultado.
Em seu arquivo docs/analise.md, descreva qual modificação exigiu apenas hot reload e qual exigiu hot restart — se alguma exigiu — e explique por quê.
Parte C — Git
Inicialize um repositório Git dentro do projeto explorador_flutter, configure o .gitignore adequado para projetos Flutter e crie dois commits seguindo a convenção Conventional Commits:
O primeiro commit deve incluir apenas os arquivos da estrutura inicial do projeto gerado pelo Flutter, com uma mensagem no formato feat:. O segundo commit deve incluir as modificações feitas na Parte B e o arquivo docs/analise.md, com uma mensagem no formato docs: que descreva claramente o que foi incluído.
Ao finalizar, execute git log --oneline e verifique se as mensagens dos dois commits são claras e descritivas.
Este exercício não tem respostas fornecidas. O objetivo é que você explore o projeto, formule suas próprias respostas com base no que leu no material e registre suas observações. Na aula presencial, você vai comparar suas conclusões com as de outros estudantes.
Exercício 2 — Nível Intermediário
Projetando a Estrutura Inicial do Seu Aplicativo
Contexto
O Projeto Integrador começa com a definição de uma proposta e com a criação da estrutura inicial do repositório. Neste exercício, você vai fazer exatamente isso de forma individual, antes de discutir com sua equipe na aula: vai propor um aplicativo, criar a estrutura de pastas seguindo os princípios Feature-First e Arquitetura Hexagonal apresentados no material, e raciocinar sobre como os princípios do null safety se aplicam aos modelos de domínio que você imagina para o aplicativo.
Parte A — Proposta individual do aplicativo
Imagine um aplicativo móvel que você gostaria de construir e que se enquadra nos critérios do Projeto Integrador: múltiplas telas, formulários com validação, persistência de dados, comunicação com backend, autenticação, notificações push e ao menos um recurso nativo do dispositivo.
Escreva uma proposta de uma página em docs/proposta_individual.md contendo: o nome do aplicativo, o problema concreto que ele resolve, o público-alvo (seja específico — não escreva “usuários em geral”), uma lista de cinco a oito funcionalidades principais, e qual recurso nativo do dispositivo seria utilizado e por quê ele agrega valor ao propósito do aplicativo.
Parte B — Estrutura de pastas
Crie um novo projeto Flutter com o nome meu_app_proposta e organize o diretório lib/ seguindo a estrutura Feature-First com Arquitetura Hexagonal apresentada no material. Você deve criar, manualmente, as pastas e arquivos .gitkeep (arquivos vazios que permitem ao Git versionar pastas vazias) correspondentes às seguintes features do seu aplicativo proposto: pelo menos duas features específicas da sua proposta, além da pasta core/ com suas subpastas (theme/, widgets/, utils/, di/).
Para cada feature que você criar, deve existir a estrutura de três camadas: domain/, data/ e presentation/. Dentro de cada camada, crie ao menos uma subpasta representativa (por exemplo, domain/models/, data/repositories/, presentation/screens/).
Parte C — Raciocínio sobre null safety
Com base na proposta que você descreveu na Parte A, identifique dois modelos de domínio que o aplicativo precisaria. Para cada modelo, escreva em docs/proposta_individual.md a declaração da classe Dart correspondente — não precisa implementar os métodos, apenas os atributos com seus tipos —, justificando para cada atributo se ele deve ser declarado como tipo não-nulável ou nulável (com ?), e por quê essa escolha é a mais correta para o domínio que você está modelando.
Por exemplo: se o seu aplicativo tem um modelo EventoCalendario, um atributo titulo provavelmente deve ser String (não-nulável, pois todo evento precisa ter título), enquanto um atributo descricao pode ser String? (nulável, pois a descrição é opcional).
Parte D — Commit final
Commite toda a estrutura criada em um único commit com uma mensagem no formato feat: que descreva adequadamente o que foi feito. Certifique-se de que o .gitignore está correto e de que nenhum arquivo gerado automaticamente pelo Flutter (como o diretório build/) foi incluído no commit.
A qualidade das justificativas na Parte C é mais importante do que a quantidade de atributos. Prefira dois modelos bem pensados com justificativas claras a cinco modelos com justificativas superficiais. O null safety é um recurso que você vai usar em absolutamente todo o código Dart que escrever ao longo do semestre — dominar o raciocínio por trás dele desde agora faz diferença.
Exercício 3 — Nível Desafiador
Análise Arquitetural Comparativa e Decisão Técnica Fundamentada
Contexto
Este exercício não envolve escrita de código. Ele exige que você aplique os conceitos arquiteturais e comparativos apresentados no material para analisar uma situação realista e tomar — e defender — uma decisão técnica. Esse tipo de raciocínio é exatamente o que diferencia um desenvolvedor que executa tarefas de um desenvolvedor que projeta soluções.
Cenário
Uma empresa brasileira de médio porte está desenvolvendo um sistema de gestão de pedidos para sua rede de restaurantes. O sistema precisa de um aplicativo mobile que os garçons usarão para anotar e acompanhar pedidos em tempo real, diretamente na mesa do cliente. A empresa já tem um time de dois desenvolvedores backend experientes em Node.js e um designer de interface.
O diretor de tecnologia apresentou três opções para o time avaliar antes de tomar a decisão de plataforma:
A Opção 1 é desenvolver aplicativos nativos separados: um em Kotlin para Android e um em Swift para iOS. A empresa fornecerá tablets Android para os garçons, mas o dono do restaurante quer ter a flexibilidade de migrar para iPads no futuro, caso encontre um bom preço.
A Opção 2 é usar Ionic, com um desenvolvedor frontend que a empresa já tem disponível e que conhece bem Angular e TypeScript. A curva de aprendizagem seria mínima e o time poderia começar a entregar funcionalidades na primeira semana.
A Opção 3 é usar Flutter, mas nenhum membro atual do time conhece Dart. O time teria de investir algumas semanas em aprendizado antes de começar a produzir funcionalidades de valor.
O aplicativo precisa: funcionar offline quando o Wi-Fi do restaurante falhar (com sincronização automática ao reconectar), exibir animações fluidas ao confirmar pedidos (para dar feedback visual ao garçom), acessar a câmera do tablet para fotografar pratos com defeito ou avarias, e ter desempenho consistente mesmo em tablets mais baratos com hardware limitado.
O que você deve fazer
Elabore um documento de análise técnica em docs/analise_plataforma.md que responda às seguintes questões, baseando-se exclusivamente nos conceitos apresentados no material do módulo:
Primeiro, para cada uma das três opções, identifique pelo menos dois pontos fortes e dois pontos fracos no contexto específico deste projeto — não em termos gerais, mas considerando as restrições e requisitos apresentados no cenário.
Segundo, explique como o modelo de renderização de cada opção (nativo, WebView ou motor próprio) influencia diretamente o requisito de animações fluidas em tablets com hardware limitado. Baseie sua argumentação nas diferenças arquiteturais apresentadas no material.
Terceiro, o requisito de funcionamento offline envolve persistência local e sincronização com o backend. Qual das três opções oferece, em termos arquiteturais, a trajetória mais natural para implementar esse requisito ao longo do desenvolvimento? Por quê?
Quarto, considerando que o time não conhece Dart e que o prazo do projeto é de seis meses, a Opção 3 ainda seria viável? Construa um argumento técnico — não apenas comercial — que justifique ou refute a viabilidade do Flutter nesse contexto, usando os conceitos de curva de aprendizagem, produtividade durante o desenvolvimento (hot reload, DevTools) e consistência visual entre plataformas discutidos no material.
Quinto, apresente sua recomendação final, escolhendo uma das três opções. A recomendação deve ser sustentada pelos argumentos desenvolvidos nas questões anteriores e deve reconhecer explicitamente os trade-offs que a opção escolhida implica.
Critério de qualidade
Seu documento será avaliado pela coerência do raciocínio e pela precisão com que os conceitos do material são aplicados ao cenário — não pela opção que você escolheu. Não existe resposta certa; existe argumento bem fundamentado ou mal fundamentado.
Este exercício exige que você leia o cenário com atenção e resista à tentação de responder de forma genérica. Cada argumento que você apresentar deve estar ancorado em uma característica técnica específica discutida no material: o modelo de renderização do Flutter, a diferença entre compilação AOT e JIT, o comportamento do hot reload, a comparação entre abordagens nativas, híbridas e multiplataforma moderna. Argumentos vagos como “o Flutter é mais moderno” ou “o Ionic é mais fácil” não são suficientes.