Questão de Engenharia de Software — Padrões de Projeto (Engenharia de Software) — CESGRANRIO 2024
- Código
- cg057919
- Banca
- CESGRANRIO
- Órgão
- IPEA
- Ano
- 2024
- Cargo
- TPP ( )
- ASingleton
- BAdapter
- CStrategy
- DFactory Method
- ETemplate Method
GabaritoE — Template Method
Gabarito: letra E. O código apresentado define um esqueleto de algoritmo na classe abstrata Checklist (o método check() que chama step01(), step02(), step03() e step04()), deixando que as subclasses implementem um dos passos (o step04() abstrato). Essa é a essência do Template Method, que permite variar partes de um algoritmo sem alterar sua estrutura geral.
O Template Method é um padrão de projeto comportamental que define o esqueleto de um algoritmo em uma operação, postergando alguns passos para as subclasses. Ele permite que subclasses redefinam certos passos de um algoritmo sem mudar a estrutura do algoritmo em si. No exemplo, o método check() é o "template" — ele define a sequência fixa de etapas (step01 → step02 → step03 → step04), mas delega a implementação do step04() para as subclasses Turboelice e Turbofan. Isso garante que o fluxo geral do checklist permaneça o mesmo, enquanto o comportamento específico do último passo varia conforme o tipo de propulsor.
A principal característica que identifica o Template Method é a presença de um método concreto que orquestra a chamada de outros métodos, sendo pelo menos um deles abstrato. O método concreto (check()) define a ordem fixa de execução, e o método abstrato (step04()) é o ponto de variação que as subclasses implementam. Esse padrão promove a reutilização de código ao centralizar a lógica comum na classe base, evitando duplicação nas subclasses.
Na prática, o padrão funciona assim: a classe abstrata define o algoritmo completo, mas marca alguns passos como abstratos ou "hooks" (ganchos) que podem ser sobrescritos. As subclasses então fornecem implementações específicas para esses passos, sem precisar reescrever o algoritmo inteiro. No caso do checklist, se amanhã a empresa criar um modelo com propulsor elétrico, bastará criar uma nova subclasse Eletrico extends Checklist e implementar o step04() — o método check() já está pronto e funcionará automaticamente para o novo modelo, sem qualquer alteração no código existente. Isso atende exatamente ao requisito de "design flexível que dê suporte a outros modelos sem alterações no código existente".
A pegadinha desta questão está em confundir o Template Method com o Strategy. Ambos são padrões comportamentais, mas diferem fundamentalmente: no Template Method, a variação ocorre por herança (subclasses sobrescrevem métodos da classe base), enquanto no Strategy a variação ocorre por composição (o contexto delega o comportamento a um objeto separado). No código, a classe Turboelice herda de Checklist e sobrescreve o step04() — não há nenhum objeto de estratégia sendo injetado. Essa distinção é o critério decisivo para separar as alternativas.
O Singleton garante que uma classe tenha apenas uma instância e fornece um ponto global de acesso a ela. No código, não há nenhum controle de instanciação — a classe Checklist é abstrata e pode ter múltiplas instâncias (Turboelice, Turbofan, etc.). O padrão Singleton não tem relação com a definição de um esqueleto de algoritmo.
O Adapter converte a interface de uma classe em outra interface que o cliente espera, permitindo que classes com interfaces incompatíveis trabalhem juntas. No código, não há conversão de interfaces nem integração de classes incompatíveis — apenas uma classe abstrata com um método abstrato que subclasses implementam. O Adapter é um padrão estrutural, enquanto o problema aqui é comportamental.
O Strategy define uma família de algoritmos, encapsula cada um deles e os torna intercambiáveis, permitindo que o algoritmo varie independentemente dos clientes que o utilizam. A diferença crucial é que o Strategy usa composição (o contexto recebe um objeto de estratégia), enquanto o código apresentado usa herança (a subclasse Turboelice estende Checklist e sobrescreve o método). No Strategy, o algoritmo é delegado a um objeto separado; aqui, o algoritmo é definido na própria hierarquia de classes. Além disso, no Template Method o fluxo geral é fixo e apenas alguns passos variam, enquanto no Strategy o algoritmo inteiro pode ser trocado.
O Factory Method define uma interface para criar um objeto, mas permite que as subclasses decidam qual classe instanciar. Ele lida com a criação de objetos (padrão criacional), enquanto o problema apresentado trata da definição de um algoritmo (padrão comportamental). No código, não há nenhum método de fábrica que cria objetos — o check() executa etapas, não cria instâncias. A criação de Turboelice no trecho Checklist c = new Turboelice() é apenas uma instanciação comum, não um Factory Method.
O Template Method define o esqueleto de um algoritmo em um método, postergando alguns passos para as subclasses. Exatamente o que o código faz: o método check() define a sequência fixa step01() → step02() → step03() → step04(), e o step04() é declarado abstrato para que cada subclasse (Turboelice, Turbofan) implemente conforme o tipo de propulsor. Isso permite adicionar novos modelos sem alterar o código existente — basta criar uma nova subclasse e implementar o step04(). O padrão é identificado pela combinação de um método concreto que orquestra a execução e um método abstrato que representa o ponto de variação.
A banca explora a confusão entre Template Method e Strategy. A pista decisiva é a herança: a classe Turboelice estende Checklist e sobrescreve o step04(). Se fosse Strategy, haveria um objeto de estratégia sendo injetado no construtor ou por um setter, e a variação seria por composição. Quando a variação vem de uma subclasse que sobrescreve um método abstrato dentro de um algoritmo já definido, é Template Method — não Strategy.
Para diferenciar na prova, pergunte-se: "como a variação é implementada?" Se for por herança (subclasse sobrescreve método abstrato dentro de um método concreto que define a sequência) → Template Method. Se for por composição (objeto de estratégia injetado e chamado pelo contexto) → Strategy. Essa pergunta elimina a dúvida em segundos.
Gabarito: letra E
Link permanente: /questoes/cg057919