De que se trata o artigo:

Uso dos padrões Facade, Template Method e Strategy. Neste artigo o Facade foi explicado e comparado em situações diferentes. Comparações e indicações de frameworks que utilizam o padrão Template Method foram utilizadas para facilitar seu entendimento, e por fim o Strategy foi abordado e exemplificado.

Para que serve:

Este artigo oferece informações ao desenvolvedor que podem auxiliá-lo a simplificar o acesso a subsistemas, além de desenvolver aplicações que sejam mais flexíveis. Utilizar os padrões abordados auxilia na busca por códigos mais simples, elegantes e reutilizáveis.

Em que situação o tema é útil:

Além de ser considerado uma boa prática de programação, o uso de Facades para reduzir o acoplamento e a complexidade para utilização de subsistemas aumenta a manutenibilidade do sistema. O Template Method é útil quando se quer dar a chance, ou exigir, de um desenvolvedor que certas customizações sejam feitas. Strategy exibe sua utilidade toda vez em que se faz necessário implementar diversas variações de comportamentos ou de algoritmos que podem ser utilizados por meio de uma interface padrão.

Explicando Padrões de Projeto – Parte 3:

Quando um sistema é composto por diversos subsistemas complexos é possível simplificar o acesso às funcionalidades utilizando Facades. Facades provêem interfaces simplificadas para isolar e facilitar o acesso a este tipo de sistemas.

Freqüentemente desenvolvedores e arquitetos desejam que a implementação de certas operações sejam delegadas, ou influenciadas, por desenvolvedores finais. Uma solução conhecida para este problema é definida no padrão Template Method, que permite definir partes do código que devem ser obrigatoriamente sobrescritas ou, ainda permitir, mas não obrigando a, que partes sejam modificadas pelo desenvolvedor.

Quando se faz necessário variar o comportamento de um sistema, ou de um algoritmo, mantendo uma interface padrão, é possível substituir condicionais encadeadas (ifs) que seriam utilizadas para escolher o comportamento adequado implementando o padrão Strategy. Desta forma o resultado é a produção de arquiteturas e códigos mais elegantes, eliminando o encadeamento de tais condicionais do código.

Nos três casos é possível observar ganhos do ponto de vista de Orientação a Objetos. Estes padrões, por exemplo, visam à redução de acoplamento. No caso de Template Method e Strategy há também ganhos no que se refere à coesão, uma vez que cada classe e/ou subclasse desempenham papéis mais bem definidos. Conseqüências decorrentes do uso destes padrões podem ser localizadas nos quadros resumo de cada um deles.

Padrões de Projeto: Trilhando o caminho

No artigo anterior desta série, os padrões de criação Abstract Factory e Factory Method foram apresentados. Neste artigo trabalharemos os padrões Façade, Template Method e Strategy, que constituem parte importante do catálogo de padrões proposto pela GoF. O uso destes padrões pode poupar trabalho, além de privilegiar a flexibilidade da arquitetura de sistemas.

Padrão: Façade

O principal objetivo de um Façade é facilitar o uso de um ou mais componentes de software. Isso é realizado por meio da construção de uma “fachada” que isola a aplicação cliente de toda a complexidade de um subsistema. O padrão Façade define uma interface de alto-nível que simplifica as chamadas a subsistemas complexos.

Basicamente, o padrão Façade propõe uma forma mais simples de interagir com o sistema que o modelo atual oferece. Claro, por ser mais simples, esta abordagem funciona quando o cliente precisa utilizar apenas um subconjunto dos recursos oferecidos pelo subsistema e/ou adaptá-lo para uso de uma maneira particular em suas necessidades.

Imagine o cenário: na empresa Acme Co. há uma plataforma complexa de APIs de cobrança, mas clientes externos precisam utilizar apenas parte dos seus recursos. Em vez de conhecer toda a complexidade da API de cobrança, seria adequado que os desenvolvedores disponibilizassem uma interface simples o suficiente para chamar os métodos que realizam as tarefas necessárias. A idéia é criar uma “fachada” que esconda toda a complexidade interna das APIs de cobrança. Dessa forma, os clientes da API de cobrança da Acme Co. ficarão agradecidos. A Figura 1 ilustra a solução do problema.

Figura 1. Isolando o cliente da complexidade dos subsistemas

Agora um exemplo concreto. Pensando na implementação da história “como usuário, gostaria de abrir uma conta e efetuar um depósito para que eu possa iniciar transações bancárias”, temos o diagrama de classes representado na Figura 2.

