My trouble with interfaces...and their contracts

M

Mike

Hi,

I generally prefer to use interfaces rather than abstract classes, for
several reasons including the ability to implement multiple interfaces and,
to me, "cleaner" polymorphism.

But, as I write this, I am working on something that has troubled me before,
and I was hoping to get some suggestions.

Basically, my problem with interfaces is that it is harder (for me, anyway)
to enforce contracts between related interfaces. Much of the contract has
to be written down as part of the documentation for the interfaces. For
example, in some cases I "wish" that I could place constructors in
interfaces, such that I could make the no-args constructor private, forcing
the use of a more specific constructor - implementing classes would then
have to provide a constructor with this signature. I also sometimes wish
that I could declare static methods in interfaces.

In general, with abstract classes, I have more control over implementation
and contractual relationships. But I don't like resorting to abstract
classes unless I have to. Although, if there is a common piece of code that
any implementor would have to provide, I may use an abstract class for that
purpose, rather than an interface (or, more likely, an abstract base
implementation of an interface.)

I just don't like leaving everything to documentation. Anyone know what I'm
talking about, and could either point out what I'm doing wrong, or suggest
alternatives? Perhaps a reference to some code that makes good use of
interfaces in this manner?

Thanks.

Mike
 
M

Mike

John C. Bollinger said:
You may be looking for a factory class -- perhaps even an abstract
factory class -- to go along with your interfaces. That would apply if
what you want is a generic / configurable way to obtain FooInterface
implementations based on specific types of arguments. For the general
case, it doesn't make sense to me to imagine constraining constructor
signatures. If an object can fulfill the contract specified by your
interface, then what does it matter how it was obtained?

Thanks for the comments.

I didn't do a very good job explaining myself, though. I agree with the
factory approach; the constructor comment was sort of a bad example. What I
was really getting at was that I would, perhaps, like to have the ability to
limit the way constructors are used. Perhaps to enforce the use of a
factory?
If your implementations are going to be so tightly held and narrowly
used that it makes sense to demand specific contructor signatures to the
exclusion of any others, then you are giving up many of the advantages
of interfaces anyway. (And you don't need them.)


You can put class definitions in interfaces, and you can give those
static methods. That feels a bit like a cheat, but as far as I can tell
it's legal. Putting static methods in an interface definately feels
wrong to me -- it violates my sense of what an interface should be for.
Luckily for me, the JLS agrees. :)

Well, my thinking with allowing static methods in interfaces was along the
lines of perhaps utility classes and methods could be used polymorphically
too. (I know, one could use a singleton instead.)
I think you are asking for too much. A language that supports
polymorphism is not well suited to the kind of programmatic contractual
enforcement that you are asking for, a language that doesn't has no such
problem in the first place.

The whole thing that is bothering me is sort of intuitive and hard for me to
explain. Let me give an example - for fun, I've worked on a couple of
toolkits from some Java Specification Requests. I was surprised at how
little information the interfaces conveyed by themselves. Significant
documentation was necessary in order to implement some of those interfaces
and corresponding relationships.

I know, I know, nothing comes free - it just seems to me there ought to be a
better way to enforce interface contracts. Also, my background - I work
with a lot of more junior people. I'm trying to think of ways to make their
life easier.

Something that occurred to me just now; what if the public interface was
just what an application uses - but implementors of the interface (I'm
thinking libraries) had to adhere to some sort of, separate, "model"
interface or abstract class? I'm trying to think out loud of how to build a
"framework" where the relationships are static, but the implementations of
individual interfaces are dynamic. Something like that.

Anyway, just thinking out loud.

Thanks for the comments!

Mike
 
A

A Bag Of Memes

Mike said:
I didn't do a very good job explaining myself, though. I agree with the
factory approach; the constructor comment was sort of a bad example. What I
was really getting at was that I would, perhaps, like to have the ability to
limit the way constructors are used. Perhaps to enforce the use of a
factory?

