Question


EDIT

Even though I use a pseudo-Java syntax below for illustration, this question is NOT limited to any 1 programming language. Please feel free to post an idiom or language-provided mechanism from your favorite programming language.


When attempting to reuse an existing class, Old, via composition instead of inheritance, it is very tedious to first manually create a new interface out of the existing class, and then write forwarding functions in New. The exercise becomes especially wasteful if Old has tons of public methods in it and whereas you need to override only a handful of them.

Ignoring IDE's like Eclipse that though can help with this process but still cannot reduce the resulting verbosity of code that one has to read and maintain, it would greatly help to have a couple language mechanisms to...

  1. automatically extract the public methods of Old, say, via an interfaceOf operator; and

  2. by default forward all automatically generated interface methods of Old , say, via a forwardsTo operator, to a composed instance of Old, with you only providing definitions for the handful of methods you wish to override in New.

An example:

// A hypothetical, Java-like language
class Old { 
    public void a() { }
    public void b() { }
    public void c() { }

    private void d() { }
    protected void e() { }
    // ...
}

class New implements interfaceOf Old {
    public New() {
        // This would auto-forward all Old methods to _composed
        // except the ones overridden in New.

        Old forwardsTo _composed;
    }

    // The only method of Old that is being overridden in New.
    public void b() {
        _composed.b();
    }

    private Old _composed;
}

My question is:

  1. Is this possible at the code level (say, via some reusable design pattern, or idiom), so that the result is minimal verbosity in New and classes like New?

  2. Are there any other languages where such mechanisms are provided?

EDIT

Now, I don't know these languages in detail but I'm hoping that 'Lispy' languages like Scheme, Lisp, Clojure won't disappoint here... for Lisp after all is a 'programmable programming language' (according to Paul Graham and perhaps others).

EDIT 2

I may not be the author of Old or may not want to change its source code, effectively wanting to use it as a blackbox.

Was it helpful?

Solution

This could be done in languages that allow you to specify a catch-all magic method (eg. __call() in php). You could catch any function call here that you have not specifically overriden, check if it exists in class Old and if it does, just forward the call.

Something like this:

public function __call($name, $args)
{
  if (method_exists($old, $name))
  {
    call_user_func([$obj, $name], $args);
  }
}

OTHER TIPS

First, to answer the design question in the context of "OOP" (class-oriented) languages:

If you really need to replace Old with its complete interface IOld everywhere you use it, just to make New, which implements IOld, behave like you want, then you actually should use inheritance.

If you only need a small part of IOld for New, then you should only put that part into the interface ICommon and let both Old and New implement it. In this case, you would only replace Old by ICommon where both Old and New make sense.

Second, what can Common Lisp do for you in such a case?

Common Lisp is very different from Java and other class-oriented languages.

Just a few pointers: In Common Lisp, objects are primarily used to structure and categorize data, not code. You won't find "one class per file", "one file per class", or "package names completely correspond to directory structure" here. Methods do not "belong" to classes but to generic functions whose sole responsibility it is to dispatch according to the classes of their arguments (which has the nice side effect of enabling a seamless multiple dispatch). There is multiple inheritance. There are no interfaces as such. There is a much stronger tendency to use packages for modularity instead of just organizing classes. Which symbols are exported ("public" in Java parlance) is defined per package, not per class (which would not make sense with the above obviously).

I think that your problem would either completely disappear in a Common Lisp environment because your code is not forced into a class structure, or be quite naturally solved or expressed in terms of multiple dispatch and/or (maybe multiple) inheritance.

One would need at least a complete example and large parts of the surrounding system to even attempt a translation into Common Lisp idioms. You just write code so differently that it would not make any sense to try a one-to-one translation of a few forms.

I think Go has such a mechanism, a struct can embed methods from another struct.

Take a look here. This could be what you are asking as second question.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top