6

If we should favor composition over inheritance, the data part of it is clear, at least for me.

What I don't have a clear solution to is how overwriting methods, or simply implementing them if they are defined in a pure virtual form, should be implemented.

An obvious way is to wrap the instance representing the base-class into the instance representing the sub-class. But the major downsides of this are that if you have say 10 methods, and you want to override a single one, you still have to delegate every other methods anyway. And if there were several layers of inheritance, you have now several layers of wrapping, which becomes less and less efficient. Also, this only solve the problem of the object "client"; when another object calls the top wrapper, things happen like in inheritance. But when a method of the deepest instance, the base class, calls it's own methods that have been wrapped and modified, the wrapping has no effect: the call is performed by it's own method, instead of by the highest wrapper.

One extreme alternative that would solve those problems would be to have one instance per method. You only wrap methods that you want to overwrite, so there is no pointless delegation. But now you end up with an incredible amount of classes and object instance, which will have a negative effect on memory usage, and this will require a lot more coding too.

So, are there alternatives (preferably alternatives that can be used in Java), that:

  • Do not result in many levels of pointless delegation without any changes.
  • Make sure that not only the client of an object, but also all the code of the object itself, is aware of which implementation of method should be called.
  • Does not result in an explosion of classes and instances.
  • Ideally puts the extra memory overhead that is required at the "class"/"particular composition" level (static if you will), rather than having every object pay the memory overhead of composition.

My feeling tells me that the instance representing the base class should be at the "top" of the stack/layers so it receives calls directly, and can process them directly too if they are not overwritten. But I don't know how to do it that way.

[EDIT] It seems that many people reading this question think that I am debating if I should use Composition or Inheritance, and that "guiding" me to the one or the other will solve my problem. This is not the case. I always use inheritance when I can, for the simple fact that composition requires more coding, and also more memory. No need to convince me that inheritance is not evil.

I have a very good reason to want to use composition. I want to create a system that model domain objects that can "change nature" over time. That is they can both gain and loose functionality/properties over time, as a result of some actions. This is a lot more natural when modeled as composition.

If the components that can be dynamically added and removed where composed only of properties, it would be easy. In fact I have already found 14 different possible designs that support that case, with varying compromise on code complexity, memory usage, and speed.

The real problem comes when all those components need to be aware of each other, and talk to each other. This is not required when they are just "beans" (in the Java sense). I want to know if there are any, and hopefully several, ways of allowing the components to talk to each other, and more specifically how to have several components of the same type, where one serves as base-class and the others progressively override some of it's methods.

I can see two ways to simulate the overriding present in inheritance.

The first is to have a base component, and all overriding components are built as wrapper on top of another component of the same type. Like that, you can choose at runtime which hierarchy of components you want. This is like pipes and filters. But the problem is that with inheritance, not only can the derived class call methods of the base class, but it works the other way around too. A base class can declare a pure virtual method, which is implemented by the sub-class, and the base class can call this method. I don't see how to accomplish that using whole component wrapping. Also, if we have N inheritance/wrapping layers, then calls to method of the base component then gets N level of delegation, even if the method was not overwritten by any of the wrapping components.

The other alternative, like I said in "One extreme alternative ...", is to do it like above, but forcing each component to contain a single method. In that case we solve the problem of the base-class not seeing/calling the methods of the derived classes, for all methods, except it's own method. So it works now correctly for all cases except for recursion. But the price we pay in memory consumption is high, at least in Java. And Java isn't "functional", so there is a lot of syntax overhead to turn every object method into an individual object.

If there any better alternatives then the two mentioned above, I would like to know about it.

8
  • 3
    It's a bit of an oversimplification to say "composition good, inheritance bad". Inheritance is in fact the preferred method when dealing with "is a" relationships. Composition is meant for "has a" relationships. The trick is determining which relationships are "is a" and which are "has a". For example, at a school would student and teacher be subclasses of person, or would teacher and student be roles that a person could take on?
    – GordonM
    May 31, 2012 at 12:33
  • @GordonM You don't need to convince me. I prefer inheritance, but for the problem I am trying to solve, (changing the type of an object at runtime), it just doesn't cut it. May 31, 2012 at 16:13
  • 3
    Why use Java for a problem it is completely unsuited for? This can be done easily in dynamic languages like Groovy, Ruby, Javascript, LUA, Python, Perl, et. al. Why implement a crappy dynamic language in Java instead of just starting with a dynamic language? May 31, 2012 at 20:35
  • 5
    You've managed to ask a very abstract question here; it's very hard to see exactly where you're going with it. My general take is “use both composition and inheritance, as appropriate”. May 31, 2012 at 20:42
  • @kevincline +1 You have a good point there. If I have to pay a lot in performance and memory to implement this, I may as well use a dynamic language that makes it easy to do. May 31, 2012 at 21:29

