Skip to content

Instantly share code, notes, and snippets.

@lfalmeida
Last active December 20, 2017 10:41
Show Gist options
  • Save lfalmeida/28f358a0a0632b67b0cdd1d760bf4368 to your computer and use it in GitHub Desktop.
Save lfalmeida/28f358a0a0632b67b0cdd1d760bf4368 to your computer and use it in GitHub Desktop.
<?php
/**
* Definimos uma interface para o cálculo do frete
*/
interface ShippingCalculatorInterface
{
// Deve receber a instância do pedido que o frete será calculado
public function calculate(Order $order);
}
/**
* Definimos uma interface para o pedido
*/
interface OrderInterface
{
public function calculateShipping();
public function setItensCost(float $cost): Order;
public function getItensCost():float;
}
/**
* Esta classe é o contexto da estratégia, que será configurada por uma
* classe cliente que a utiliza
*/
class Order implements OrderInterface
{
protected $cost;
private $shippingCalculator;
// Toda instância deve receber um objeto que implementa a interface ShippingCalculator
public function __construct(ShippingCalculatorInterface $shippingCalculator)
{
$this->shippingCalculator = $shippingCalculator;
}
public function calculateShipping()
{
// O cálculo do frete será realizado de fato pelo objeto Strategy configurado
return $this->shippingCalculator->calculate($this);
}
// [...]
}
/**
* Implementação da calculadora de custo de entrega padrão
*
*/
class DefaultShippingCalculator implements ShippingCalculatorInterface
{
/**
* Aqui definimos a lógica para calcular no caso de entrega normal,
* imaginando que pela regra de negócio, o valor da entrega será 5% do custo dos produtos
*/
public function calculate(Order $order)
{
return $order->getItemsCost() * 0.05;
}
}
/**
* Implementação da calculadora de custo de entrega Expressa
*
*/
class ExpressShippingCalculator implements ShippingCalculatorInterface
{
/**
* Aqui definimos a lógica para calcular no caso de entrega Expressa,
* imaginando que pela regra de negócio, o valor da entrega será 10% do custo dos produtos
*/
public function calculate(Order $order)
{
return $order->getItemsCost() * 0.1;
}
}
// A classe Order seria consumida desta maneira:
// para um pedido com entrega normal
$defaultShippingCalculator = new DefaultShippingCalculator();
$order = new Order($defaultShippingCalculator);
$order->setItemsCost(280.00);
$shippingCost = $order->calculateShipping();
// para um pedido com entrega expressa
$defaultShippingCalculator = new ExpressShippingCalculator();
$order = new Order($defaultShippingCalculator);
$order->setItemsCost(280.00);
$shippingCost = $order->calculateShipping();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment