Shuffling methods

I’m writing some quite complicated class structure in PHP, and I have realised there’s one feature I am missing in PHP – I need to be able to define an interface with default method implementation. Why not class? But of course because I can not inherit two classes. And I don’t really want multiple inheritance with all its problems – I want something much more restricted. Let’s see an example.

Let’s say I am definining interface “Kickable” having method kickMe, which describes an object that can be kicked. Most of the kickable classes would have this wonderful code:

function kickMe() {
    echo "Oy-vey!";
}
?>

So if I have 20 classes which are kickable, I’d probably have to write this 18 times (2 classes would say something different when kicked). This is boring. I’d want somehow to say “OK, here’s a function, here’s the default, if you want – reimplement it”. If you ask what happens when I define two interfaces with defaults for kickMe – well, then either it would be an error or the latest implemented would win. It is not worse than having to implement two interfaces with same function names and different semantics anyway, and that is supported right now.

Alternatively, another approach would work – if I could “steal” a method implementation from a brother class (or, more nicely, delegate my function to it). I.e., suppose I have the 18 classes mentioned above, and I define the function once and in other classes I say something like:

function kickMe same as DefaultKicker::kickMe;

That would be fun – I can write much less code and additionally if I’d want to internationalize it so it could say “Oh my!” and “O-la-la!” – I could do it just once.

There are ways to do it now – I can shuffle functions with runkit, but that’s runtime – not nice (and runkit is not in default PHP anyway). I could also implement the default behaviour separately and call it on need – which would solve the consistency problem, but would solve the boredom problem only partially and would not solve the problem that external implementation couldn’t access protected class data.

I could probably use some design pattern to do it, but I didn’t find anything that does exactly that (decorator looks similar, but it assembles at runtime, and I need design-time).

