#MOVED! now this library is mantained by pugx/godfather
| A small library for the strategy pattern in PHP, if you use Symfony2 you could easily integrate Godfather with the bundle.
Be careful this is not stable and is not production-ready.
http://en.wikipedia.org/wiki/Strategy_pattern
Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
- If you have a lot of classes that differs only by their behaviour...
- If you have multiple conditional statements in order to define different behaviours...
- Given an object you want to know its manager...
composer require liuggio/godfather dev-master
Imagine that you want to add a product into a cartitem with some options. The problem is that you have multiple products, and each product has a different policy/behaviour.
You could find the code of this use case in: tests/Godfather/Test/FunctionalTest.php tests/GodFather/Test/FunctionalTest.php
before the cure:
// Pseudo Code
class Cart
function add(ProductInterface $product, OptionsInterface $options)
{
if ($product instanceOf Bus) {
set $cartItem->inbound = true;
}
if ($product instanceOf Tshirt) {
// set ...
}
return $cartItem;
}
With GodFather:
// Step1. init
$godfather = new Godfather();
// |-context name---Interface to respect (optional)----Fallback Strategy-(optional)-|
$godfather->addContext('cart', 'Godfather\Test\Fixture\CartItemInterface', new StandardCartItem());
// start adding billion of strategies
// |-context name---------------context key----------------Strategy-------|
$godfather->addStrategy('cart', 'Godfather\Test\Fixture\Entity\Ticket', new TicketCartItem());
$godfather->addStrategy('cart', 'Godfather\Test\Fixture\Entity\Socket', new SocketCartItem());
// Step2. usage
class Cart
public function __construct($godfather)
//...
public function add(ProductInterface $product, OptionsInterface $options)
{
// get the strategy for cart with the context $product
$strategy = $this->godfather->getStrategy('cart', $product);
// or $strategy = $this->godfather->getCart($product);
return $strategy->addToCart($product, $options);
}
You want to call the correct manager, starting from the entity:
$godfather = new Godfather();
// the context is created if is not found.
$godfather->addStrategy('manager', 'Product\ShoeProduct', new ShoeProductManager());
$godfather->addStrategy('manager', 'Product\PillowProduct', new PillowProductManager());
$manager = $this->godfather->getManager($product);
// or $manager = $this->godfather->getStrategy('manager', $product);
Add the bundle in the app/AppKernel.php
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = array(
...
new Godfather\GodfatherBundle\GodfatherBundle(),
Modify the app/config/config.yml
only if you need:
// add the below configuration only if you need to specify the fallback or the interface.
godfather:
contexts:
manager:
fallback: %manager.standard.class%
interface: %manager.interface.class%
cart: ~
Set your strategies:
services:
manager.shoe:
class: ShoeProductManager
tags:
- { name: godfather.strategy, context_name: 'manager', context_key: %product.show.class% }
manager.pillow:
class: PillowProductManager
tags:
- { name: godfather.strategy, context_name: 'manager', context_key: %product.pillow.class% }
payment.pillow:
class: PillowPaymentManager
tags:
- { name: godfather.strategy, context_name: 'payment', context_key: %payment.pillow.class% }
then use it in the controller:
$product = new \Product\ShoeProduct();
$manager = $container->get('godfather')->getManager($product);
// or $manager = $container->get('godfather')->getStrategy('manager', $product);
$manager->...
Active contribution and patches are very welcome. To keep things in shape we have quite a bunch of unit tests. If you're submitting pull requests please make sure that they are still passing and if you add functionality please take a look at the coverage as well it should be pretty high :)
composer create-project liuggio/godfather --dev -s dev
cd godfather
bin/phpunit
please help me.
- improve Context Factory
- gather feedback
- annotation