Search code examples
phpdesign-patternsoxid

Transparent parent classes to extend base class vs "normal" extension of a base class


I'm new to the Oxid framework, which makes an extensive use of transparent parent classes to extend a base class. I don't see the advantage of this technique. So I'm curious, is this a pattern? Where are the benefits?

Cheers, Kathrin

Example code:

\\ a class by the framework I like to extend
class A { ... }

Than the common way of extending this class by the Framework:

class B extend class B_parent

Where B_parent is class created by the framework via a config file, which looks like:

'extend'    => array(
        'A'    => 'path_to/B')

Solution

  • This is not a specific known design pattern, it is a functionality made especially for oxid. Classes in Oxid are instantiated not with "new" but instead by a factory, for example oxnew("oxarticle"). If no registered modules are present for oxarticle, the factory just returns an instance of oxarticle.

    When a module has registered "myOxarticle" as an extension to oxarticle, oxnew("oxarticle") would return a myOxarticle instance, and myOxarticle would be extended from oxarticle. This class chain is built by the factory. That's the first benefit, imagine you had used "myOxarticle extends oxarticle", you would have to change all places that use oxarticle so that your object is used instead of oxarticle. Now with the transparent class chain, the factory takes care of this, your new functionality is now used everywhere an oxarticle object is used. The places that call oxnew("oxarticle") do not need to know about your new object.

    The second advantage is when there are several modules that extend the same Oxid class, and even the same method. The factory builds a class chain in the background, and oxnew("oxarticle") returns an instance of the last class in the chain. It is good practice that if you extend a class, you call the parent method in all your methods. So each method of all the module classes gets executed if a certain method of the base class is called, and each of the modules does not need to know about the other modules.

    Another way of extending functionality would be the use of hooks or filters. The disadvantage of hooks is that they have to be built into every method that could possibly be extended, and even then the oxid way is more flexible.

    There might be some reasons that prevent you from calling a parent method in your class methods, for example if the parent method does something that you do not want to happen. In this case, this breaks the independence between modules, and should be done only if no other way is possible.

    If you do not want to change existing behaviour but instead want to make up your own class that is used only by your module, for example a new page controller, there is the "files" array in metadata, which only registers your class in the autoloader, in this case you would use for example "mycontroller extends oxubase" and not "mycontroller extends mycontroller_parent".