I suggest a change of attitude. You'll never force anyone else to do
something the "right" way, because that's subjective. Make it easy for them
to do it "your" way, but let go of the desire for control.
Something that occurred to me just now; what if the public interface was
just what an application uses - but implementors of the interface (I'm
thinking libraries) had to adhere to some sort of, separate, "model"
interface or abstract class? I'm trying to think out loud of how to build a
"framework" where the relationships are static, but the implementations of
individual interfaces are dynamic. Something like that.

That's exactly how you build a framework. Isolate the key methods that need
to be implemented, put them in interfaces and put everything else
(relationships, factories, everything you can) in the framework. Security
management frameworks are a good example. They often provide an interface
with a few methods like "isGood(user, password)" and "isMember(user,
group)". Everything else is in the framework, including creation of the
security manager, users, passwords and groups. All the framework user has
to write are the bits they are interested in.
 
X

xarax

Roedy Green said:
If you want want to control the implementation, then you need to use
an abstract class. The whole point of an interface is to allow
implementations done ways the original interface specifier never
imagined. Are your restrictions just good practice or strictly
mandatory? Perhaps you are just being a Nazi trying to impose your
will where it is none of your business.

Enough! That was uncalled-for. His reasons and motivations
are well explained. If cannot you cannot help him with
constructive ideas, then STFU!
 
R

Roedy Green

If cannot you cannot help him with
constructive ideas,

I did give him a constructive idea -- use both an abstract class AND
an interface. I also suggested to check into his motivations.
Perhaps he did not really need to do what he thought he needed to do.
 
A

A Bag Of Memes

Bent C Dalager said:
I tend to think that when you have complex rules for how custom
implementations of your interfaces should work, the best approach is
to supply an automated test suite they cun run on their creations to
weed out the most glaring mistakes.

That's a good approach, if your imagined implementor cares enough to test.
I think any method that needs complex rules to describe what it should do
probably has several smaller, simpler methods struggling to get out. I'd
consider refactoring the interface.
 
B

Bent C Dalager

That's a good approach, if your imagined implementor cares enough to test.

True. You're not forcing compliance, you're only facilitating it. But
that is probably the best you can hope for anyway.
I think any method that needs complex rules to describe what it should do
probably has several smaller, simpler methods struggling to get out. I'd
consider refactoring the interface.

Perhaps. It doesn't really have to be very complex though, just
important and non-obvious. I've always found the equals()/hashCode()
interdependence to be problematic. The rules for writing those aren't
particularly complex, but they are important and they're anything but
obvious.

Not that I am clever enough to be able to insta-suggest a decent test
suite to catch that one, but I also doubt that refactoring would offer
much in the way of a solution. Both operations are about as basic as
it can get already.

Cheers
Bent D
 
E

Edmund Kirwan

Mike said:
Basically, my problem with interfaces is that it is harder (for me, anyway)
to enforce contracts between related interfaces. Much of the contract has
to be written down as part of the documentation for the interfaces. For
example, in some cases I "wish" that I could place constructors in
interfaces, such that I could make the no-args constructor private, forcing
the use of a more specific constructor - implementing classes would then
have to provide a constructor with this signature. I also sometimes wish
that I could declare static methods in interfaces.

I'm afraid that I don't have any advice or solutions, I just thought
that it might be ok to sympathise. Completely. It *should* strike
programmers as strange that constructors open a free door to code that
interfaces cannot control. There's an intuitive incompleteness about
the whole business.

Java's a nice language, but it's also remarkably young and remarkably
open to change. (That deprecation is a great boost.) I wouldn't be
surprised if, in a few years, interfaces held swap over constructors,
too.

..ed

www.edmundkirwan.com
 
A

A Bag Of Memes

Edmund Kirwan said:
"Mike" <[email protected]> wrote in message

I'm afraid that I don't have any advice or solutions, I just thought
that it might be ok to sympathise. Completely. It *should* strike
programmers as strange that constructors open a free door to code that
interfaces cannot control. There's an intuitive incompleteness about
the whole business.

Java's a nice language, but it's also remarkably young and remarkably
open to change. (That deprecation is a great boost.) I wouldn't be
surprised if, in a few years, interfaces held swap over constructors,
too.

Can it be added without polymorphic contructors? I thought that was the
reason for leaving it out of interfaces. I don't think we want polymorphic
constructors, do we?
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top