Using interfaces "everywhere" due to (EMF) modelling framework

P

plmuon

Hello,

I would be very interested in your thoughts on the following:

In a large project with lots of own model classes and basetypes we are
debating to stick interfaces in front of any such class. (the
implementation language is Java, but the same could be done with
abstract classes in c++).

The reason for this is that some are using EMF, the eclipse modelling
framework, which could generate code and just demands this from any
code involved.

I would like some advice on whether it is wise to do as described
below.

Suppose we would normally have something like (pseudocode):

class Employee {...}
class Country {...}
class Position{...}

class Client {
private Country domicile;
private Position[] positions;
private Employee custumerResponsible;

public Country getDomicile() {return domicile;}
public Position[] getPositions() {return positions;}
public Employee getCustomerResponsible() {return customerResponsible;}
}


Instead we would have:

interface Employee {...}
class EmployeeImpl implements Employee {...}

interface Country {...}
class CountryImpl implements Country {...}

interface Position {...}
class PositionImpl implements Position {...}

interface Client {
public Country getDomicile() {return domicile;}
public Position[] getPositions() {return positions;}
public Employee getCustomerResponsible() {return customerResponsible;}
}

class ClientImpl extends Client {
// constructor left out

private Country domicile;
private Position[] positions;
private Employee custumerResponsible;

public Country getDomicile() {return domicile;}
public Position[] getPositions() {return positions;}
public Employee getCustomerResponsible() {return customerResponsible;}
}


So note there is no direct conection between ClientImpl and
CountryImpl e.g., everything goes via the interfaces.

Until now I am used to using interfaces on a coarser level, only to
define some kind of API and facade (and some other cases). In this
case we would have a very fine grained "facade": each and every model
class, even including base types such as Country, Currency, are
"wrapped" into interfaces and do not interact directly with each
other. As mentioned, EMF is the reason for doing this, but one might
argue that this is a good thing in itself even if not forced to do so
due to some tool such as EMF.

In my first usage of this mechanism, I found that it is quite
cumbersome. I have the feeling that I'm coming forward only at 1/10th
of my normal speed. Also when class browsing, the indirection through
all of these interfaces kind of generates a fog for me that is very
hard to see through.

I would be very interested to know your thoughts on this approach. Is
it a good thing, even becoming common practice? Is it overdesign?

A popular modelling framework EMF, the Eclipse Modelling Framework,
uses it and relies on it. If we want to allow some people in our team
to use it, we must go this way. The interfaces would have annotations
(such as @model) to pass extra information to the EMF.

I did not post this question to an eclipse (EMF) group because my
impression is that it is being used only by people that are not mainly
developing applications using modelling, but mainly by people that
have the modelling itself (e.g. to develop modelling tools) as their
core business, i.e. I have my doubts on the practicability of EMF in
real world applications.

Peter
 
C

Chris Uppal

Until now I am used to using interfaces on a coarser level, only to
define some kind of API and facade (and some other cases). In this
case we would have a very fine grained "facade": each and every model
class, even including base types such as Country, Currency, are
"wrapped" into interfaces and do not interact directly with each
other. As mentioned, EMF is the reason for doing this, but one might
argue that this is a good thing in itself even if not forced to do so
due to some tool such as EMF.

In my first usage of this mechanism, I found that it is quite
cumbersome. I have the feeling that I'm coming forward only at 1/10th
of my normal speed. Also when class browsing, the indirection through
all of these interfaces kind of generates a fog for me that is very
hard to see through.

Hmm.. I hadn't looked at EMF before. I must say that it's not the kind of
tool or approach that I think highly of. (And anything that mentions both UML
and XML on the same webpage is going to have a hard time convincing me that
it's not a mere froth from over-excited programmer's wet dreams).

But cynicism aside. I suspect that you may be taking the approach too
literally, or thinking of it the wrong way around.

