Atividade 08: Bridge
Exercício 1: Aplicações
Seção intitulada “Exercício 1: Aplicações”Para cada cenário abaixo, indique se o padrão Bridge é apropriado ou não e justifique em 2–3 frases.
- Um sistema de notificações que precisa variar em duas dimensões: o tipo de conteúdo (informativo, alerta, promoção) e o canal de envio (SMS, e-mail, push). Sem o padrão, cada combinação viraria uma classe nova.
- Uma aplicação multiplataforma que precisa rodar a mesma lógica sobre APIs de sistema operacional diferentes (Windows, Linux, macOS), sem multiplicar as classes da interface.
- Um módulo de persistência em que a mesma lógica de repositório precisa funcionar com MySQL ou PostgreSQL, podendo até trocar de banco em tempo de execução.
- Um framework de testes que precisa executar testes em diferentes ambientes com diferentes configurações de hardware.
Para cada item, responda:
- “Faz sentido usar Bridge” ou “Não faz sentido usar Bridge”.
- Explique rapidamente o porquê (duas dimensões ortogonais, explosão de subclasses, plataforma, overengineering, etc.).
Exercício 2: Analogia
Seção intitulada “Exercício 2: Analogia”Crie uma analogia própria para explicar o padrão Bridge para alguém que não é da área de TI.
Na aula, usamos o carro e o motor: dirigir um carro não depende do motor (combustão ou elétrico), o carro delega a força ao motor, e carros e motores evoluem independentes. Agora crie uma outra analogia.
Descreva uma situação do mundo real em que:
- existam duas “famílias” que precisam ser combinadas de muitas formas,
- combinar tudo de uma vez por “duplicação” seja inviável,
- e cada família possa evoluir separadamente, com as combinações feitas na hora (composição).
Exercício 3: Anti-pattern
Seção intitulada “Exercício 3: Anti-pattern”Considere o código Java abaixo, usado em um editor gráfico:
public abstract class Forma { public abstract void desenhar();}
public class CirculoVermelho extends Forma { @Override public void desenhar() { System.out.println("Desenhando círculo vermelho"); // lógica de desenhar círculo + lógica da cor vermelho }}
public class CirculoAzul extends Forma { @Override public void desenhar() { System.out.println("Desenhando círculo azul"); // mesma lógica de círculo, cor azul }}
public class QuadradoVermelho extends Forma { @Override public void desenhar() { System.out.println("Desenhando quadrado vermelho"); }}
public class QuadradoAzul extends Forma { @Override public void desenhar() { System.out.println("Desenhando quadrado azul"); }}Responda:
- Por que essa hierarquia (uma classe por combinação de forma × cor) é um problema de design?
- O que acontece ao adicionar uma nova forma (ex.:
Triangulo) ou uma nova cor (ex.:Verde)? Quantas classes existiriam paraNformas eMcores? - Proponha uma solução usando o padrão Bridge, explicando em linhas gerais: as duas hierarquias (forma e cor), como a
Formapassaria a referenciar umaCore por que cada lado passaria a evoluir de forma independente.
Exercício 4: Exemplo real
Seção intitulada “Exercício 4: Exemplo real”Acesse os seguintes arquivos em um projeto open source:
- Projeto: OpenJFX (a biblioteca JavaFX, da família OpenJDK)
- Arquivos:
O JavaFX separa a lógica de um controle da sua aparência usando o padrão Bridge: o Control (a abstração) guarda uma referência a uma Skin (a implementação) e delega a ela a renderização. Cada controle tem a sua própria skin (por exemplo, o Button usa um ButtonSkin). Quando o Control precisa da skin e ela ainda não existe, ele chama createDefaultSkin(). É a mesma estrutura do ControleRemoto que delega a um Dispositivo vista em aula.
Responda:
- Quais são as duas hierarquias do padrão nesse exemplo? Onde está a abstração e onde está a implementação?
- Em
Button.java, localize o métodocreateDefaultSkin(). O que ele retorna? Por que oButtondelega a própria aparência a umButtonSkinem vez de embutir todo o desenho no próprio controle?
Exercício 5: Implementação
Seção intitulada “Exercício 5: Implementação”Imagine que você foi contratado para criar o sistema de veículos de uma concessionária.
O sistema precisa montar veículos combinando dois conceitos que evoluem de forma independente:
- o tipo de veículo (por exemplo,
SedaneSUV), e - o tipo de motor (por exemplo,
MotorGasolinaeMotorEletrico).
Sem o padrão, cada combinação viraria uma classe nova (SedanGasolina, SedanEletrico, SuvGasolina…).
Sua missão
Seção intitulada “Sua missão”Implemente, em Java, um sistema que separe as duas hierarquias, usando o padrão Bridge.
- Crie a interface de implementação
Motor:- Métodos:
void ligar()evoid acelerar().
- Métodos:
- Crie as implementações concretas:
MotorGasolinaeMotorEletrico, cada um imprimindo mensagens que identificam o motor.
- Crie a classe abstrata
Veiculo(a abstração):- Um campo
protected Motor motor(recebido no construtor). - Métodos
void dirigir()(liga o motor) evoid acelerar()(delega ao motor).
- Um campo
- Crie as abstrações refinadas:
SedaneSuv, que estendemVeiculo(cada uma pode imprimir o próprio tipo ao dirigir).
- Crie uma classe de teste, por exemplo
Main, que:- Monte as quatro combinações (
SedancomMotorGasolina,SedancomMotorEletrico,SuvcomMotorGasolina,SuvcomMotorEletrico) e as execute. - Mostre que o mesmo veículo funciona com motores diferentes e que o mesmo motor funciona em veículos diferentes.
- Explique, em um comentário ou README, como adicionar um novo motor (ex.:
MotorHibrido) ou um novo veículo (ex.:Picape) exigiria apenas uma nova classe, sem alterar o outro lado.
- Monte as quatro combinações (