7 Answers 7

16

"favor composition over inheritance" doesn't mean never use inheritance, but just don't use inheritance when composition will work. IMO, the need of overwriting justifies the use of inheritance.

4
  • 1
    I see that this is not getting me anywhere. Please look at my comment to @GordonM . I have no choice. May 31, 2012 at 16:15
  • 5
    @SebastienDiot, may I suggest you ask a new question in terms of the problem you are trying to solve and not in terms of the issues you have with your current solution? You are spreading bits of information in your question and your comments and it is difficult to get a clear idea of the big picture. May 31, 2012 at 17:02
  • 1
    I do not agree with you. My question was not a debate about whether to prefer composition over inheritance, or the other way around, as you seem to have taken it. There are several other questions like that out there, most of which got negative votes. I have already chosen composition, and I am not ready to discuss this choice. I want to know how to solve, using composition, the problems that inheritance normally solve, and that is exactly what I have asked. No need for a different question. May 31, 2012 at 18:36
  • I have seen object systems that were strictly composition only. They worked very well for a lot of practical uses, but really struggled when dealing with true is-a relationships. OTOH, a lot of (noob) programmers seem to feel that inheritance is how you compose things… May 31, 2012 at 20:14
4

A way to reduce the memory overhead of your second solution is to add one level of indirection and push the behavior in an object which would be shared by all the objects which share the same behavior (more or less like prototype based language behaves). As you seem to want a very dynamic behavior, finding it could be difficult if the objects have to make evolve their behavior independently.

class Composed { 
public:
    void foo() { proto->foo(this); } // with a proto member, less overhead per call, maintaining it could be hard
    void bar() { protos[state]->bar(this); } // with a static map allowing to decode a state member
    void qux() { findProto(this)->qux(this); } // find it however you want
    // you need to handle the data part
};
2
  • 1
    +1 This is what I'm trying to "formalize" atm. I have to first define a bunch of test-cases to see if all corner cases are supported. BTW: I didn't know the same person could give several answers to the same question! Jun 1, 2012 at 10:42
  • I think my own answer goes in the direction you proposed. It just goes into more details by giving a complete working example. Jun 2, 2012 at 9:33
3

If you're composing your data, why not also compose your methods? Many languages have a notion of a function as an object, or a function pointer. Your composition target could have methods which are defined as properties and these could be recomposed as you see fit. Here's an example in my primary language, C#:

public class ComposedClass
{
    public Func<string, string> Format { get; set; }

    public ComposedClass()
    {
        Format = s => s.ToUpper();
    }
}

This class has a default implementation of Format which will convert the string to upper case. We could provide an alternative implementation which does something else.

[TestFixture]
public class Tests
{
    [Test]
    public void Default_implementation_returns_FOO()
    {
        var composedObj = new ComposedClass();

        var result = composedObj.Format("Foo");

        Assert.That(result, Is.EqualTo("FOO"));
    }

    [Test]
    public void Alternative_implementation_returns_foo()
    {
        var composedObj = new ComposedClass();
        composedObj.Format = (string s) => s.ToLower();

        var result = composedObj.Format("Foo");

        Assert.That(result, Is.EqualTo("foo"));
    }
}

You would have to implement appropriate guards around set_Format of course, and you would have to explicitly pass around an alternative to this if it is required.

It's worth pointing out that in reality, I would probably do what @AProgrammer is suggesting, and use inheritance anyway, but since you asked what are the alternatives, here is an alternative!

