Interface Inheritance Use Case examples

Posted by Tim Kuehn on 26-Jan-2015 20:40

I'm researching what the use and anti-use cases are for interface inheritance. 

So far all the material I've found so far talks about the generic technical aspects - I'm looking for "they're good for X situations, and bad for Y situations"
Any pointers people care to share would be appreciated. :) 

All Replies

Posted by Matt Baker on 26-Jan-2015 22:03

You need to think of types as a set of restrictions that you use to model some aspect of your system.  Once you start thinking that way, your question goes away.

Take javascript for example.  It has no types, but it has objects.  So with javascript there are no restrictions so you can add any method and any variable to any object.  But you only add things that you need to accomplish some task.  The exact opposite of strongly typed language where you can only do what the class implements.

Interface inheritance is useful to a avoid some extra casting in some situations or to use as markers.  If your system you have modeled doesn't need them, don't use them.  If it makes sense, then use them.  It comes down to how you have structured your classes.

One last point though.  Generally composition is preferred over inheritance for more complex systems so the more interfaces each class implements the less composition is implied.  So keep your classes as small as they need to be and make sure your interface model is accurate for your system.

Posted by Tim Kuehn on 26-Jan-2015 22:33

[quote user="Matt Baker"]

You need to think of types as a set of restrictions that you use to model some aspect of your system.  Once you start thinking that way, your question goes away.
[/quote]

I'm looking for actual examples for what I'm working on, so the question remains. 

[quote user="Matt Baker"]

Interface inheritance is useful to a avoid some extra casting in some situations or to use as markers.  If your system you have modeled doesn't need them, don't use them.  If it makes sense, then use them.  It comes down to how you have structured your classes. [/quote]

Examples of where Interface Inheritance is appropriate is what I'm looking for. 

[quote user="Matt Baker"] One last point though.  Generally composition is preferred over inheritance for more complex systems so the more interfaces each class implements the less composition is implied.  So keep your classes as small as they need to be and make sure your interface model is accurate for your system.[/quote]

That's a given. What I'm working on is some docs for Interface Inheritance and I need some concrete examples of where it's appropriate to use. 

Posted by Mike Fechner on 26-Jan-2015 22:53

Do we get named in your manual? :-)

Consider a parameter to a method that needs to support a generic high level interface like ISerializable (which could be implemented by inheriting from JsonSerialzable or XmlSerializable or what ever).

But the method also needs to know that the parameter instance passed in has propertiesrequired for the subject matter.

That's where IThisSpecificMethodParameter inherits ISerializable in our framework. Saves the additional TYPE-OF and CAST to get access to the members of both interfaces.

Von meinem Windows Phone gesendet

Von: Tim Kuehn
Gesendet: ‎27.‎01.‎2015 06:33
An: TU.OE.Development@community.progress.com
Betreff: RE: [Technical Users - OE Development] Interface Inheritance Use Case examples

Reply by Tim Kuehn

Matt Baker

You need to think of types as a set of restrictions that you use to model some aspect of your system.  Once you start thinking that way, your question goes away.

I'm looking for actual examples for what I'm working on, so the question remains. 

Matt Baker

Interface inheritance is useful to a avoid some extra casting in some situations or to use as markers.  If your system you have modeled doesn't need them, don't use them.  If it makes sense, then use them.  It comes down to how you have structured your classes. 

Examples of where Interface Inheritance is appropriate is what I'm looking for. 

Matt Baker
One last point though.  Generally composition is preferred over inheritance for more complex systems so the more interfaces each class implements the less composition is implied.  So keep your classes as small as they need to be and make sure your interface model is accurate for your system.

That's a given. What I'm working on is some docs for Interface Inheritance and I need some concrete examples of where it's appropriate to use. 

Stop receiving emails on this subject.

Flag this post as spam/abuse.

Posted by mbanks on 27-Jan-2015 08:07

One example I can think of would be something like collections.  You may want to have many implementations of collections, but there may also be subgroups of collections that share some behavior.

So, for example, a List interface may extend a Collection interface.  Similarly, you may have other interfaces that extend Collection like Set, Map, Queue.  For each one of those derived interfaces, you may have any number of implementations.  By implementing the List interface, a concrete class LinkedList could be both a Collection and a List.

I think the key to designing a hierarchy like that is to decide for example if List "is a" Collection and that all Lists will always be Collections.  Otherwise, I agree with Matt, it's almost always better to use composition.

Posted by Matt Baker on 27-Jan-2015 08:14

The classic shape or animal examples would be appropriate.

Something like:

Dog interface inherits from Animal interface and LeggedCreature interface

Elephant interface also inherits from Animal but also implements implements LeggedCreature and TrunkedCreature interface, but dog doesn't get TrunkedCreature

