I have a Products class. Now I want to add some kind of discount module to my site which should interact with the Products class.
Currently the only solution I can think of is using some kind of decorator pattern to wrap around the product class so it can alter the price of the product.
Like this:
class Product {
function price() {
return 10;
}
}
class ProductDiscountDecorator {
private $product;
function __construct($product) {
$this->product = $product;
}
function price() {
return $this->product->price()*0.8;
}
}
$product = new ProductDiscountDecorator(new Product());
echo $product->price();
This being the discount, the prices should be adjusted on every page on the website. So every page using the Product class should also add the decorator. The only way I could think of solving this is using a factory that automatically adds this decorator.
$product = $factory->get('product'); // returns new ProductDiscountDecorator(new Product());
It would probably work, but I feel like I'm misusing the decorator pattern here.
Do you guys have any thoughts on this? How would you implement something like this?
A Decorator is one option. Another option would be to use a Strategy Pattern for calculating the discount
class Product
{
protected $discountStrategy;
protected $price;
public function __construct(DiscountStrategy $discountStrategy)
{
$this->discountStrategy = $discountStrategy;
}
public function getPrice()
{
return $this->discountStrategy->applyDiscount($this->price);
}
}
and then capsule the various possible discounts into classes of their own:
interface DiscountStrategy
{
public function applyDiscount($cent);
}
class NoDiscount implements DiscountStrategy
{
public function applyDiscount($cent)
{
return $cent;
}
}
class PremiumDiscount implements DiscountStrategy
{
public function applyDiscount($cent)
{
return $cent - $cent * 0.8;
}
}
You'd still use a Factory to assemble the products but Strategies are more fine grained and you can reuse them in other situations as well, for instance, some loyal customers could get a Discount as well, even when the product itself doesnt have a discount attached.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With