Qual é o padrão Bridge?
O padrão Bridge é um padrão de projeto estrutural. Ou seja, sua principal tarefa é criar uma estrutura completa de classes e objetos. O Bridge resolve esse problema dividindo uma ou mais classes em hierarquias separadas – abstração e implementação . Uma alteração na funcionalidade de uma hierarquia não implica alterações em outra. Tudo parece claro, mas na verdade esta definição parece muito ampla e não responde à questão principal: “O que é o padrão Bridge?” Acho que isso será mais fácil para você descobrir na prática. Vamos modelar imediatamente um exemplo clássico para o padrão Bridge. Temos uma classe abstrataShape
que geralmente descreve uma figura geométrica:
-
Forma.java
public abstract class Shape { public abstract void draw(); }
Quando decidirmos adicionar formas triangulares e retangulares, herdaremos da classe
Shape
: -
Retângulo.java:
public class Rectangle extends Shape { @Override public void draw() { System.out.println("Drawing rectangle"); } }
-
Triângulo.java:
public class Triangle extends Shape { @Override public void draw() { System.out.println("Drawing triangle"); } }
draw()
. Para termos diferentes implementações do método draw()
, precisamos criar uma classe para cada forma correspondente a uma cor. Se houver três cores, então haverá seis classes: TriangleBlack
, TriangleGreen
, TriangleRed
, RectangleBlack
, RectangleGreen
e RectangleRed
. Seis aulas não é grande coisa. Mas! Se precisarmos adicionar uma nova forma ou cor, o número de classes crescerá exponencialmente. Como sair desta situação? Armazenar cores em um campo e testar opções através de condicionais não é a melhor solução. Uma boa solução é exibir as cores em uma interface separada . Mal dito e feito: vamos criar uma interface Color
e três de suas implementações BlackColor
- GreenColor
e RedColor
:
-
Cor.java:
public interface Color { void fillColor(); }
-
PretoColor.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 vamos adicionar um campo de tipo
Color
à classeShape
- receberemos seu valor no construtor. -
Forma.java:
public abstract class Shape { protected Color color; public Shape(Color color) { this.color = color; } public abstract void draw(); }
color
Usaremos a variável nas implementaçõesShape
. Isso significa que as formas agora podem usar a funcionalidade da interfaceColor
. -
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
é uma ponte que interconecta duas hierarquias de classes separadas.
Dispositivo Bridge: o que é abstração e implementação
Vamos dar uma olhada no diagrama de classes que descreve o padrão Bridge: Aqui você pode ver duas estruturas independentes que podem ser modificadas sem afetar a funcionalidade uma da outra. No nosso caso é:- Abstração - aula
Shape
; - Abstração Refinada - classes
Triangle
,Rectangle
; - Implementador-interface
Color
; - Classes ConcreteImplementor
BlackColor
eGreenColor
.RedColor
Shape
representa uma Abstração - mecanismo de controle da coloração de formas em cores diferentes, que delega a Implementação à interface Color
. Classes Triangle
são Rectangle
objetos reais que utilizam o mecanismo oferecido pela classe Shape
. BlackColor
e GreenColor
- RedColor
implementações específicas no ramo Implementação. Eles são frequentemente chamados de plataforma.
Onde o padrão Bridge é usado?
Uma grande vantagem de usar esse padrão é que você pode fazer alterações na funcionalidade das classes de um branch sem quebrar a lógica de outro. Esta abordagem também ajuda a reduzir o acoplamento de classes de programas. A principal condição para usar os moldes é “seguir as instruções”: não cole em lugar nenhum! Na verdade, vamos descobrir em quais casos você definitivamente precisa usar o Bridge:-
Se for necessário expandir o número de entidades em duas direções (formas geométricas, cores).
-
Se você quiser dividir uma classe grande que não atende ao princípio de responsabilidade única em classes menores com funcionalidade de perfil restrito.
-
Caso haja a possível necessidade de realizar alterações na lógica de funcionamento de determinadas entidades durante a execução do programa.
-
Se necessário, oculte a implementação dos clientes da classe (biblioteca).
Prós e contras do padrão
Como outros padrões, o Bridge tem vantagens e desvantagens. Benefícios da ponte:- Melhora a escalabilidade do código - você pode adicionar funcionalidades sem medo de quebrar algo em outra parte do programa.
- Reduz o número de subclasses - funciona quando é necessário expandir o número de entidades em duas direções (por exemplo, o número de formas e o número de cores).
- Torna possível trabalhar separadamente em dois ramos independentes de Abstração e Implementação - isso pode ser feito por dois desenvolvedores diferentes sem se aprofundar nos detalhes do código um do outro.
- Reduzindo o acoplamento de classes - o único local onde duas classes estão conectadas é a ponte (campo
Color color
).
- Dependendo da situação específica e da estrutura do projeto como um todo, pode haver um impacto negativo na produtividade do programa (por exemplo, se for necessário inicializar mais objetos).
- Complica a legibilidade do código devido à necessidade de navegar entre as classes.
GO TO FULL VERSION