Qual é o padrão da ponte?
O padrão de ponte é um padrão de projeto estrutural. Em outras palavras, sua principal tarefa é criar uma estrutura completa de classes e objetos. Uma ponte faz isso dividindo uma ou mais classes em hierarquias separadas: abstração e implementação . Uma mudança na funcionalidade em uma hierarquia não acarreta uma mudança na outra. Tudo bem, mas essa definição é muito ampla e não responde à pergunta mais importante: "Qual é o padrão da ponte?" Acho que será mais fácil para você entender sua aplicação prática. Então, vamos criar um cenário clássico para o padrão de ponte. Temos umaShapeclasse abstrata, que representa uma figura geométrica genérica:
-
Shape.java
public abstract class Shape { public abstract void draw(); }Quando decidirmos adicionar formas como triângulos e retângulos, faremos com que eles herdem a
Shapeclasse: -
Rectangle.java:
public class Rectangle extends Shape { @Override public void draw() { System.out.println("Drawing rectangle"); } } -
Triangle.java:
public class Triangle extends Shape { @Override public void draw() { System.out.println("Drawing triangle"); } }
draw()método dependerá dessa cor. Para ter diferentes implementações do draw()método, então precisamos criar uma classe para cada combinação forma-cor. Se tivermos três cores, precisaremos de seis classes: TriangleBlack, TriangleGreen, TriangleRed, e . Seis classes não é um problema tão grande. Mas! Se precisarmos adicionar uma nova forma ou cor, o número de classes aumentará exponencialmente. Como sair dessa situação? Armazenar cores em um campo e enumerar todas as opções usando instruções condicionais não é a melhor solução. Uma boa solução é mover a cor para uma interface separadaRectangleBlackRectangleGreenRectangleRed. Dito e feito: vamos criar uma Colorinterface com três implementações: BlackColor, GreenColore RedColor:
-
Color.java:
public interface Color { void fillColor(); } -
BlackColor.java:
public class BlackColor implements Color { @Override public void fillColor() { System.out.println("Filling in black color"); } } -
GreenColor.java
public class GreenColor implements Color { @Override public void fillColor() { System.out.println("Filling in green color"); } } -
RedColor.java
public class RedColor implements Color { @Override public void fillColor() { System.out.println("Filling in red color"); } }Agora adicionamos um
Colorcampo àShapeclasse. Obteremos seu valor no construtor. -
shape.java:
public abstract class Shape { protected Color color; public Shape(Color color) { this.color = color; } public abstract void draw(); }Usaremos a
colorvariável emShapeimplementações. Isso significa que as formas agora podem usar a funcionalidade daColorinterface. -
Retângulo.java
public class Rectangle extends Shape { public Rectangle(Color color) { super(color); } @Override public void draw() { System.out.println("Drawing rectangle"); color.fillColor(); } }
Color colorcampo é uma ponte que conecta duas hierarquias de classes separadas.
Como construir uma ponte: abstração e implementação
Vejamos um diagrama de classes que descreve o padrão de ponte:
Aqui você pode ver duas estruturas independentes que podem ser modificadas sem afetar a funcionalidade uma da outra. No nosso caso:
- Abstração é a
Shapeclasse - RefinedAbstraction são as classes
TriangleeRectangle - Implementador é a
Colorinterface - ConcreteImplementor é o
BlackColor,GreenColoreRedColoras classes.
Shapeclasse é uma abstração — um mecanismo para gerenciar o preenchimento de formas com várias cores, que delega para a Colorinterface (Implementor). As classes Trianglee Rectanglesão classes concretas que utilizam o mecanismo disponibilizado pela Shapeclasse. BlackColor, GreenColore RedColorsão implementações concretas na hierarquia de Implementação.
Onde usar o padrão de ponte
Um grande benefício de usar esse padrão é que você pode fazer alterações nas classes funcionais em uma hierarquia sem quebrar a lógica da outra. Além disso, essa abordagem ajuda a reduzir o acoplamento entre as classes. O principal requisito ao usar esse padrão é "siga as instruções" — não ignore nenhuma delas! Para isso, vamos descobrir as situações em que você definitivamente deve usar o padrão bridge:-
Se você precisar expandir o número de entidades com base em combinações de dois conceitos (por exemplo, formas e cores).
-
Se você deseja dividir uma classe grande que não atende ao princípio de responsabilidade única em classes menores com funcionalidade restrita.
-
Se for necessário fazer alterações na lógica de determinadas entidades enquanto o programa estiver em execução.
-
Se for necessário ocultar uma implementação dos clientes da classe ou biblioteca.
Prós e contras do padrão
Como outros padrões, uma ponte tem vantagens e desvantagens. Vantagens do padrão de ponte:- Melhora a escalabilidade do código — você pode adicionar funcionalidade sem medo de quebrar algo em outra parte do programa.
- Reduz o número de subclasses quando o número de entidades seria baseado em combinações de dois conceitos (por exemplo, formas e cores).
- Torna possível trabalhar separadamente em duas hierarquias distintas — Abstração e Implementação. Dois desenvolvedores diferentes podem fazer alterações sem se aprofundar nos detalhes do código um do outro.
- Reduz o acoplamento entre as classes — o único lugar onde as duas classes são acopladas é a ponte (ou seja, o
Color colorcampo).
- Dependendo da situação específica e da estrutura geral de um projeto, isso pode afetar negativamente o desempenho de um programa (por exemplo, se você precisar inicializar mais objetos).
- Isso torna o código menos legível devido à necessidade de alternar entre as duas classes.
GO TO FULL VERSION