14 thoughts on “Shuffling methods

  1. I too know it as the strategy pattern…
    but i should have read the comments before I bothered writing the code:

    _kicker = $kicker;
    }

    public function getKicker()
    {
    return $this->_kicker;
    }

    public function kickMe()
    {
    $this->getKicker()->kick();
    }
    }

    interface KickStrategy
    {
    public function kick();
    }

    class StandardKick implements KickStrategy
    {
    public function kick()
    {
    echo 'Oy-vey!';
    }
    }

    class FrenchKick implements KickStrategy
    {
    public function kick()
    {
    echo 'Oh-la-la!';
    }
    }

    $stas = new KickingObject();
    $stas->setKicker(new StandardKick());
    $stas->kickMe();

  2. I think ambush commander and Roderik have the right idea with composition. It makes the class heirachy a little more complex but a lot more flexible. I don’t see why the kickables need to know about the composing class though.

    interface Kickable {
    function kickMe();
    }

    class DefaultKick implements Kickable {
    function kickMe() {
    return 'Oy-vey!';
    }
    }

    class OtherKick implements Kickable {
    function kickMe() {
    return 'Wey-Hey!';
    }
    }

    class SomeKickingClass {
    protected
    $kick_strategy;
    function __construct() {
    $this->setKickStrategy( new DefaultKick() );
    }
    protected function setKickStrategy( Kickable $kick_strategy ) {
    $this->kick_strategy = $kick_strategy;
    }
    function kickMe() {
    return $this->kick_strategy->kickMe();
    }
    }

    As mentioned above this is sometimes known as the delegate pattern, I know it as the strategy pattern.

  3. I believe this is usually solved by using the delegate pattern. Ok, you still have to write the function and call the delegate from within, but at least you don’t have any functional code duplication.

  4. An option that doesn’t solve the problem of no multiple inheritance, but is still useful is to create an abstract class either as a replacement for your interface or as a supplement to it.


    abstract class Kickable
    {
    function kickMe() { /* default implementation */ }

    //You also have the option of a necessary function
    //without implementation (similar to interfaces)
    abstract function puntMe();
    }

    Something like that can be used to replace an interface and gives you the ability to provide default implementations of certain or all functions, but obviously at the expense of requiring you to subclass the abstract.

    Another common technique is to supplement your interface with an abstract. In the following example we keep the Kickable interface but also provide an abstract. This gives the users of this interface / abstract combination the option of either using an interface (perhaps when they are already extending another class or when they are overriding all default implementation anyway) or using the abstract and saving themselves the duplication of default code.


    abstract class KickableAbstract implements Kickable
    {
    function kickMe() { /* default implementation */ }
    }

    I first encountered this type of convention (An abstract supplementing an interface) in JAVA.

  5. PHP doesn’t have multiple inheritance, and anyway I don’t actually want it, because then all behavioral classes then would inherit base object class that has quite a lot of data and behavior that would lead to usual diamond-shape inheritance problems.

    Moving up is possible, but not desired – basic infrastructure classes should be static, and if we move Kickable up into infrastructure class and tomorrow we have also Squeezable and Pushable – we’d pollute top classes with ton of stuff that they do not need to care about.

    I agree that using mix-ins may lead to weird code – but then again, some designs have to be more complex than others, because underlying concepts are more complex.

  6. Do you have any other (maybe slightly more involved) examples of why you couldn’t just move the common function up the class hierarchy? I don’t see why multiple inheritance, weird interface hacks, or mix-in would be preferred in this kind of situation.

    Mix-in is kind of a interesting concept but it really makes it even more of a pain in the neck to figure out other people’s code😛.

  7. Well, it’s easy to say “you really need to re-evaluate your design”, but it won’t help much. I’m pretty sure the design is OK, and actually it works, only I’d have to reimplement same behavior in a ton of classes because if I have two or three such “interfaces with defaults” – i.e., some interfaces for which most implementors would do the same. I could probably go with composition as described above but I don’t like it – there’s no actual composition there, it’s clearly behavioral aspect only, and with composition it’s also harder to check if the class/object actually supports certain behavior (no instanceof for composition).

    As for Javascript, all OO in Javascript is basically shuffling methods as above🙂 and there’s a lot of fun about what can be done with it. It works quite well actually for JS, though doing such things in PHP would be mighty confusing probably. I don’t actually need all of that, only small portion.

  8. What you described, interfaces with default function definitions, is multiple inheritance really. When I wasn’t so up on patterns there would be plenty of times where I’d say “hmmm multiple inheritance could help here”. Now I seem to be learning more and more ways to prevent that from being the case and in the process creating more flexible designs.

    In one particular recent occasion I found I had duplication of a couple of simple methods between about 3 classes and multiple inheritance definately would have eliminated that and made the hierarchy simpler. As it was that duplication had been minimised as much as it could whilst still maintaining the identity of the classes.

    I think the limitations of OO are probably one of its greatest assets. Sure you can have friend classes and multiple inhertance and all that but the times when these things should be used are few and their presence would encourage you to use them when in fact what you really need to do is re-evaulate your design.

    The thing that interests me is EMCAScript (JS and ActionScript), which seems to throw that idea in my face by allowing all kinds of things. For instance you can dynamically assign new methods to objects, perform selective multiple inheritance and call methods in the scope of other things. For this reason I’ve always wanted to explore JS more and see what the implication of such a language really is.

  9. Actually, __get wouldn’t help you very much, since you’re looking for a compile way of achieving this.

    Here’s a different way of looking at the problem: instead of trying to mix-in the Kickable behavior into the main object, the main object is composed of actions which it can do, one of which is Kickable. Instead of inheritance, you use composition to achieve the same effect, and Kickable could have its own class hierarchy for the customized behavior (further promoting reusability). The problem of accessing protected class data would be a bugger, since PHP doesn’t have friend classes, so I’d go with reflection or dedicated “private” accessors (forces you to figure out which protected attributes Kickable depends on, further formalizing dependencies).

    Anyway, decorator’s not right for the job, because it’s not supposed to change the interface, just enhance the functionality.

Comments are closed.