Forgetting EMF for a second, the interfaces-to-everything approach has its
virtues but can be overdone. I quite like an approach where packages only
export interfaces, so all /public/ access is via interfaces. However within a
package, the classes code can (and often should) reference other
(package-private) classes directly. Note that this approach depends on how you
split the code up into packages -- that's to say the division is part of the
/design/, it's not, um, mere packaging. In essence that approach boils down
to: "(nearly) all classes should be package-private".

Now, translating that back into EMF terms. What we are saying is that EMF is
used to define the public interfaces (and the annotations can be used so that
EMF will recognise them if they already exist, or were created by
designer/programmers who don't use the EMF tools). So the intended flow goes:
first design the abstract model, which amounts to designing a bunch of
interfaces. Then implement them. What I /think/ you are doing is looking at
it the other way, and seeing it as "whenever I create a new class, I should
hide it behind an interface which it implements" -- which is not the same thing
at all ;-)

As I said earlier, I'm not an EMF guru (to say the least of it !), but I
suspect that the intended picture is that each modelled domain is rather like
an iced cake. There's a thin layer of icing around it, which is what other
people see (the interfaces), but inside it's just cake (normal, readable,
browsable, writable, code).

Idle thoughts on a Sunday morning. Take 'em for what they're worth (not
much)...

-- chris
 
H

H. S. Lahman

Responding to Plmuon...
Suppose we would normally have something like (pseudocode):

class Employee {...}
class Country {...}
class Position{...}

class Client {
private Country domicile;
private Position[] positions;
private Employee custumerResponsible;

public Country getDomicile() {return domicile;}
public Position[] getPositions() {return positions;}
public Employee getCustomerResponsible() {return customerResponsible;}
}

I know you specified pseudocode, but I would point out that the Client
class definition represents a huge difference between Java and C++
implementation. In Java 'domicile' will always be a reference and
getDomicile just navigates the relationship

? R1 1
[Client] --------------- [Country]

In C++, though, lacking a specific pointer 'domicile' would be
"hard-wired" into Client's implementation. In that case getDomicile
becomes a major no-no because it exposes the implementation of Client to
other objects. [IMO, one of the advantages of Java over C++ is that it
eliminates this sort of distinction so that domicile is always a Country
peer object.] I point this out because I think it has a bearing on your
question, albeit indirectly.
Instead we would have:

interface Employee {...}
class EmployeeImpl implements Employee {...}

interface Country {...}
class CountryImpl implements Country {...}

interface Position {...}
class PositionImpl implements Position {...}

interface Client {
public Country getDomicile() {return domicile;}
public Position[] getPositions() {return positions;}
public Employee getCustomerResponsible() {return customerResponsible;}
}

class ClientImpl extends Client {
// constructor left out

private Country domicile;
private Position[] positions;
private Employee custumerResponsible;

public Country getDomicile() {return domicile;}
public Position[] getPositions() {return positions;}
public Employee getCustomerResponsible() {return customerResponsible;}
}

Note that you have redundantly defined the implementations (i.e., the
contents of the curly brackets). My preference would be to only define
the implementations in XxxxImpl. I would then name it 'Client' and I
would name the corresponding interface 'iClient', which is a pretty
common convention.
So note there is no direct conection between ClientImpl and
CountryImpl e.g., everything goes via the interfaces.

I don't think that's the issue. If 'domicile' is just a reference to
implement relationship navigation, then there wouldn't be any dependence
anyway. Other objects that needed to collaborate with a Country object
would navigate directly to the right one by following the getDomicile
relationship path and talk directly to it. Similarly, any serious
behavior implementation for Client would do the same thing.

<aside>
Apropos of my point above, if domicile is part of Client's own
implementation, then one has a problem when other objects needs to talk
to it because they have to know that Client has that particular
implementation. That lack of implementation hiding introduces a
dependency that is potentially quite nasty. It is a subtle point and
one only gets shot in the foot in arcane situations, but one should keep
relationship navigation orthogonal to implementations.