Figura 2. Diagrama de Classes do Subsistema de Abertura de Contas

O subsistema bancário responsável pela abertura de contas possui classes diferentes para representar o cliente (Customer) e a conta (Account). Assim, para criar uma conta com um depósito inicial, seriam necessárias duas chamadas, uma para criar a conta e outra para efetuar o depósito inicial. Para simplificar o uso do subsistema, um façade foi criado (Bank) para realizar as duas operações em uma única chamada de método (createCustomer(...)). Na Listagem 1, a implementação da solução.

Listagem 1. Implementação do Façade Bank

// Classe do subsistema que representa o cliente
 package pigbank;
  
 public class Customer {
  
   private String name;
   private String address;
   
   //constructor
   public Customer(String address, String name) {
    this.address = address;
    this.name = name;
   }
   
   //getters and setters...
 }
  
 // Classe do subsistema que representa a conta no banco
 package pigbank;
 import java.math.BigDecimal;
  
 public class Account {
  
   private Customer customer;
   private BigDecimal balance;
   
   //constructor
   public Account(Customer customer) {
    this.customer = customer;
   }
   
   //getters and setters...
 }
  
 // Implementação do façade para simplificar o acesso ao subsistema
 package pigbank.facade;
 import java.math.BigDecimal;
 import pigbank.Account;
 import pigbank.Customer;
  
 public class Bank {
          
          private Customer customer;
          private Account account;
  
     public void createCustomer(String name, String address, BigDecimal initalDeposit) {
         this.customer = new Customer(name, address);
         this.account = new Account(this.customer);
         this.account.setBalance(initalDeposit);
     }
 }

Façade vs. Session Façade

Em sistemas distribuídos, o número sucessivo de chamadas a métodos remotos aumenta o fluxo de pacotes na rede e pode levar à lentidão do sistema. Na solução com o Bank façade, além de simplificar a API para a aplicação cliente, também foi reduzido o número de chamadas. De um modo geral, em um ambiente JEE, quando um façade é utilizado com o propósito de diminuir o overhead na rede, adotamos o termo Session Façade. Um session façade é um session bean que organiza um conjunto de métodos de negócio relacionados. O cuidado aqui é sempre se lembrar do princípio de Orientação a Objetos da separação de responsabilidades, isso evita que o session façade não vire um bean-faz-tudo.

No ambiente Java EE, quando um bean interage com outro bean no mesmo servidor (mesma máquina virtual Java), o acesso aos métodos é realizado por meio da interface local, evitando o tráfego de pacotes na rede. Esta abordagem pode render significativos ganhos de desempenho, particularmente em casos onde o bean está interagindo com múltiplos session beans e entidades de persistência.

Façade vs. Adapter

No primeiro artigo da série foi apresentado o padrão Adapter, que tem semelhanças com o padrão Façade. De certa forma, os dois padrões podem ser utilizados como wrappers para funções mais complexas. Porém, vale reforçar as diferenças: um Façade simplifica uma interface enquanto um Adapter converte uma nova interface em uma interface pré-existente.

Façades permitem esconder a complexidade de um subsistema, reduzir o acoplamento entre componentes e simplificar o uso do subsistema. Por outro lado, um Adapter permite converter uma interface em outra interface que um programa cliente espera, ampliando o uso dessa classe em uma nova hierarquia e promovendo o comportamento polimórfico dos componentes do sistema.

Pattern: Façade

Objetivo

Simplificar o uso de um subsistema existente.

Problema

A aplicação cliente tem a necessidade de interagir com apenas alguns métodos/classes de um subsistema complexo e/ou utilizar esse subsistema de uma maneira particular.

Solução

Criar uma fachada que isola a aplicação cliente de toda a complexidade do subsistema.

Participantes

Façade: declara uma interface para acessar o subconjunto de métodos/classes do sistema.

ConcreteClasses: implementam as chamadas necessárias no subsistema para os métodos declarados na interface.

Conseqüências

Fachadas simplificam o acesso a subsistemas. Contudo, como não dão acesso a todos os métodos/classes do subsistema, alguma funcionalidade interna pode ficar indisponível para o cliente.

Implementação

Criar uma nova classe (ou um conjunto de novas classes) que implementem a nova interface desejada.


Template Method

Pertencente à classe de padrões comportamentais, o padrão Template Method define o esqueleto de um algoritmo, de forma que seja possível delegar determinados passos para subclasses, que por sua vez redefinem o comportamento sem que a estrutura do algoritmo seja alterada.

...

Quer ler esse conteúdo completo? Tenha acesso completo