March 02, 2007

Multiple Interface Implementation via Proxy

Nemerle is like C# in that it only has single implementation inheritance and multiple interface inheritance. However when modelling business problems it would be beneficial to have multiple implementation inheritance to allow for better code reuse and modularisation.
For example, consider a PurchaseOrder object. We would like to add rich UI data binding functionality and undo/redo operations to it. The .NET framework contains a number of interfaces that should be implemented to achieve these goals. IEditableObject has methods BeginEdit, EndEdit and CancelEdit. INotifyPropertyChanged has an event PropertyChanged. The implementation of these is fairly standard so we do not want to write it in each class. In C#, we would usually make some kind of abstract base class that implements the interfaces and then inherit our real business classes from that.
Whilst this approach is fine for simple object models, things get a lot more difficult when not all business classes require all interfaces. Maybe some are read-only; maybe others have special auditing requirements. We end up creating many strange abstract base classes that implement different subsets of functionality. This inevitably leads to repeated code and a maintenance nightmare.
If we step back, we realise that we are actually abusing inheritance as an attempt to reduce code repetition. A better approach would be to have implementations of single interfaces as single classes that are then pulled together by the actual business classes. The business classes are then in charge of what implementations they require, rather than relying on a rather fragile base class.
The following Nemerle code demonstrates how this might work:

class PurchaseOrder : IEditableObject
    private _editableObject : IEditableObject
    public this()
        _editableObject = EditableObjectImplementation(this)
    public BeginEdit() : void
        _editableObject.BeginEdit()
    public EndEdit() : void
        _editableObject.EndEdit()
    public CancelEdit() : void
        _editableObject.CancelEdit()

The constructor creates and instance of some implementation class. Any calls to the interfaces methods are forwarded to the implementation class. Note that we provide the implementation class with the object that is using it. This allows the implementation class to do things like reflection to get all the private state to be saved.
Basically, we are implementing a form of the Proxy design pattern.
The above idea will work fine (even in C# and VB.NET), however it requires lots of “glue” code to be written. This is where Nemerle macros come in handy!
Imagine being able to write something like:

class PurchaseOrder \
    use EditableObjectImplemenation for IEditableObject \
    use NotifyPropChangedImpl for INotifyPropertyChanged
{
// Look! No glue code at all now!
}

The “use” macro would expand out to code that includes private instance fields and the glue code that calls those instances.
Of course, the macros have to be quite smart, but there are already working Proxy macros for Nemerle that just need enhancing to support events (they already do properties and methods I believe).
Other enhancements allow an implementation class to place demands on the class using it. An implementation of some interface ICircle could provide members like “Area”, “Circumference” and “Diameter” but require the using class to have a member “Radius”. The implementation class calls back into the using class to get Radius. It can then provide the various additional members using that value. This idea follows from the work done on Traits in OOP, the difference here is that implementation are not mixed into the using class at compile time. By keeping them outside, they can do useful things like have their own state.

The benefits of such infrastructure are:
  • Classes are more logically decomposed.
  • Classes are less fragile.
  • Maintenance is easier.
  • Testing business classes by providing stub implementation is easy.

- No comments Not publicly viewable


Add a comment

You are not allowed to comment on this entry as it has restricted commenting permissions.

Trackbacks

Google Ads

Search this blog

Most recent comments

  • I scratched my eye while i was holding some kind of plastic packaging.. Anyways the corner of the pl… by Ercan on this entry
  • About a year ago my contacts that i was wearing, i guess were fautly, because shortly after they wer… by Jon on this entry
  • I got shower gel in my eye 4 and a half days ago, and becasue i rubbed my eyes a lot, i have scratch… by Chris on this entry
  • This website may help http://www.webmd.com/eye–health/tc/Eye–Injuries–Home–Treatment by S on this entry
  • I somehow got dirt, or debris in my eye. The terrible pain sent me in a tailspin. I was afraid of sa… by Bobbi on this entry

Tags

March 2007

Mo Tu We Th Fr Sa Su
Feb |  Today  | Apr
         1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31   

Galleries

Blog archive

Loading…
Not signed in
Sign in

Powered by BlogBuilder
© MMXIV