For example, in an automatic code generator for UML, relationships are
implemented like cross-cutting aspects. That would be reflected in
rather ugly code where one would have

class ClientImpl ...
private Object* R1Ref;
...
public Object* getR1 () {return R1Ref;};
...

and the caller would cast Object* to Country*. A code generator can do
the cast safely because it knows from the Class Model exactly what is at
the end of the relationship path. (It can also write the code for
navigating the path in the caller without looking at the class
definitions along the path because of naming conventions like RnRef.)
My point here is that the relationship implementation in Client can be
completely independent of the semantics of the relevant classes. Only
client in a peer-to-peer collaboration needs to know who it is talking to.
</aside>

I think the real issue is that the interfaces just represent static
boilerplate for the convenience of EMF. IOW, there are just some extra
keystrokes in the static definitions. Note that a popular convention is
the one I mentioned above where one defines the class implementation as
'Class' and then would name the relevant interface definitions as
'iClass'. Then the working code that actually implements knowledge and
behaviors looks like your original pseudocode and the interfaces are
just boilerplate declarations around that.


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
(e-mail address removed)
Pathfinder Solutions -- Put MDA to Work
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
(888)OOA-PATH
 
A

Andrew McDonagh

H. S. Lahman said:
Responding to Plmuon...
Suppose we would normally have something like (pseudocode):

class Employee {...}
class Country {...}
class Position{...}

class Client {
private Country domicile;
private Position[] positions;
private Employee custumerResponsible;

public Country getDomicile() {return domicile;}
public Position[] getPositions() {return positions;}
public Employee getCustomerResponsible() {return
customerResponsible;}
}


I know you specified pseudocode, but I would point out that the Client
class definition represents a huge difference between Java and C++
implementation. In Java 'domicile' will always be a reference and
getDomicile just navigates the relationship

? R1 1
[Client] --------------- [Country]

In C++, though, lacking a specific pointer 'domicile' would be
"hard-wired" into Client's implementation. In that case getDomicile
becomes a major no-no because it exposes the implementation of Client to
other objects. [IMO, one of the advantages of Java over C++ is that it
eliminates this sort of distinction so that domicile is always a Country
peer object.] I point this out because I think it has a bearing on your
question, albeit indirectly.
Instead we would have:

interface Employee {...}
class EmployeeImpl implements Employee {...}

interface Country {...}
class CountryImpl implements Country {...}

interface Position {...}
class PositionImpl implements Position {...}

interface Client {
public Country getDomicile() {return domicile;}
public Position[] getPositions() {return positions;}
public Employee getCustomerResponsible() {return
customerResponsible;}
}

class ClientImpl extends Client {
// constructor left out

private Country domicile;
private Position[] positions;
private Employee custumerResponsible;

public Country getDomicile() {return domicile;}
public Position[] getPositions() {return positions;}
public Employee getCustomerResponsible() {return
customerResponsible;}
}


Note that you have redundantly defined the implementations (i.e., the
contents of the curly brackets). My preference would be to only define
the implementations in XxxxImpl. I would then name it 'Client' and I
would name the corresponding interface 'iClient', which is a pretty
common convention.

not in Java it isn't, adding Impl is pretty much standard.

And is actively discouraged elsewhere.

The 'xxxxImpl' tag isn't great, true, but removing it by tagging the
interface is just as bad.

A better example would be

interface Client

class CharitableClient
class BillableClient
etc...
 
A

Andrew McDonagh

Andrew said:
not in Java it isn't, adding Impl is pretty much standard.

And is actively discouraged elsewhere.

The 'xxxxImpl' tag isn't great, true, but removing it by tagging the
interface is just as bad.

A better example would be

interface Client

class CharitableClient
class BillableClient
etc...

Oh and Sun's own standard in Java for cases where implementations are
unknown other than the provided one, is to prefix with 'Default'

As in