5
  • I'm sorry that I don't know the equivalent of Func<...> in Java. It's been a long time since I looked at that class library. I think this approach would be a piece of cake in Scala though. May 31, 2012 at 12:09
  • What you suggest is what I meant by "One extreme alternative that would ..." I know that it is possible and would work, but it would probably (in the case of Java) multiply the whole memory footprint by at least 4 times. A Java int is 4 bytes, a java.lang.Integer (the object form of an int), plus reference is at least 20 bytes in 64 bits, if I get it right. That is the main downside. Memory is cheap, but not that cheap. May 31, 2012 at 16:22
  • Yeah, true enough. I wouldn't worry about the computer's memory though (unless you're in a mobile or other embedded environment) - that's what the garbage collector is for. My main worry would be the memory of the maintenance programmer that follows you - without delegates, he could have lots of single-method classes to understand. May 31, 2012 at 20:18
  • +1, really neat trick when you need to have a sometimes composable class or a pluggable implemetation May 31, 2012 at 23:15
  • Inject the delegate as a constructor argument and you have the canonical functional way of implementing "strategies" (a concept that doesn't even have a "pattern" name in FP because it's such a fundamental trivial thing to do. I think this is way cleaner, more succinct, more understandable and easier to maintain than having a bunch of one-method interfaces. Of course, in pure FP you wouldn't have a class at all, you'd probably just compose functions.
    – sara
    May 8, 2016 at 10:40
1

Consider using a dynamic language (e.g. Python) instead of Java, if possible. That way you get the dynamic language and its features from the beginning, instead of having to implement it yourself.

1

Delegation

Its very used in Java in the Streams classes, but , applies to other programming languages, and frameworks, as well.

In the following "dummy" example, there are several interfaces, and several classes that support those interfaces.

One of that clases, its composed by another classes, delegates their functuonality, by using their composite fields methods.

public interface StreamInterface
{
  bool canRead();
  bool canWrite();
  bool canSeek();
}

public interface ReaderInterface extends StreamInterface
{
  void read(byte[] Buffer, int MaxSize);
}

public interface WriterInterface extends StreamInterface
{
  void write(byte[] Buffer, int MaxSize);
}

public class ReaderClass extends ReaderInterface
{    
  bool canRead() { ... }
  bool canWrite() { ... }
  bool canSeek() { ... }

  void read(byte[] Buffer, int MaxSize) { ... }
} // class ReaderClass

public class WriterClass extends WriterInterface
{    
  bool canRead() { ... }
  bool canWrite() { ... }
  bool canSeek() { ... }

  void write(byte[] Buffer, int MaxSize) { ... }
} // class WriterClass

public class ReaderWriterStreamClass
  extends
    ReaderInterface,
    WriterInterface
{
  public ReaderInterface Reader;
  public WriterInterface Writer;

  void read(byte[] Buffer, int MaxSize)
  {
     Reader.read(Buffer, MaxSize);
  }

  void write(byte[] Buffer, int MaxSize)
  {
     Writer.write(Buffer, MaxSize);
  }    
} // class ReaderWriterStreamClass

In this example, we can use "ReaderClass" & "WriterClass", to support the required methods, but, can also be replaced by other classes.

Cheers.

0

I have come to a working example that shows the properties I desired from the solution. It is somewhat unwieldy, but that is always the case in static languages when using composition to do what inheritance was made for (IMO).

The idea is that you simulate a virtual dispatch table using a singleton class instance, where you have one field per method, pointing to the domain interface. So you can set each field of the VDT to a different implementation if you want, and the implementations are decoupled. And in your real object, you just need one extra reference to that VDT, which is immutable and shared by all your instances.

Here is the code example

5
  • Why didn't you just use a dynamic language? I apologize if this seems like an unproductive comment... but it really seems like you put a lot of work into something that is solved in other languages.
    – SpykeBytes
    Apr 7, 2016 at 1:53
  • In the end, I haven't pursued this line of thought, because it was too much trouble, and staid with traditional inheritance. My reason for staying with Java is simply "laziness"; changing language means changing your technological stack, starting from scratch, kind of like moving country, something that I would try hard to avoid (after having done it once). Apr 7, 2016 at 14:31
  • Can't you call Scala from Java?
    – SpykeBytes
    Apr 8, 2016 at 19:46
  • Of course I can, but Scala is not a dynamic language. :D Also significant in my decision to stay with Java was that I wanted (eventually) that others (specifically, non-professional programmers) be able to contribute. And the barrier to entry for languages like Scala or Clojure .., is just too high. While the mechanic in the example I linked is unwieldy, most of that would be generated automatically by annotation processors. Apr 9, 2016 at 13:01
  • Finally, I'm not into dynamic languages, because when I'm in my IDE, and I have an object, and press "." after it, I want to be shown all things that object has to offer, and nothing else. That is not possible with dynamic languages, because you simply cannot know for sure what the object even is, and that just ruins it for me. Apr 9, 2016 at 13:01
0

Have one or more optional delegate properties in the base class, then have it call the delegate's method from the base method, if present and where applied. Simplistic code in ECMAScript (can be translated to most modern languages):

class BaseClass {
    method() {
        // optional code before

        if (this.delegate) {
            this.delegate.method();
        }

        // optional code after
    }
};

With this approach, you'll have the option to dynamically plug any kind of delegate to instances of the base class.

You can even have code in the base class' own method, regardless of what the delegate does after/before. This can have its own advantages as opposed to having each method that overrides the base class' method calling super() when using inheritance.

For more sample code that use this technique, please refer to this source code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.