Posted by Tim Kuehn on 27-Jan-2015 08:14

[quote user="Mike Fechner"]

Do we get named in your manual? :-)[/quote] 
It's quite possible! 

[quote user="Mike Fechner"]

Consider a parameter to a method that needs to support a generic high level interface like ISerializable (which could be implemented by inheriting from JsonSerialzable or XmlSerializable or what ever).

But the method also needs to know that the parameter instance passed in has propertiesrequired for the subject matter.

That's where IThisSpecificMethodParameter inherits ISerializable in our framework. Saves the additional TYPE-OF and CAST to get access to the members of both interfaces.

[/quote]

So in effect your inherting the "serializable" interface and combining it with the interface for the current class, which saves you from having to do un-needed CAST() and TYPE-OF()s elsewhere. Correct? 

Posted by mbanks on 27-Jan-2015 08:21

I don’t think it’s quite a matter of avoiding CAST and TYPE-OF.  It’s more that by saying JsonSerializable extends ISerializable you are saying that anything that is JsonSerializable is always ISerializable.  You are enforcing the idea that you can’t have a JsonSerializable object that is not ISerializable.
 
[collapse]
From: Tim Kuehn [mailto:bounce-timk519@community.progress.com]
Sent: Tuesday, January 27, 2015 9:16 AM
To: TU.OE.Development@community.progress.com
Subject: RE: [Technical Users - OE Development] Interface Inheritance Use Case examples
 
Reply by Tim Kuehn
Mike Fechner
Do we get named in your manual? :-)
 
It's quite possible! 
Mike Fechner
Consider a parameter to a method that needs to support a generic high level interface like ISerializable (which could be implemented by inheriting from JsonSerialzable or XmlSerializable or what ever).

But the method also needs to know that the parameter instance passed in has propertiesrequired for the subject matter.

That's where IThisSpecificMethodParameter inherits ISerializable in our framework. Saves the additional TYPE-OF and CAST to get access to the members of both interfaces.

So in effect your inherting the "serializable" interface and combining it with the interface for the current class, which saves you from having to do un-needed CAST() and TYPE-OF()s elsewhere. Correct? 

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse]

Posted by Mike Fechner on 27-Jan-2015 09:05

“So in effect your inherting the "serializable" interface and combining it with the interface for the current class, which saves you from having to do un-needed CAST() and TYPE-OF()s elsewhere. Correct?“

There’s a little more to it.

I express the expectation that the objects implement both interfaces – the base interface and the inheriting interface.

In menu maintenance, for storing a menu function object in the DB, the StoreMenuItem method needs to know, that the object is ISerializable (for technical reasons) and IMenuFunction for logical reasons. When the object does not meet the requirements of both interfaces, the method cannot use it. The fact, that I don’t need the extra cast is just very convenient with the method.

Posted by Peter Judge on 27-Jan-2015 10:02

[quote user="Tim Kuehn"]

So in effect your inherting the "serializable" interface and combining it with the interface for the current class, which saves you from having to do un-needed CAST() and TYPE-OF()s elsewhere. Correct? 

[/quote]

That's quite a powerful incentive, especially given interface composition isn't really feasible. Yes, you can include members in an interface that are of another (interface) type, but that means you end up doing some fancy footwork to expose those members in the object correctly.

When you define variables  as an interface type, you /only/ see that single interface type's members, unlike when you define a variable based on a class type, where you can see public members that are part of one or more interfaces, and of the class type.

By way of example:

Lets say you have an interface IComponent, with the following definition.

interface IComponent:
  method public void Initialize().
  method public void Destroy().
end interface.

There's also an interface for Business Entities:

interface IBusinessEntity:
  method public void FetchData().
  method public void SaveData().
end interface.



The question becomes how to apply the IComponent behaviour to a BusinessEntity .

Option 1 is to have a business entity implement both interfaces:


class CustomerBE implements IBusinessEntity, IComponent:
  
  method public void Initialize().
  method public void Destroy().

  method public void FetchData().
  method public void SaveData().

end class.

Now, if you want to create and initialise a BE you have to cast() to another type.

def var oBE as IBusinessEntity.

oBE = new CustomerBE().
cast(oBE, IComponent):Initialize().


Option 2 is to have the business entity interface include the IComponent interface via composition

interface IBusinessEntity:
  define public property Component as IComponent get.
  method public void FetchData().
  method public void SaveData().
end interface.


Now the implementing BE needs to do some fancy footwork to expose it

class CustomerBE implements IBusinessEntity, IComponent:
  define public property Component as IComponent
    get():
      return this-object.
    end get.  

  method public void Initialize().
  method public void Destroy().

  method public void FetchData().
  method public void SaveData().

end class.


Not really pretty and now the  instantiating code needs to do something like

def var oBE as IBusinessEntity.

oBE = new CustomerBE().
oBE:Component:Initialize().


Option 3 is to use interface inheritance

interface IBusinessEntity inherits IComponent:
  method public void FetchData().
  method public void SaveData().
end interface.

With a simple implementation

class CustomerBE implements IBusinessEntity:
  method public void Initialize().
  method public void Destroy().

  method public void FetchData().
  method public void SaveData().

end class.




and the calling code is nice and clean too.

def var oBE as IBusinessEntity,

oBE = new CustomerBE()
oBE:Initialize().


hth,

-- peter

Posted by Tim Kuehn on 27-Jan-2015 12:19

Peter - that was epic! Thank you very much.

WRT "Option 1" - you may've answered my follow-up question, namely about the possible utility multiple interface inheritance. Using your example, I can change this:

class CustomerBE implements IBusinessEntity, IComponent

to this:

INTERFACE iCustomerBE INHERITS IBusinessEntity, IComponent.

CLASS CustomerBE IMPLEMENTS iCustomerBE:
   /* Stuff */
END CLASS.

so then I can do this: 

DEFINE VARIABLE oBE AS iCustomerBE.
oBE = NEW CustomerBE().

Which basically does the same thing as Option 3 except that it creates a 3rd interface instead of having IBusinessEntity inherit IComponent, thereby keeping all 3 interfaces separated. 

Posted by Tim Kuehn on 27-Jan-2015 12:28

So the chain would be:


Interface iSerializable: /* Stuff */ Interface JsonSerializable INHERITS iSerializable: /* Stuff */

Posted by mbanks on 27-Jan-2015 12:36

Exactly

Posted by Marian Edu on 27-Jan-2015 12:52

you've already passed to the anti-pattern now? :)

i would dare to question the use of both ICustomerBE and JsonSerializable interfaces... it looks to me there is going to only be one class implementing those specific interface so then why bother?

while interfaces are used both for parameter passing as well as holding references I never had a need to use composed interfaces to avoid extra casting... hell, if I treat an object both as a 'business object' and a 'serializable object' in the same place it means I failed to adhere to SRP - the piece of code handling that object should only do one thing so the object should be either a serializable or a business object at a time.

beside, Peter, inversion of control seemed to be something which appeals you... there is even less of a problem the mentioned extra casting, or I might be missing the point here :(

Posted by Tim Kuehn on 27-Jan-2015 13:04

On Tue, Jan 27, 2015 at 1:53 PM, Marian Edu
wrote:
> RE: Interface Inheritance Use Case examples
> Reply by Marian Edu
>
> you've already passed to the anti-pattern now? :)

How so?

> i would dare to question the use of both ICustomerBE and JsonSerializable
> interfaces... it looks to me there is going to only be one class
> implementing those specific interface so then why bother?

I expect iCustomerBE and IJsonSerializable would specify additional
class elements that are specific to their respective implementation.
Given that both these were examples given to my "what would it look
like" question, I'm not sure what your question is.

> hell, if I treat an object both as a 'business object' and a
> 'serializable object' in the same place it means I failed to adhere to SRP -
> the piece of code handling that object should only do one thing so the
> object should be either a serializable or a business object at a time.

Why shouldn't a BE be serializable? If the "serializable" interface
specified a method that was a facade to a serialize support class that
the ICustomerBE used to collect it's serialize values, then it's not
violating SRP.

I'm thinking you may be mistaking an abstraction of the API at the
interface level with actual class implementation(s).

Posted by Marian Edu on 27-Jan-2015 13:26

[quote user="Tim Kuehn"]
I expect iCustomerBE and IJsonSerializable would specify additional
class elements that are specific to their respective implementation.
Given that both these were examples given to my "what would it look
like" question, I'm not sure what your question is.
[/quote]

The question was why do you need IJsonSerializable if it's going to be only one class implementing that special serialization? Maybe the example is confusing, I'm probably expecting more serializers not objects that can be serialized in specific format.

[quote user="Tim Kuehn"]
Why shouldn't a BE be serializable? If the "serializable" interface
specified a method that was a facade to a serialize support class that
the ICustomerBE used to collect it's serialize values, then it's not
violating SRP.
[/quote]

I wasn't questioning the fact that the BE can be serializable, but BE the class not IBE the interface... one (object) can be as many things as it wants same as we can be friend, lover, husband, father, rugby player, beer drinker, developer, super mario or super man... from the outside someone will see us only as one of all those 'interfaces', at least one at a time.


But it's late, time to switch one of those interfaces off till morning :)

Posted by Tim Kuehn on 27-Jan-2015 13:41

[quote user="Marian Edu"]

The question was why do you need IJsonSerializable if it's going to be only one class implementing that special serialization? Maybe the example is confusing, I'm probably expecting more serializers not objects that can be serialized in specific format.[/quote]

Mike's example was how interface inheritance worked in his framework for serialization. I expect that IJsonSerialiable would be inherited by whatever classes had that requirement, so there'd be more than one class implementing that interface.

[quote user="Marian Edu"]

[quote user="Tim Kuehn"] Why shouldn't a BE be serializable? If the "serializable" interface specified a method that was a facade to a serialize support class that the ICustomerBE used to collect it's serialize values, then it's not violating SRP. [/quote]

I wasn't questioning the fact that the BE can be serializable, but BE the class not IBE the interface... one (object) can be as many things as it wants same as we can be friend, lover, husband, father, rugby player, beer drinker, developer, super mario or super man... from the outside someone will see us only as one of all those 'interfaces', at least one at a time[/quote]

My guess (and Mike can correct me) is that IJsonSerializable contains references to a specific class which would contain the Json serialized version of the object. Said object can be contained in the target class, and it created / populated / depopulated by the enclosing class. Once the enclosing class is done passing it's values to the Json class, then the object can be passed on to other functionality for transmission or what-have-you. 

Posted by pedrorodriguez on 27-Jan-2015 14:12

A real use case scenario I've implemented using interface inheritance was to support read-only and read-write business entities.

I think it is an obvious case where you need an interface to define a common set of methods properties and an extended interface that will support in every case all same methods with some extra of their own.

Posted by pedrorodriguez on 27-Jan-2015 14:21

[quote user="Tim Kuehn"]

Mike's example was how interface inheritance worked in his framework for serialization. I expect that IJsonSerialiable would be inherited by whatever classes had that requirement, so there'd be more than one class implementing that interface. 

[/quote]

I guess it is just a typo, but classes implements interfaces they don't inherit them, and the key point is that an interface that inherits from another interface makes sense when more than one class will implement it, otherwise that interface could perfectly be just a class implementing the parent interface.

[quote user="Tim Kuehn"] Why shouldn't a BE be serializable? If the "serializable" interface specified a method that was a facade to a serialize support class that the ICustomerBE used to collect it's serialize values, then it's not violating SRP. [/quote]

Is not about if BE can be serializable, is if an interface that defines BE and serializable makes sense, and that definition of the interface breaks the SRP principle, in the class you will end up implementing BEInterface and ISerializable, but adding a third interface that inherits from those two, just couples two independent functionalities with no further value.

Posted by Peter Judge on 27-Jan-2015 14:24

[quote user=" Marian Edu"]

you've already passed to the anti-pattern now? :)

i would dare to question the use of both ICustomerBE and JsonSerializable interfaces... it looks to me there is going to only be one class implementing those specific interface so then why bother?

[/quote]

My intent wasn't to combine the serialisable and business entity interfaces in my example

[quote user=" Marian Edu"]

beside, Peter, inversion of control seemed to be something which appeals you... there is even less of a problem the mentioned extra casting, or I might be missing the point here :(

[/quote]
 
IoC does appeal to me. But I find the TYPE-OF/CAST pattern to generally be an anti-pattern. Yes, there are times that it's unavoidable – and factory-type methods are one of those places – but I try to avoid it where possible (and that was the intent of my examples). The fact that I used  new and an Initialize() method is just a coincidence.
 
-- peter
 
[collapse]
From: Marian Edu [mailto:bounce-medu@community.progress.com]
Sent: Tuesday, 27 January, 2015 13:53
To: TU.OE.Development@community.progress.com
Subject: RE: [Technical Users - OE Development] Interface Inheritance Use Case examples
 
Reply by Marian Edu

you've already passed to the anti-pattern now? :)

i would dare to question the use of both ICustomerBE and JsonSerializable interfaces... it looks to me there is going to only be one class implementing those specific interface so then why bother?

while interfaces are used both for parameter passing as well as holding references I never had a need to use composed interfaces to avoid extra casting... hell, if I treat an object both as a 'business object' and a 'serializable object' in the same place it means I failed to adhere to SRP - the piece of code handling that object should only do one thing so the object should be either a serializable or a business object at a time.

beside, Peter, inversion of control seemed to be something which appeals you... there is even less of a problem the mentioned extra casting, or I might be missing the point here :(

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse]

Posted by Mike Fechner on 27-Jan-2015 21:23

Not quite in my world….
 
IMenuFunction needs to be ISerializable.
 
I don’t care about if it’s IXmlSerializable or IJsonSerializable or what …
 

This thread is closed