Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Feature/delegate factories #825

Closed
wants to merge 4 commits into
from

Conversation

Projects
None yet
4 participants
Member

Ocramius commented Apr 3, 2013

Provides documentation for zendframework/zf2#4145

@Ocramius Ocramius referenced this pull request in zendframework/zendframework Apr 3, 2013

Merged

Delegate factories #4145

@robertbasic robertbasic commented on an outdated diff Apr 3, 2013

.../modules/zend.service-manager.delegator-factories.rst
+ use Zend\ServiceManager\ServiceLocatorInterface;
+
+ class BuzzerDelegatorFactory implements DelegatorFactoryInterface
+ {
+ public function createDelegatorWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName, $callback)
+ {
+ $realBuzzer = call_user_func($callback);
+ $eventManager = $serviceLocator->get('EventManager');
+
+ $eventManager->attach('buzz', function () { echo "Stare at the art!\n"; });
+
+ return new BuzzerDelegator($realBuzzer, $eventManager);
+ }
+ }
+
+You can then instruct the service manager to handle the service ``'buzzer'`` as a delegate:
@robertbasic

robertbasic Apr 3, 2013

Contributor

I don't think the single quotes here are needed.

@robertbasic robertbasic commented on an outdated diff Apr 3, 2013

.../modules/zend.service-manager.delegator-factories.rst
+
+Delegator factory signature
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A delegator factory has following signature:
+
+.. code-block:: php
+
+ namespace Zend\ServiceManager;
+
+ interface DelegatorFactoryInterface
+ {
+ public function createDelegatorWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName, $callback);
+ }
+
+The parameters passed to the ``DelegatorFactoryInterface#createDelegatorWithName`` factory are following:
@robertbasic

robertbasic Apr 3, 2013

Contributor

are the following

@robertbasic robertbasic commented on an outdated diff Apr 3, 2013

.../modules/zend.service-manager.delegator-factories.rst
@@ -0,0 +1,156 @@
+.. _zend.service-manager.delegator-factories:
+
+Delegator service factories
+===========================
+
+``Zend\ServiceManager`` can instantiate `delegators`_ of requested services, decorating them
+as specified in a delegate factory implementing the `delegator factory interface`_.
+
+The delegate pattern is useful in cases when you want to wrap a real service in a `decorator`_,
+or generally intercept actions being performed on the delegate in an `AOP`_ fashioned way.
+
+Delegator factory signature
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A delegator factory has following signature:
@robertbasic

robertbasic Apr 3, 2013

Contributor

has the following

@robertbasic robertbasic commented on an outdated diff Apr 3, 2013

.../modules/zend.service-manager.delegator-factories.rst
+is prepended.
+
+The delegated object ``Buzzer`` (original object) is defined as following:
+
+.. code-block:: php
+ :linenos:
+
+ class Buzzer
+ {
+ public function buzz()
+ {
+ return 'Buzz!';
+ }
+ }
+
+The delegator class ``BuzzerDelegator`` has following structure:
@robertbasic

robertbasic Apr 3, 2013

Contributor

has the following

@robertbasic robertbasic commented on an outdated diff Apr 3, 2013

.../modules/zend.service-manager.delegator-factories.rst
+
+ public function __construct(Buzzer $realBuzzer, EventManagerInterface $eventManager)
+ {
+ $this->realBuzzer = $realBuzzer;
+ $this->eventManager = $eventManager;
+ }
+
+ public function buzz()
+ {
+ $this->eventManager->trigger('buzz', $this);
+
+ return $this->realBuzzer->buzz();
+ }
+ }
+
+To use the ``BuzzerDelegator``, you can run following code:
@robertbasic

robertbasic Apr 3, 2013

Contributor

run the following

@robertbasic robertbasic commented on an outdated diff Apr 3, 2013

.../modules/zend.service-manager.delegator-factories.rst
+ $eventManager->attach('buzz', function () { echo "Stare at the art!\n"; });
+
+ $buzzer = new BuzzerDelegator($wrappedBuzzer, $eventManager);
+
+ echo $buzzer->buzz(); // "Stare at the art!\nBuzz!"
+
+This logic is fairly simple as long as you have access to the instantiation logic of the
+``$wrappedBuzzer`` object.
+
+You may not always be able to define how ``$wrappedBuzzer`` is created, since a factory for it may be
+defined by some code to which you don't have access, or which you cannot modify without introducing further
+complexity.
+
+Delegator factories solve this specific problem by allowing you to wrap, decorate or modify any existing service.
+
+A simple delegator factory for the ``'buzzer'`` service can be implemented as following:
@robertbasic

robertbasic Apr 3, 2013

Contributor

I don't think the single quotes here are needed.

Contributor

robertbasic commented Apr 3, 2013

Great job!

Member

Maks3w commented Apr 8, 2013

Note as source PR goes against develop this too

GeeH added a commit that referenced this pull request Apr 15, 2013

Contributor

GeeH commented Apr 15, 2013

Merged to develop, had to close by hand as it was opened against master.

@GeeH GeeH closed this Apr 15, 2013

@Ocramius Ocramius commented on the diff May 3, 2013

.../modules/zend.service-manager.delegator-factories.rst
+ class Buzzer
+ {
+ public function buzz()
+ {
+ return 'Buzz!';
+ }
+ }
+
+The delegator class ``BuzzerDelegator`` has the following structure:
+
+.. code-block:: php
+ :linenos:
+
+ use Zend\EventManager\EventManagerInterface;
+
+ class BuzzerDelegator extends Buzzer
@Ocramius

Ocramius May 3, 2013

Member

extending is required to respect the LSP

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment