Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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.

share|improve this question
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 '12 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. –  Sebastien Diot May 31 '12 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? –  kevin cline May 31 '12 at 20:35
4  
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”. –  Donal Fellows May 31 '12 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. –  Sebastien Diot May 31 '12 at 21:29
show 3 more comments

6 Answers

up vote 0 down vote accepted

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

share|improve this answer
add comment

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.

share|improve this answer
add comment

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.

share|improve this answer
add comment

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
};
share|improve this answer
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! –  Sebastien Diot Jun 1 '12 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. –  Sebastien Diot Jun 2 '12 at 9:33
add comment

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!

share|improve this answer
    
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. –  Damian Powell May 31 '12 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. –  Sebastien Diot May 31 '12 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. –  Damian Powell May 31 '12 at 20:18
    
+1, really neat trick when you need to have a sometimes composable class or a pluggable implemetation –  Wyatt Barnett May 31 '12 at 23:15
add comment

"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.

share|improve this answer
1  
I see that this is not getting me anywhere. Please look at my comment to @GordonM . I have no choice. –  Sebastien Diot May 31 '12 at 16:15
4  
@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. –  AProgrammer May 31 '12 at 17:02
    
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. –  Sebastien Diot May 31 '12 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… –  Donal Fellows May 31 '12 at 20:14
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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