DefaultTableCellRenderer implements TableCellRender
DefaultTableModel implements TableModel
etc
 
P

Patrick May

Andrew McDonagh said:
not in Java it isn't, adding Impl is pretty much standard.

And is actively discouraged elsewhere.

The 'xxxxImpl' tag isn't great, true, but removing it by tagging the
interface is just as bad.

A better example would be

interface Client

class CharitableClient
class BillableClient
etc...

Excellent point. The "*Impl" and "I*" warts are ugly, fragile,
and generally a sign that the developer hasn't given enough thought to
descriptive names. Your example shows how it should be done.

Regards,

Patrick
 
G

Greg R. Broderick

I would be very interested in your thoughts on the following:

In a large project with lots of own model classes and basetypes we are
debating to stick interfaces in front of any such class. (the
implementation language is Java, but the same could be done with
abstract classes in c++).

IMHO, interfaces are primarily useful when there are two or more of
something -- two or more concrete classes that implement the interface, or
where there can potentially be two or more of something. When there's only
one of something, and there's likely to only be one of something in the
future, an interface such as you describe is just extra overhead code that
you've got to grovel through when you go about making changes. When
there's only one of something, the class' public methods and fields _are_
its interface.


Cheers
GRB

--
---------------------------------------------------------------------
Greg R. Broderick [rot13] (e-mail address removed)

A. Top posters.
Q. What is the most annoying thing on Usenet?
---------------------------------------------------------------------
 
P

plm

Andrew McDonagh said:
not in Java it isn't, adding Impl is pretty much standard.

In fact, it is how EMF generates its code.
Once you have an EMF model (which may be generated from annotated
interfaces or also be entered through some UML tool), by default it
generates for each UML "entity":
Entity (interface)
impl.EntityImpl (implementation class)

The whole point is: we get this mechanical duplication of interface
and class (kind of redundant) because that is just the way EMF does
it. I don't really like it, but was seeking advice here to find out if
this, nowadays, is common place in the OO world or if it is just some
weirdness of EMF itself.

Of course, if hand coding classes and carefully selecting interfaces
(or abstract classes) you don't have this 1-1 relationship between any
impl-class and interface. But from the perspective of this modelling
framework, you have. I'm still doubting if we should put up with it,
for the sake of enabling some of the benefits that EMF may have (at
least to allow 1 or 2 people on our team who wish to use it). Judging
from the slowness and fog it brought me so far, I think either it is
wrong or I should accept a new way of doing things and get used to it.


Thanks for all your answers so far.

Peter
 
A

Andrew McDonagh

Greg said:
IMHO, interfaces are primarily useful when there are two or more of
something -- two or more concrete classes that implement the interface, or
where there can potentially be two or more of something. When there's only
one of something, and there's likely to only be one of something in the
future, an interface such as you describe is just extra overhead code that
you've got to grovel through when you go about making changes. When
there's only one of something, the class' public methods and fields _are_
its interface.


Cheers
GRB

I see and understand your point...

However, the primary use of an interface is to separate the 'Interface'
from the implementation. This is nothing to do with there (potentially)
being multiple implementations.

Interface separation allows much more design fluidity than direct
coupling to classes. Heck, its even the principle that used in
frameworks like Spring.
 
S

Stefan Ram

Andrew McDonagh said:
Interface separation allows much more design fluidity than
direct coupling to classes.

Skillful interface usage often does not mean, specifying a
(large) interface and implementing it by a class, but
specifying several (small) interfaces (like java.lang.Iterable
or java.lang.Comparable) and then using them for every class,
where they are appropriate.
 
S

Stefan Ram

Skillful interface usage often does not mean specifying a
(large) interface and implementing it by a class, but
specifying several (small) interfaces (like java.lang.Iterable
or java.lang.Comparable) and then using them for every class,
where they are appropriate.

