Re: Annouce: DBIx::Class, a.k.a "taking the easy way out"

[prev] [thread] [next] [Date index for 2005/07/27]

From: John Siracusa
Subject: Re: Annouce: DBIx::Class, a.k.a "taking the easy way out"
Date: 02:07 on 27 Jul 2005
On 7/26/05 7:15 PM, Matt S Trout , Matt S Trout wrote:
> The problem with what you're talking about is that it ties you down to
> specific points to plug in to things. This is fantastic in terms of meeting
> the appropriate CS theory guidelines, but in practice you *always* end up
> needing something it didn't - hence why many Class::DBI plugins override all
> sorts of private methods (Sweet is terrible for this but I had no other
> choice). So instead, I'm going to let people override anything however they
> like and once a bunch of different approaches have been tried we can sit
> down and recommend the best one.

Inheritance vs. delegation is not an either/or proposition.  Obviously
subclassing is an important and powerful feature.  But when it comes time to
publish and support a system for "plug-in"-style modifications, inheritance
is poorly suited to the task--partly *because* it's so powerful.

Since a subclass can override "anything," it's much harder to enforce the
boundaries between components.  In fact, it's tempting to leave such
boundaries only vaguely specified, or even entirely undefined.  Given the
attention of enough developers, and enough time, it's almost impossible to
keep the "sprawl" contained--to keep track of who is doing what to which
methods when combined in which @ISA permutations.

> Delegation may turn out to be it, but so far it seems like it's a trade-off
> of flexibility vs. simplicity, and I want flexible above all here.

The "ultimate flexibility" of inheritance is most appropriate for situations
where the code can change without repercussions (or with very deliberate
repercussions).  Using inheritance and MI internally in order to eliminate
code duplication and so on is effective and appropriate.  It's also a good
way to feel out the "pieces" that can or should be modularized in a system.

But when it comes time to actually "publish" the modularity of your system
to a sea of eager, enthusiastic developers, delegation is a better choice.
It makes easy things easy--for both the community of developers and for the
module maintainers.

A well-vetted and time-tested delegation- or hook-style plug-in system will
also make hard things possible, but such a scaffolding is not easy to design
all at once.  This, however, is not an argument in favor of "punting" and
simply doing everything through inheritance.

Yes, inheritance does make hard things possible right off the bat, but
eventually it also makes easy things *hard*--again, for both the community
of developers and the module maintainers.  (Class::DBI is a perfect example
of this.)

It makes things harder for the community because subclassing is more
involved than hooks or delegation.  Yes, it's also "scarier."  That's
because developers know what subclassing can do ("anything") and are afraid
of stepping on toes.  (Or rather, they should be, because if they're not
then they definitely will!)

Extension solely through inheritance/MI makes things harder for the module
maintainers as well in that (again, given enough developers and enough time)
the code base will eventually become paralyzed by the weight of all the
existing subclasses and inheritance-based extensions.

With no way to know which classes extend or override which methods, it's
hard to determine what parts of the core code can be modified "safely"
(i.e., without breaking any third-party code).  The entire code base has
essentially become the "public extension API."  From this point, the only
way forward is painful, slow (or possibly "incompatible") change.  Again,
Class::DBI is a good example of this.

Now imagine the alternate scenario where delegation is the officially
supported public "plug-in" system.  Initially, delegates are put only in the
most obvious places.  There are not enough delegates, or not the correct
delegates, to do a lot of interesting things, but at least easy things are
easy.  Meanwhile, the internal code is entirely free to change so long as
the very simple delegate interfaces remain intact.

As more people use the module, it becomes clear where, and with what
granularity, more powerful or complex delegates should be used.  Again, if
the internal code needs to be refactored in order to support the new
delegates, its free to do so.  As long as it continues to fulfill the
minimal promises made by the earlier delegate APIs, no third-party code will
break.

At some point, a line must be drawn between what is reasonably possible with
delegates and what is "semantically divergent" enough to require inheritance
(or a fork).  Put another way, it's unwise to try to include delegation
everywhere, at a very fine granularity.

Any supported, public API should aim for the sweet spot: make easy things
easy, and make most hard-things-that-people-actually-want-to-do possible.
If this effort is successful, the vast majority of "regular users" (well,
developers) will use the easy-to-understand-and-maintain plug-in interface.

This leaves the hardcore developers ("the crazy ones") as the only group
still looking to subclass.  This is a much smaller group of people who will
either a) dutifully restrict themselves to a well-specified (but limited)
public subclassing API, or b) are willing to and accept admonitions like,
"Feel free to override that private method or class, but don't be surprised
if it changes or disappears later."

This leaves Joe Blow who just want to write a simple plug-in to get his job
done safely in the world of his well-specified, scope-limited delegation
interface, while still providing a fun and productive playground for the
hardcore developers to take the code in interesting new directions, or
pervert it for their own purposes, etc.

-John


(message missing)

Delegation vs Hooks (was: Annouce: DBIx::Class, a.k.a "taking the easy way out")
=?ISO-8859-1?Q?Ask_Bj=F8rn_Hansen?= 23:27 on 26 Jul 2005

Re: Annouce: DBIx::Class, a.k.a "taking the easy way out"
John Siracusa 02:07 on 27 Jul 2005

Generated at 16:37 on 28 Jul 2005 by mariachi v0.52