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 umaShape
classe 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
Shape
classe: -
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 separadaRectangleBlack
RectangleGreen
RectangleRed
. Dito e feito: vamos criar uma Color
interface com três implementações: BlackColor
, GreenColor
e 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
Color
campo àShape
classe. 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
color
variável emShape
implementações. Isso significa que as formas agora podem usar a funcionalidade daColor
interface. -
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 color
campo é 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:
- Abstração é a
Shape
classe - RefinedAbstraction são as classes
Triangle
eRectangle
- Implementador é a
Color
interface - ConcreteImplementor é o
BlackColor
,GreenColor
eRedColor
as classes.
Shape
classe é uma abstração — um mecanismo para gerenciar o preenchimento de formas com várias cores, que delega para a Color
interface (Implementor). As classes Triangle
e Rectangle
são classes concretas que utilizam o mecanismo disponibilizado pela Shape
classe. BlackColor
, GreenColor
e RedColor
sã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 color
campo).
- 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