Aula 4 — Programação Orientada a Objetos
2026-08-30
Até aqui: o objeto protegido (encapsulamento) e bem-comportado (Demeter).
O problema que sobra: um objeto pode ser tudo isso e ainda fazer coisas demais.
Roteiro: Classe Deus → SRP → o lado sombrio do SRP → tipos de associação → delegação.
Pedido: Cinco Responsabilidades, Uma ClasseMudar imposto, banco ou layout do recibo — em todos os casos, mexe-se em Pedido.
4 problemas: fragilidade, acoplamento com infraestrutura, difícil reuso, carga cognitiva alta.
Caixa só com chaves de fenda = alta coesão. Caixa com sanduíche + sapato + controle remoto = baixa coesão.
Ligar a TV exigindo abrir a geladeira primeiro = alto acoplamento — dois sistemas amarrados sem necessidade.
O santo graal: alta coesão + baixo acoplamento.
“A classe Pedido calcula o total E processa o pagamento E notifica o cliente.” → responsabilidades demais.
Ganhos: testabilidade (mocks), reuso, manutenibilidade.
Por que testar Pedido.finalizar() sem Injeção de Dependência exigiria cobrar um cartão de crédito de verdade?
Escreva sua resposta e compare com um colega antes de avançar (2 min). Para ajudar, julgue V ou F nos 4 itens abaixo — a questão só conta se acertar todos:
Pedido exigiria disparar um e-mail real ou cobrar um cartão de verdade.Pagavel real é uma violação do princípio de Injeção de Dependência.Dica
Pedido exigiria disparar um e-mail real ou cobrar um cartão de verdade — é exatamente o problema resolvido pela DI.Pagavel real é uma violação do princípio de Injeção de Dependência — usar um Mock é a aplicação correta de DI, não uma violação.Voltando à pergunta: sem DI, Pedido cria suas próprias dependências concretas internamente (new CartaoDeCredito(...), new ServicoEmail(...)), então qualquer teste do método aciona o código real de pagamento e envio; com DI, o teste injeta mocks e isola só a lógica de orquestração.
Dois atores, uma classe → mudança de layout do RH força re-testar a folha de pagamento.
Interseção de uso vazia = duas classes disfarçadas de uma (RepositorioUsuario + AuditoriaAcesso).
Fragmentação excessiva: uma regra de negócio exige tocar em 15 classes minúsculas.
Correto: Conta gerencia o próprio saldo (debitar()/creditar()) — SRP não é fragmentar tudo.
Vínculo mais fraco — como usar a caneta do balcão e devolver.
Domínio decide: dados de cartão devem sumir com a conta → Composição, não Agregação.
Por que a escolha entre Agregação e Composição para Cliente/Cartao depende de uma decisão de negócio, e não só de como o código é escrito?
Escreva sua resposta e compare com um colega antes de avançar (2 min). Para ajudar, julgue V ou F nos 4 itens abaixo — a questão só conta se acertar todos:
Dica
Cliente mostra exatamente isso.Voltando à pergunta: a declaração private Cartao cartao é idêntica sintaticamente nos dois casos — o que decide é a regra de domínio sobre o que deve acontecer ao cartão quando a conta é excluída; a mesma linha de código pode ser Agregação ou Composição dependendo dessa regra de negócio.
joao.pagar(500.0); — o chamador nem sabe que Cartao existe.
Associação (ter) + Delegação (usar) = a composição fica tão poderosa quanto a herança, mais flexível.
joao.pagar(500.0) esconde a existência de Cartao de quem chama. Isso é o mesmo mecanismo da Lei de Demeter (Aula 3) ou algo diferente?
Escreva sua resposta e compare com um colega antes de avançar (2 min). Para ajudar, julgue V ou F nos 4 itens abaixo — a questão só conta se acertar todos:
joao.getCartao().processar(500.0) respeita a Lei de Demeter, pois Cartao é um atributo de Cliente.joao.pagar(500.0) é um exemplo de “Tell”: o chamador diz o que quer, sem saber como é feito.pagar() desconhece completamente a existência de Cartao.Cartao sem afetar quem chama pagar().Dica
joao.getCartao().processar(500.0) respeita a Lei de Demeter, pois Cartao é um atributo de Cliente — Cartao ser atributo de Cliente não autoriza um objeto externo a navegar até ele; isso é o “naufrágio de código”.joao.pagar(500.0) é um exemplo de “Tell”: o chamador diz o que quer, sem saber como é feito — é a definição de “Tell” nesta aula.pagar() desconhece completamente a existência de Cartao — é o ganho central da delegação.Cartao sem afetar quem chama pagar() — é a síntese de Associação + Delegação apresentada nesta seção.Voltando à pergunta: é o mesmo mecanismo — a delegação em cadeia dentro de pagar() respeita a Lei de Demeter porque Cliente só fala com seu próprio Cartao (um “amigo” direto), e é exatamente essa delegação que impede o chamador externo de navegar até Cartao e violar a lei.
Próxima aula: interfaces como contrato formal, e testes automatizados com JUnit.
UNICAMP — Instituto de Computação