And each of these (small) interfaces needs to have meaning,
i.e., its operations need to have a high cohesion, preferably
representing a single (interface) concept, preferably one
that can be communicated by a single word (term).
 
A

Andrew McDonagh

Stefan said:
Skillful interface usage often does not mean, specifying a
(large) interface and implementing it by a class, but
specifying several (small) interfaces (like java.lang.Iterable
or java.lang.Comparable) and then using them for every class,
where they are appropriate.

An excellent reminder Stefan

Google-able term 'Interface Separation Principle'
 
A

Andrew McDonagh

Thomas said:
A Java class defines an interface as well as an accompanying
implementation, just without the repetition. Client code of the class'
interface should not be relying on the particular implementation.
Agreed

Defining a Java interface for a single class just causes unnecessary
repetition.

Like all things, this depends.

For simple straight forward POJOs that are used like most POJOs, you are
spot on. E.g. String, Integer, MySimpleClass, etc...

However, (you knew there was one)...

There are times when even these singular POJOs benefit from separation
of interface from implementation - Dependency inversion, coupling
avoidance (as in when using Frameworks), Substitutability for Testing
(as in Fakes or Mocks for TDD) even though there is only one concrete
production class, etc...
 
T

Thomas Hawtin

Andrew said:
However, the primary use of an interface is to separate the 'Interface'
from the implementation. This is nothing to do with there (potentially)
being multiple implementations.

A Java class defines an interface as well as an accompanying
implementation, just without the repetition. Client code of the class'
interface should not be relying on the particular implementation.
Defining a Java interface for a single class just causes unnecessary
repetition.

Tom Hawtin
 
C

Chris Uppal

Andrew said:
Oh and Sun's own standard in Java for cases where implementations are
unknown other than the provided one, is to prefix with 'Default'

I think Sun's convention is to use the prefix 'Default' for classnames when
instances of the class in question are used by default. I.e. "this is what gets
used if you don't actively choose something else". So the prefix is meaningful
in the normal way, rather than being a "flag".

-- chris
 
E

Ed Kirwan

Chris said:
(e-mail address removed) wrote:
Forgetting EMF for a second, the interfaces-to-everything approach has its
virtues but can be overdone. I quite like an approach where packages only
export interfaces, so all /public/ access is via interfaces. However within a
package, the classes code can (and often should) reference other
(package-private) classes directly. Note that this approach depends on how you
split the code up into packages -- that's to say the division is part of the
/design/, it's not, um, mere packaging. In essence that approach boils down
to: "(nearly) all classes should be package-private".

I admire this design approach. It's a fine test of the flexibility of a
system to look at the JavaDoc (or whatever documentation that reveals
such insights) for public-only elements: if the flexibility afforded by
variance-encapsulation is considered a, "Good thing," (as GoF propose),
then seeing mostly interfaces is a good thing; seeing many times more
concrete classes than packages is a bad thing.

It's puzzling that programmers, who readily admit the value of
encapsulation on class-level, are sometimes happy to make concrete
classes unnecessarily public, thereby dismissing the value added by
package-level encapsulation.

Well, I suppose this doesn't measure actual flexibility, but potential
flexibility: a public concrete class may have no package-external
dependencies on it, and therefore not be an obstacle to flexibility -
it's just that a package-private classes are far more likely to have no
external-package dependencies on them.

Still, "(nearly) all classes should be package-private" is a fine
rule-of-thumb.
 
E

Ed Kirwan

Hello,

I would be very interested in your thoughts on the following:

In a large project with lots of own model classes and basetypes we are
debating to stick interfaces in front of any such class.

Sounds overkill to me. And I've not seen this done elsewhere.

As a matter of interest, does EMF put the interfaces which it strips
from every class into the same package in which the class is defined?

I ask as a tangent to one of Chris's responses, concerning the idea of
developing an abstract model, and then designing an implementation model
behind it. It is useful to put interfaces in packages other than the
implementation packages, as then the client is unaffected by any
redesign of the implementation model package structure; but this is
really also presuming a less-than one-to-one correspondence between both
models.

