Sunday, August 9, 2009

Favor composition over inheritance

There is a software design principle that states “Favor composition over inheritance

Inheritance is a cool way to change behavior. But we know that it's brittle, because the subclass can easily make assumptions about the context in which a method it overrides is getting called. There's a tight coupling between the base class and the subclass, because of the implicit context in which the subclass code I plug in will be called. Composition has a nicer property. The coupling is reduced by just having some smaller things you plug into something bigger, and the bigger object just calls the smaller object back. From an API point of view defining that a method can be overridden is a stronger commitment than defining that a method can be called.

That Principe my friends is valid for Xaf also. So overriding other controllers should be considered a bad practice and your controllers should be design to expose all functionality needed to be able to be composed by a statement like this

protected override void OnActivated()
{
    base.OnActivated();
    Frame.GetController<MyController>().MyCustomEvent+= (sender, args) => DoSomething(args);
}

form any other controller thus achieving all the above.

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

4 comments:

  1. Tolis, what about memory leaks? When you perform a generic delegate with LAMBDA on Activated for an event, you cannot unsubscribe from the event on Deactivated which will not be collected by the GC. Have you tested this for memory leaks?

    ReplyDelete
  2. Gary,

    thnks for correcting me, although my point here was the design pattern the code should be better written like

    protected override void OnActivated()
    {
    base.OnActivated();

    MyCustomEventDelegateType activated = (sender, args) => DoSomething(args);
    var controller = Frame.GetController<MyController>();
    controller.MyCustomEvent += activated;
    controller.MyCustomEvent -= activated;

    }

    ReplyDelete
  3. I find that this guideline is better understood after you've run into a real situation where inheritance has shown its limitations, as you've said. I'm glad to see you've used a real-world example.

    ReplyDelete
  4. Eric I do not know if you saw http://apobekiaris.blogspot.com/search/label/ModelArtifactState. That module looses some of its power when inheritance is used. That is more real world

    ReplyDelete