De acordo com sua defini¸c˜ao, o padr˜ao Bridge tem por finalidade: “Desacoplar uma abs- tra¸c˜ao de sua implementa¸c˜ao para que os dois possam variar independentemente” [Gamma et al., 1994]. Em situa¸c˜oes nas quais podem existir v´arios tipos diferentes de abstra¸c˜oes, assim como diversas implementa¸c˜oes, a ado¸c˜ao e aplica¸c˜ao deste padr˜ao facilita a manuten- ¸c˜ao do c´odigo-fonte, assim como a extens˜ao, pois facilita o acr´escimo de novas abstra¸c˜oes, sem impactar o projeto como um todo.
Quando se necessite, por exemplo, selecionar ou modificar uma implementa¸c˜ao em tempo de execu¸c˜ao, deve ser necess´ario evitar uma liga¸c˜ao forte entre esta implementa¸c˜ao e sua referente abstra¸c˜ao. Neste caso a utiliza¸c˜ao do padr˜ao Bridge torna-se necess´aria. Tamb´em pode ser verificado que, ao separar uma abstra¸c˜ao de sua implementa¸c˜ao, qualquer mudan¸ca que se fa¸ca na implementa¸c˜ao n˜ao ir´a afetar sua respectiva abstra¸c˜ao, facilitando assim a manuten¸c˜ao do fonte.
4.3.1
Exemplo utilizado para este padr˜ao
Para exemplificar a utiliza¸c˜ao do padr˜ao de projetos Bridge, ´e utilizado um exemplo retirado de [Kulandai, 2012], no qual ´e modelada uma f´abrica que produz dois tipos prin- cipais de meios de transportes: carros e bicicletas. Al´em destes dois produtos, existem duas formas com as quais ´e poss´ıvel fabric´a-los: produzindo por meio de maquin´ario fabril e montando de forma manual. Ou seja, existem dois tipos diferentes de produtos e cada produto possui duas formas diferentes de fabrica¸c˜ao.
A classe que representa o produto “carro” possui o nome Car, e a classe que repre- senta o produto “bicicleta” est´a designada como Bike. A fabrica¸c˜ao por meio de processos automatizados da f´abrica possui uma classe com o nome Produce, e a fabrica¸c˜ao manual tem sua classe, chamada Assemble. Al´em destas classes, o cen´ario possui uma classe ge- ral dos ve´ıculos, chamada Vehicle, que ´e herdada por ambos os produtos fabricados. A figura 4.4 mostra um diagrama de classes para melhor entendimento do cen´ario. As classes sobrepostas possuem implementa¸c˜ao similar `as classes que as sobrep˜oem.
Como pode ser observado, o padr˜ao Bridge j´a est´a sendo utilizado. De acordo com este padr˜ao , o objetivo principal ´e o de separar uma abstra¸c˜ao de sua implementa¸c˜ao. Neste caso espec´ıfico, as abstra¸c˜oes s˜ao os tipos de produtos e as implementa¸c˜oes s˜ao as formas com as quais cada um desses produtos s˜ao fabricados. Existe um desacoplamento entre os produtos e seus tipos de fabrica¸c˜ao.
Caso este padr˜ao n˜ao estivesse sendo utilizado, uma solu¸c˜ao que poderia vir a ser usada seria a de criar a classe Vehicle sendo herdada pelos dois tipos de ve´ıculos. Em seguida, cada ve´ıculo estaria associado com ambos os m´etodos de fabrica¸c˜ao. Desta forma haveria duplica¸c˜ao de c´odigos, pois para cada ve´ıculo haveriam duas classes Produce e duas classes
Padrão Bridge 70
Figura 4.4: Diagrama de classes do exemplo para o padr˜ao Bridge.
Assemble. As classes estariam fortemente acopladas e se fosse necess´ario incluir um novo tipo de produto, haveria grande impacto e retrabalho no projeto.
Por´em, neste caso, foi implementado um desacoplamento entre os tipos de ve´ıculos e suas formas de fabrica¸c˜ao. Por meio da interface Workshop, referente `as formas de fabrica¸c˜ao, a duplica¸c˜ao de c´odigos foi evitada e se for necess´ario inserir novos ve´ıculos ou novas formas de fabrica¸c˜ao, isto n˜ao acarretar´a grandes problemas ao projeto como um todo.
4.3.2
Compara¸c˜ao das implementa¸c˜oes em Java e ooErlang
As classes mostradas no diagrama referente `a figura 4.4 foram todas implementadas em ooErlang, tendo-se em vista que a implementa¸c˜ao em Java foi retirada de [Kulandai, 2012]. Observadas e ressalvadas as relativas peculiaridades na sintaxe de cada uma das linguagens, as implementa¸c˜oes em ooErlang apresentam-se semelhantes `as mostradas em Java. Os c´odigos observados em 4.3.1 e 4.3.2 revelam a implementa¸c˜ao da classe Bike em Java e ooErlang, respectivamente.
1 public class Bike extends Vehicle { 2
3 public Bike(Workshop workShop1, Workshop workShop2) { 4 super(workShop1, workShop2);
5 }
6
7 public void manufacture() { 8 System.out.print("Bike "); 9 workShop1.work(); 10 workShop2.work(); 11 } 12 13 }
C´odigo 4.3.1: Classe Bike em Java
1 -class(bike). 2 -extends(vehicle). 3 -export([new/2, manufacture/0]). 4 -constructor([new/2]). 5 6 methods. 7 8 new(WorkShop1, WorkShop2) -> 9 self::WorkShop1 = WorkShop1, 10 self::WorkShop2 = WorkShop2. 11 12 manufacture() -> 13 io:format("Bike "), 14 Work1 = self::WorkShop1, 15 Work2 = self::WorkShop2, 16 Work1::work(), 17 Work2::work().
C´odigo 4.3.2: Classe Bike em ooErlang
implementa¸c˜oes da classe Car, por isso apenas o fonte da classe Bike ´e mostrado. Deve-se observar que cada objeto da classe Bike recebe como parˆametro duas formas de fabrica¸c˜ao, referente `as duas maneiras com que pode ser produzido. Assim como a classe Car, a classe Bike herda os atributos e m´etodos da classe Vehicle.
Analisando os c´odigos da classe Assemble, mostrados em 4.3.3 e 4.3.4 (Java e ooErlang respectivamente), pode-se notar que esta classe implementa o m´etodo work(), presente na interface Workshop. Isto ocorre de forma semelhante com o fonte da classe Produce. A utiliza¸c˜ao da interface Workshop ´e o ponto fundamental de aplica¸c˜ao do padr˜ao Bridge neste exemplo, possibilitando separar os objetos de suas relativas formas de fabrica¸c˜ao.
Padrão Bridge 72
1 public class Assemble implements Workshop { 2
3 public void work() {
4 System.out.println(" Assembled.");
5 }
6 }
C´odigo 4.3.3: Classe Assemble em Java
1 -class(assemble). 2 -implements(workshop). 3 -export([work/0]). 4 5 methods. 6 7 work() -> 8 io:format(" Assembled. ~n").
C´odigo 4.3.4: Classe Assemble em ooErlang
A classe Vehicle possui dois atributos, relacionados com os dois tipos de fabrica¸c˜ao dos ve´ıculos da f´abrica utilizada no exemplo. Os m´etodos desta classe s˜ao um construtor, que apenas instancia um objeto, dependendo da classe principal (BridgePattern) e o m´etodo abstrato manufacture(), que ´e implementado nas classes Bike e Car.
Em rela¸c˜ao `a classe principal, BridgePattern, para testar a utiliza¸c˜ao do padr˜ao Bridge, s˜ao instanciados dois objetos, um do tipo Car e outro do tipo Bike. Para cada um destes, ´
e passado como parˆametro de constru¸c˜ao os dois distintos modos de fabrica¸c˜ao de um ve´ıculo. Em seguida ´e utilizado o m´etodo manufacture(), que ´e implementado em cada um dos ve´ıculos, e realiza a fabrica¸c˜ao do ve´ıculo das duas formas existentes. A implementa¸c˜ao desta classe est´a mostrada nos c´odigos em 4.3.5 e 4.3.6.
1 public class BridgePattern { 2
3 public static void main(String[] args) { 4
5 Vehicle vehicle1 = new Car(new Produce(), new Assemble()); 6 vehicle1.manufacture();
7 Vehicle vehicle2 = new Bike(new Produce(), new Assemble()); 8 vehicle2.manufacture();
9 }
10 }
1 -class(bridgePattern). 2 -export([main/0]). 3 4 class_methods. 5 6 main() ->
7 Vehicle1 = car::new(produce::new_(), assemble::new_()), 8 Vehicle1::manufacture(),
9
10 Vehicle2 = bike::new(produce::new_(), assemble::new_()), 11 Vehicle2::manufacture().
C´odigo 4.3.6: Classe principal BridgePattern em ooErlang
Assim para ambos os ve´ıculos, os dois m´etodos de fabrica¸c˜ao s˜ao testados. Percebe-se assim que, dependendo da necessidade do sistema, poderiam ser inclu´ıdos novos ve´ıculos e eles j´a poderiam possuir as duas formas de fabrica¸c˜ao que j´a existem, sem necessidade de alterar nenhum c´odigo em qualquer outra classe de ve´ıculos. O mesmo ´e valido em uma situa¸c˜ao em que fosse necess´ario retirar de fabrica¸c˜ao algum tipo de ve´ıculo. As figuras 4.5 e 4.6 mostram a execu¸c˜ao deste exemplo em Java e ooErlang.
A extens˜ao do Erlang para orienta¸c˜ao `a objetos, ooErlang, mostrou poder ser utilizada na implementa¸c˜ao de fontes similares aos fontes utilizados no exemplo mostrado para o padr˜ao Bridge. Este padr˜ao estrutural ´e bem aplicado em situa¸c˜oes onde seja necess´ario variar as implementa¸c˜oes distintamente de suas abstra¸c˜oes.
Com a aplica¸c˜ao deste padr˜ao de projeto, ´e poss´ıvel perceber que a inser¸c˜ao e/ou exclus˜ao de novos ve´ıculos na f´abrica utilizada neste exemplo, n˜ao iria ocasionar um grande impacto no projeto como um todo. Similarmente, se fosse necess´ario incluir novas formas de fabrica¸c˜ao de ve´ıculos, ou retirar alguma forma j´a existente, tamb´em n˜ao haveriam impactos no projeto inteiro.
As principais consequencias provindas da utiliza¸c˜ao deste padr˜ao de projetos podem ser citadas como sendo o desacoplamento de uma interface com uma implementa¸c˜ao (elimi- nando dependˆencias), melhoramento da extensibilidade do fonte em rela¸c˜ao `as hierarquias de abstra¸c˜ao e implementa¸c˜ao (tornam-se independentes), e a caracter´ıstica de encapsula- mento deste padr˜ao, que n˜ao mostra ao usu´ario detalhes da implementa¸c˜ao que n˜ao s˜ao do interesse do mesmo.
Padrão Composite 74
Figura 4.5: Execu¸c˜ao do exemplo para o padr˜ao Bridge em Java.