(And as a tiny aside, the EMF SDO plugins that I've just downloaded
consist of 1475 classes, of which 1218 are concrete and only 257 are
abstract/interfaces, so they hardly practice what they preach.)

(And 796 of those concrete classes are public, which seems rather high.)

(And they have 38 circular dependencies.)
 
H

H. S. Lahman

Responding to McDonagh...
Instead we would have:

interface Employee {...}
class EmployeeImpl implements Employee {...}

interface Country {...}
class CountryImpl implements Country {...}

interface Position {...}
class PositionImpl implements Position {...}

interface Client {
public Country getDomicile() {return domicile;}
public Position[] getPositions() {return positions;}
public Employee getCustomerResponsible() {return
customerResponsible;}
}

class ClientImpl extends Client {
// constructor left out

private Country domicile;
private Position[] positions;
private Employee custumerResponsible;

public Country getDomicile() {return domicile;}
public Position[] getPositions() {return positions;}
public Employee getCustomerResponsible() {return
customerResponsible;}
}



Note that you have redundantly defined the implementations (i.e., the
contents of the curly brackets). My preference would be to only
define the implementations in XxxxImpl. I would then name it 'Client'
and I would name the corresponding interface 'iClient', which is a
pretty common convention.

not in Java it isn't, adding Impl is pretty much standard.

And is actively discouraged elsewhere.

The 'xxxxImpl' tag isn't great, true, but removing it by tagging the
interface is just as bad.

A better example would be

interface Client

class CharitableClient
class BillableClient
etc...

You are introducing subclassing and polymorphic dispatch that was not in
the OP's example. My first point was simply that the interface should
be virtual, as yours seems to be here. My secondary point is that the
class spawning the objects should be named for the problem space
entities being abstracted and that the interface name should be the
derivative _when there is no polymorphic dispatch_. Again, that is what
you are doing here, albeit with subclassing. If there is subclassing
and polymorphic dispatch, then one should name the superclass interface
in a reasonable fashion, as you have done here, rather than as a derivative.


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
(e-mail address removed)
Pathfinder Solutions -- Put MDA to Work
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
(888)OOA-PATH
 
P

plm

Ed said:
Sounds overkill to me. And I've not seen this done elsewhere.

As a matter of interest, does EMF put the interfaces which it strips
from every class into the same package in which the class is defined?

No, usually in an impl sub package, but you can configure this, I think
on a per-package level. Not per class however.
I ask as a tangent to one of Chris's responses, concerning the idea of
developing an abstract model, and then designing an implementation model
behind it. It is useful to put interfaces in packages other than the
implementation packages, as then the client is unaffected by any
redesign of the implementation model package structure; but this is
really also presuming a less-than one-to-one correspondence between both
models.

Indeed, in theory you might implement multiple variants. In practice,
withing a single project however, this shall hardly ever be the case. I
was pointed to a paper of Martin Fowler regarding the difference
between public and published interfaces:
http://www.martinfowler.com/ieeeSoftware/published.pdf

I think that within the project we're dealing with public interfaces,
not with published interfaces (i.e. they are not hard to change as long
as we can keep the whole project in one workspace and apply refactoring
(tools) to all of the API and all users. In this case I think as well
that what we're doing is overkill.
(And as a tiny aside, the EMF SDO plugins that I've just downloaded
consist of 1475 classes, of which 1218 are concrete and only 257 are
abstract/interfaces, so they hardly practice what they preach.)

(And 796 of those concrete classes are public, which seems rather high.)

(And they have 38 circular dependencies.)

Heh, that's funny.
 
G

Greg R. Broderick

the primary use of an interface is to separate the 'Interface'
from the implementation.

Only for Java coders who can't read, or who don't understand the meaning
and use of the access modifier keywords "public", "protected", and
"private". :)



Cheers
GRB
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top