[TYPO3-ect] News about XCLASSES?
Joerg Schoppet
joerg at schoppet.de
Thu Aug 24 07:29:02 CEST 2006
Oliver Hader wrote:
> Ernesto Baschny [cron IT] wrote:
>> You create a new class that implements the complete interface of the
>> original class (i.e. it provides all methods from the "inherited"
>> class). The constructor gets an instance of the original class and you
>> start with calling all original methods on that instance that you get
>> passed. Then you can simply add or change or enhance certain methods to
>> do what you want it to do. As the constructor gets an instance of the
>> class with the same interface, it is easy to "chain" together many classes.
>
> That's true. Real decorators must have the complete interface as it is
> present the decorated class. But in PHP5 we could use something new, the
> __call($method, $args) for calling the method from the decorated class.
>
> I've created a small example on the decorator usage. Decorators have
> appropriate class names, the decorated classes a called "Components".
> In that example it's possible to build up a multi-functional-object that
> has all functionallity of the component class and all involved
> decorators. I removed some stuff, just to get the idea, the complete
> code is shown at http://devel.t3ip.de/decorator.php.txt.
>
> So here we go:
>
>
> $digitComponent = new DigitComponent(16, 2);
> // give it a try, and create a "hyper" functional class
> $hyperObject =
> new SummateDecorator(
> new DivideDecorator(
> new MultiplyDecorator(
> $digitComponent
> )
> )
> );
> $hyperObject->divide();
> $hyperObject->multiply();
> $hyperObject->summate();
> $hyperObject->show();
>
>
> /**
> * Here come the components we are working on.
> * This could be any type of content.
> */
> abstract class Component {
> public $content = '';
>
> public function show() {}
> public function addBR() {}
> }
>
> class DigitComponent extends Component {
> public $numberA;
> public $numberB;
> public function __construct($numberA, $numberB) {}
> }
>
> /**
> * Here come our decorators playing with the components in some way.
> */
> abstract class Decorator extends Component {
> protected $component;
>
> public function __construct(Component &$component) {
> $this->component =& $component;
> }
>
> public function show() {
> // call the show method of the component
> $this->component->show();
> }
>
> public function __call($method, $args) {
> // fetch calls to currenty unsupported methods an try
> // on the decorated component
> call_user_method($method, $this->component, $args);
> }
>
> public function getComponent() {
> $component =& $this->component;
>
> // iterate out of decorators up to the component
> while ($component instanceof Decorator)
> $component =& $component->component;
>
> // return the component so we can work on it
> return $component;
> }
> }
>
> class MultiplyDecorator extends Decorator {
> public function multiply() {}
> }
>
> class DivideDecorator extends Decorator {
> public function divide() {}
> }
>
> class SummateDecorator extends Decorator {
> public function summate() {}
> }
>
>
> So you can see, that the methods divide, summate, multiply are sticked
> together with several decorator classes. Probably someone finds some
> errors in my "two decorator-cents", but it should just show, how it
> could work.
>
>
>> When TYPO3 then needs to create a cObj and our extension has
>> "registered" somehow that we provide an enhancement to it, the
>> makeInstance method just has to chain that together:
>>
>> function &makeInstance($className) {
>> $obj =& new $className;
>> $decorators =
>> $GLOBALS['TYPO3_CONF_VARS']['SYS']['OBJ_DECORATORS'][$className];
>> foreach ($decorators as $dec) {
>> $obj =& new $dec($obj);
>> }
>> return $obj;
>> }
>>
>> This is untested, I just made it out! :)
>>
>
> I also didn't check this, but I'm sure that this will work! ;)
>
> On using decorators the system would get very complex very fast. So if
> there is no documentation or "plan" how to use decorators in TYPO3, give
> it some months and nobody knows again which decorator solves which problem.
> An advantage is that you could build your own objects, depending on your
> special demands. The disadvantage could be, that laziness finds it's way
> it that topic and everything is fired up using all available decorators
> and kills performace step by step.
>
> But I like the idea of using design patterns in general - as you all can
> imagine, "decorator" is not the only one out there... ;)
>
>
> Regards,
> Olly
Hi,
this is nearly the solution I'm working on. A combination of Olly's and
Ernesto's thoughts.
I've a general registry-object. Each extension, which wants to provide a
decorator for a given class has to register its classes (decorators) in
the registry-object informing about the class it wants to extend
(through a method-call in ext_localconf.php), the classes its depend on
and classes its conflicts with.
As a developer I can then simple call a factory-method of the
registry-object, informing about the class I want and which additional
functionality I want, and the factory-method then automatically resolves
all necessary dependencies and decorator-chains and return a new object.
With the technique of registering, it could also be possible to create a
little backend-module, which shows the available decorators (like the
sv_auth be-module in TYPO3 3.7).
Joerg
More information about the TYPO3-team-extension-coordination
mailing list