Advertisement
  1. Code
  2. OOP

Padrões de design: o padrão facade (fachada)

Scroll to top
Read Time: 6 min
This post is part of a series called Design Patterns in PHP.
Design Patterns: The Adapter Pattern

() translation by (you can also view the original English article)

Quando se trata de padrões de design, podes ter questões:

Porque é que devemos usar padrões de design em programação? O nosso código pode funcionar bem sem isso.

Quanto à isso a minha questão seria: "Preferias viver numa casa luxuosa, ou em um simples estabelecimento com quatro paredes?" Afinal, ambos servem o nosso propósito.

Geralmente, nós procuramos uma casa luxuosa, porque esta oferece melhores condições e necessita de menos manutenção, e a manutenção podes ser feita com menos aborrecimento porque o trabalho básico já está lá.

A mesma coisa aplica-se a programação: Código que utiliza padrões de design é fácil de entender, fácil de manter e é fácil de estender.

Nesta série de tutoriais, vamos cobrir diferentes padrões de design, que estão disponíveis para nós na programação. Irás aprender sobre as suas vantagens e desvantagens e os fatores que indicam onde os deves usar.

Ao longo destes tutoriais, eu irei pegar em PHP, como linguagem base para demonstrar os padrões de design; contudo, eles são atualmente um conceito que pode ser usado em qualquer linguagem de programação – é uma questão de mudar a sintaxe para a linguagem preferida.

Regras de design são separadas em quatro categorias:

  • Padrões de criação
  • Padrões de estruturação
  • Padrões de comportamento
  • Padrões de concorrência

Neste tutorial, nós vamos cobrir o padrão de design facade(fachada). Ele assenta na categoria dos padrões de estruturação, porque ele lida como o teu código deve ser estruturado para fazê-lo ser compreensível e mantê-lo bem conservado a longo prazo.

Padrão de Design Facade(fachada)

UML

Problema

Vamos assumir que tu tens algumas operações a serem feitas em sequência, e que a mesma ação é necessária em múltiplos sítios dentro da aplicação. Tens que colocar o mesmo código em diferentes sítios. Fizes-te isso, mas após alguns dias descobres que algo tem que ser modificado nesse código. 

Vês qual é o problema? Nós temos que introduzir alterações em todos os sítios onde esse código se encontra. É aborrecido, não é?

Solução

Como solução, o que deverias estar a fazer é criar um controlador principal que lida-se com esse código repetido. Do ponto de vista da chamada, só iriamos chamar esse controlador, para executar ações baseada nos parâmetros providenciados. 

Agora se nós necessitássemos de introduzir qualquer alteração no processo, então iriamos simplesmente modificar o controlador principal, em vez de modificar o código em todos os sítios onde usamos o código.

Exemplo

Neste tutorial, vamos escolher uma lição para que faça as coisas mais claras. Vamos dizer que foi-te atribuída a tarefa de planear o casamento do teu amigo. Se fizeres tudo por tua conta, imagina as coisas que tens que fazer. Irás criar uma grande possibilidade para erro, e aumentas a margem de esquecer algo que pode afetar de forma drástica o casamento do teu amigo.

Neste caso, em vez de fazeres tudo por tua conta, deves usar um planeador de casamentos e ter a certeza que o trabalho fica feito e é bem gerido de forma a que haja menos oportunidades para erro.

Aqui, estás-te a comportar como cliente que inicia o processo, e o planeador do casamento está a trabalhar como facade(fachada) para ti, completando o trabalho baseado na tua decisão.

Exemplo de código

Nesta secção vamos ver mais um exemplo, o qual é muito comum para websites, claro com um exemplo de código. Iremos ver a implementação do padrão de design facade(fachada) usando o processo de checkout de produtos, mas antes de verificarmos o código perfeito com o padrão facade(fachada), vamos dar uma vista de olhos ao código que tem o problema.

Um processo de checkout simples inclui os seguintes passos:

  1. Adicionar um produto ao carrinho.
  2. Calcular a taxa de envio.
  3. Calcular o desconto.
  4. Gerar a ordem.

Problema

1
// Simple CheckOut Process
2
$productID = $_GET['productId'];
3
4
$qtyCheck = new productQty();
5
6
if($qtyCheck->checkQty($productID) > 0) {
7
8
  // Add Product to Cart
9
	$addToCart = new addToCart($productID);
10
	
11
	// Calculate Shipping Charge
12
	$shipping = new shippingCharge();
13
	$shipping->updateCharge();
14
	
15
	// Calculate Discount Based on 
16
	$discount = new discount();
17
	$discount->applyDiscount();
18
	
19
	$order = new order();
20
	$order->generateOrder();
21
}

No código acima, irás verificar que o procedimento de checkout inclui vários objetos que necessitam de ser produzidos em ordem para completar a operação de checkout. Imagina que tens que implementar este processo em múltiplos sítios. Se esse for o caso, seria problemático quando o código tivesse que que ser modificado. É melhor fazer estas alterações em todos os sítios de uma vez. 

Solução

Iremos escrever a mesma coisa com o padrão facade(fachada), o qual faz o mesmo código mais fácil de manter e de estender.

1
class productOrderFacade {
2
	
3
	public $productID = '';
4
	
5
	public function __construct($pID) {
6
		$this->productID = $pID;
7
	}
8
	
9
	public function generateOrder() {
10
		
11
		if($this->qtyCheck()) {
12
			
13
			// Add Product to Cart

14
			$this->addToCart();
15
			
16
			// Calculate Shipping Charge

17
			$this->calulateShipping();
18
			
19
			// Calculate Discount if any

20
			$this->applyDiscount();
21
			
22
			// Place and confirm Order

23
			$this->placeOrder();
24
			
25
		}
26
		
27
	}
28
	
29
	private function addToCart () {
30
		/* .. add product to cart ..  */
31
	}
32
	
33
	private function qtyCheck() {
34
		
35
		$qty = 'get product quantity from database';
36
		
37
		if($qty > 0) {
38
			return true;
39
		} else {
40
			return true;
41
		}
42
	}
43
	
44
	
45
	private function calulateShipping() {
46
		$shipping = new shippingCharge();
47
		$shipping->calculateCharge();
48
	}
49
	
50
	private function applyDiscount() {
51
		$discount = new discount();
52
		$discount->applyDiscount();
53
	}
54
	
55
	private function placeOrder() {
56
		$order = new order();
57
		$order->generateOrder();
58
	}
59
}

A partir de agora, nós temos a “fachada”(facade) da ordem do nosso produto preparada. Tudo o que temos que fazer é usar com alguns canais de comunicação no código, em vez de um monte de código como foi mostrado na parte anterior. 

Por favor verifica a quantidade de código abaixo, o qual precisarás de investir de forma a teres o processo de checkout em múltiplas posições.

1
// Note: We should not use direct get values for Database queries to prevent SQL injection

2
$productID = $_GET['productId'];
3
4
// Just 2 lines of code in all places, instead of a lengthy process everywhere

5
$order = new productOrderFacade($productID);
6
$order->generateOrder();

Agora imagina quando necessitares de fazer alterações no teu processo de checkout, simplesmente crias alterações na classe facade(fachada) que foi criada, em vez de introduzires alterações em todos os sítios onde ele foi aplicado.

Conclusão

Simplificando, podemos dizer que o padrão facade(fachada) deve ser utilizado numa situação onde necessitas de uma única interface para completar múltiplos procedimentos, como no exemplo do planeador de casamentos que está a trabalhar como facade(fachada), para tu completares múltiplos procedimentos.

Por favor, deixa quaisquer comentários ou perguntas no feed abaixo.

Seja o primeiro a saber sobre novas traduções–siga @tutsplus_pt no Twitter!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.