One /very/ important reason not to use interfaces in this case is that: interfaces are hard to evolve. Interfaces have to be pretty darn stable before even considering throwing them out in the public, as there is no way (not without a tough fight at least) you can alter it later on - even adding a new method will break all clients. >> I don`t agree. My rule is: if you get more to the core (so more depends on you) there is more reason to design from an interface. Especially things like Page and othere core parts should always (no exceptions) be designed from an interface. You define a contract... as long as the contract is obayed, every implementation will do (that is what the contract is for). Almost every pattern that is out there depends on some kind of contract/implementation-seperation. Another reason not to use interfaces here is that there is so much behaviour in here (in the pages and components), that it is very hard to extract something usefull out of it. What would the interface of a Page be? --------------------------------- Simple: everything that behaves as the javadoc-contract describes. The Javadoc is the contract.. At the moment the interface should be all the methods the page defines, although I only added 'core' methods to interfaces and put all the handy but unrequired stuff in util classes and abstract classes. But as soon as you see an abstract class as a method argument... something most have gone wrong.. an abstract class should (almost) never declare as a type. One of the good practices when making interfaces is that they should be small. Having an interface like http://jakarta.apache.org/tapestry/tapestry/apidocs/org/apache/tapestry/IPage.html doesn't really display that. They can be large, like the collection interfaces are, but they have to be really, really stable and consistent.
Just to be sure, and as I didn't make this decision for Wicket I asked
Jonathan Locke (who is doing movie stuff now, and left the mailing lists
for some time) why he choose for interfaces. Here's a partial transcript
of our chat:
[22:31] jonathan: i don't believe in big interfaces
[22:31] jonathan: no interface should be as large as Page
[22:32] jonathan: it's too fragile
[22:35] jonathan: abstract classes are evolvable
[22:36] jonathan: interfaces should always be a set of methods that you
cannot ever imagine extending
[22:36] jonathan: it encapsulates a very specific set of behaviors
[22:37] jonathan: everyone should feel free to create/extract his own
IPage interface for use with proxies
[22:38] jonathan: there's something fundamentally wrong with the way
that current OO languages try to wire things together with static
interfaces.
[22:39] jonathan: unless i'm missing something, this is really not a
problem with wicket
[22:40] jonathan: in fact i think it's a feature
[22:40] jonathan: interfaces are really most useful for things that are
truly pluggable
[22:43] jonathan: my ideal number of methods in an interface is 1
[22:43] jonathan: ;-)
[22:44] jonathan: 2 is okay in some cases
[22:44] jonathan: 3 often should be re-thought
[22:44] jonathan: the more methods you have, the more likely it is that
you've got a bad design
So, it is a design decission not to work with interfaces. However, as
Jonathan stated, you could extract an interface, let your page class
implement it and off you go. Furthermore, I wonder what it is you want
to do with a proxy that you can't do by simply subclassing? Or AOP?
As a final statement I'd like to add that a framework like Wicket is
very different from a business system, which could have tons of business
methods that must be pluggable. Though even in that case, I think too
that interfaces are overused/ get too much focus with some of the
current popular frameworks. Seems to be getting a knee-jerk reaction
instead of a design decision. But maybe that's just me.
-----------------------------------------------------------------------------
My experience as a programmer is that everytime a system isn`t designed from
interface, it causes a lot of unrequired restrictions. If more depends on you
(like Wicket)... the more reason everything should be designed from an
interface.. And I like my interfaces very very small *I have the attentionspan
of a chicken.. so if I don`t understand it in five seconds.. it must be wrong*.
But the problem is that it is impossible for me to generate proxies for
enhanced pages. I wanted to added security and transaction (Spring/Acegi) and
it would have been easy if the page was designed from an interface. But because
there are final methods (I love final methods) it is impossible to generate a
proxy (because there is no interface) that is based on a dynamic generated
subclass.
I wanted to do something like this:
class FooPage extends WebPage{
@security(role=Administrator)
@transaction(readonly=false, .....)
void submit(){
..code
}
}
At the company I work for we have two different ways of designing applications.
For small applications we don`t build a 'service' layer. The code is added to
the evenhandlers and that is what I`m doing at the moment. For larger
applications we write a seperate service layer where I have full control how
everything is done, but this costs more time.. and makes small projects less
profitable
[edit]
I have been reading my reply and it should have been more friendly (especially
because you have takes the time to answer my questions). But I hate it when I
can`t do what I thought I wanted to do and when I`m restricted to unrequired
restrictions. I love good design (that is the thing I love about writing
software) so I like tools that think like I do. Btw.. I like Wicket so far
(even though I don`t like some design decisions)
<<winmail.dat>>
