Groups > Borland > Delphi Object Oriented design > Re: Interface inheritance




Re: Interface inheritance

Re: Interface inheritance
Tue, 4 Mar 2008 08:21:32 -0500
On Tue, 04 Mar 2008 13:46:49 +0100, Christian Kaufmann wrote:

> Now I think it's better to avoid inheritance of interfaces and if I
> need the Id() method then I just add that to the IEvent interface.
> 
> Other programmers in our company prefere to use interface inheritance
> because with this you can save some typing.
> 
> So I'm looking for arguments pro or contra interface inheritance. When
> does it make sence, when is it better to avoid and why?

I have found, more than once, that I have gone the easy route
(inheriting) and have regretted it later because I could not reuse the
interfaces somewhere else or change to a cleaner model.

You really shouldn't use inheritance because it saves typing but
because it makes sense. My rule is something along the strength of the
dependency between the two and how likely it is that I am going to
access them together. To use your examples, if I am editing an item I
am always going to combine saving the values with loading them so it
makes sense to inherit, but the saving and loading has nothing to with
the application's use of your code, or observing changes.

-- 
Marc Rohloff [TeamB]
Post Reply
Re: Interface inheritance
Tue, 04 Mar 2008 13:18:40 +000
Christian Kaufmann a écrit :

> Now I think it's better to avoid inheritance of interfaces and if I
> need the Id() method then I just add that to the IEvent interface.
> 
> Other programmers in our company prefere to use interface inheritance
> because with this you can save some typing.
> 
> So I'm looking for arguments pro or contra interface inheritance. When
> does it make sence, when is it better to avoid and why?

Interfaces describe behaviour; if behaviour A includes the elements of 
behaviour B, then A can derive from B.

e.g.

IStreamable

IBusinessRule

If all business rules are allowed to be streamable then IBusinessRule 
should derive from IStreamable; that way, by implementing the "larger"

interface, classes are required to also implement any interfaces that 
make up the overall behaviour.

However, if you state that not all business rules may be streamable then 
derivation is not appropriate.

Simpler example :

IHuman

IClever

IPerson

IPerson should inherit from IHuman because you can't have a person that 
is not human, however not all persons are clever, so derivation is not 
suitable :-)

Joanna

-- 
Joanna Carter [TeamB]
Post Reply
Re: Interface inheritance
Tue, 4 Mar 2008 13:24:00 -0500
"Christian Kaufmann" <christian.kaufmann@gmx.net> wrote in
message 
news:6ngqs3ls78jc905b7vkoq8035fh8061ujp@4ax.com...
>
>  //@@ general interface for all BO's
>  IBSItem = interface
>  end;
>
>  //@@ interface to an editable BO
>  IBSItemEditable = interface(IBSItem)
>  end;
>
>  //@@ interface to a application specific BO
>  IEvent = interface
> end;
>
> Now I think it's better to avoid inheritance of interfaces and if I
> need the Id() method then I just add that to the IEvent interface.

Then you will have Id defined in multiple interfaces.

As other have pointed out, the best criteria for deciding is whether one 
interface really needs the other interface to function - which means in 
practice that if every object that implements interface IFoo will, by 
definition, also need to implement interface IBar, then it probably makes 
sense for IFoo to inherit from IBar.

In your example, any object that is editable will, by definition, also need 
to be readable from data storage. Thus it makes sense that the writable 
interface inherit from a readable interface.

However, your readable interface currently is tied directly to your base 
business object interface. This is where I see inheritance that should be 
eliminated. I often design business objects that are not, themselves, read 
from or saved to a database but rather perform processes against other 
business objects that are.

Thus, I would suggest something more like the following (if you really want 
separate read and write interfaces):

  // basic business class interface
  IBSItem = interface
    // whatever all BOs will have *apart* from reading or writing
  end;

  // interface to read from storage
  IBSReadInterface = interface
    procedure Load;
    property ID: integer;
    // etc.
  end;

  // interface to write to storage - **inherit read interface**
  IBSWriteInterface = interface(IBSReadInterface)
    function Validate: boolean;
    procedure Save;
    // etc.
  end;

  // an actual BO interface - ** inherit from IBSItem **
  IEvent = interface(IBSItem)
  end;

Now when you implement an object, you can decide whether it is *persistable 
at all*, and if so, whether it is read-only or writable too:

    TBaseItem = class(TInterfacedObject, IBSItem)
        // implement IBSItem
    end;

    // if TEvent does not need to be read or stored
    TEvent = class(TBaseItem, IBSItem);
    end;

    // if TEvent can only be read
    TEvent = class(TBaseItem, IBSItem, IBSReadInterface);
    end;

    // if TEvent is writable
    TEvent = class(TBaseItem, IBSItem, IBSWriteInterface );
    end;

Personally, I don't see value in separate read and write interfaces, but 
rather simply whether an object is subject to storage at all. After all, if 
an object is readable from storage, it had to have been written by something 
at some time. Further, the *same* object might be writable in one 
application and read-only in another - you should not need to implement two 
separate business objects to achieve this, but rather flag an individual 
object as being read-only when appropriate (possibly an attribute set by a 
persistence layer that can be opened as read-only).

-- 
Wayne Niddery - TeamB (www.teamb.com)
Winwright, Inc. (www.winwright.ca) 
Post Reply
Interface inheritance
Tue, 04 Mar 2008 13:46:49 +010
Hi,

we use a lot of interfaces for our business objects (garbage
collection, circular references). Here are some examples:


  //@@ general interface for all BO's
  IBSItem = interface
    procedure ApplyFull(const AData: IBSColumns);
    procedure ApplyMinimal(const AData: IBSColumns);
    function Id: Integer;
    function IsNull: Boolean;
    function IsSame(const AOther: IInterface): Boolean;
    procedure Reload;
  end;


  //@@ interface to an editable BO
  IBSItemEditable = interface(IBSItem)
    function GetEditValues: IBSWritableColumns;
    procedure SetEditValues(const AValue: IBSWritableColumns);

    function Changed: Boolean;
    procedure Delete;
    property EditValues: IBSWritableColumns read GetEditValues write
SetEditValues;
    procedure Save;
  end;


  //@@ interface to a application specific BO
  IEvent = interface
    function AgeGroups: IAgeGroups;
    function BaseEvent: IEvent;
    procedure ClearResults;
    function Duration: TDateTime;
    function Id: Integer;
    function IsNull: Boolean;
    function IsSame(const AOther: IInterface): Boolean;
    function Number: String;
    function Rounds: TBSSwRounds;
    procedure Save;
    procedure UpdateAgegroups(ADefaults: IBSXmlElement);
    procedure UpdateAllHeatStatus(AStatus: TRaceStatus);
end;



Now I think it's better to avoid inheritance of interfaces and if I
need the Id() method then I just add that to the IEvent interface.

Other programmers in our company prefere to use interface inheritance
because with this you can save some typing.

So I'm looking for arguments pro or contra interface inheritance. When
does it make sence, when is it better to avoid and why?

Post Reply
Re: Interface inheritance
Tue, 4 Mar 2008 15:51:50 -0000
> Simpler example :
>
> IHuman
>
> IClever
>
> IPerson

I don't understand. 

Post Reply
<< Previous 1 2 3 Next >>
( Page 1 of 3 )
about | contact