Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / January 2006

Tip: Looking for answers? Try searching our database.

Design for Extension

Thread view: 
Martin  Ankerl - 17 Jan 2006 09:11 GMT
Hi! I have recently read about Design for Extension [1], which says
that all your methods should be either

* abstract,
* final, or
* have an empty implementation

This forces you to design the classes for extension, i.e. provide hooks
for each extension you need. I used to be an opponent of final methods,
because you never know in advance when you have to extend something.
But from the viewpoint described in [1] this makes a lot of sense. What
are the opinions on this topic? I could not find anything with Google.
I am curious if anyone here has use this approach for a project and can
share his experience?

[1]
http://checkstyle.sourceforge.net/config_design.html#DesignForExtension

Signature

Martin Ankerl | http://martinus.geekisp.com/

Thomas Weidenfeller - 17 Jan 2006 10:50 GMT
Martin Ankerl wrote:
> Hi! I have recently read about Design for Extension [1], which says
> that all your methods should be either
[quoted text clipped - 8 lines]
> But from the viewpoint described in [1] this makes a lot of sense. What
> are the opinions on this topic?

It is religion. If you are in need of another faith, then consider XP.
One of the fundamentals of XP is

  *You ain't gonna need it*

Which e.g. means, you do not explicitly design your stuff to be
expendable, unless the extension is needed right at the moment. The XP
arguments for doing so also make sense.

/Thomas
Signature

The comp.lang.java.gui FAQ:
ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq
http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/

iamfractal@hotmail.com - 17 Jan 2006 12:10 GMT
Object-orientation is based on variance-encapsulation (see GoF), so to
practice object-orientation you must know:

A) What quality of a system is varying, and
B) How to encapsulate that quality.

Varying necessarily means, "Varying with time," so unless you're
planning to design a system that's moving into the past, then there is
some aspect of the future that you'll find yourself contending with.

People sometimes use the phrase, "Don't design for the future," as
though desiging-for-the-future carries a cost and
not-designing-for-the-future is free: this is an inaccuracy.

To practice variance-encapsulation you must of course practice
encapsulation; and to practice encapsulation you must identify your
system's natural fracture-lines and carve it up appropriately: those
carved pieces must then be encapsulated from one-another.

This is inevitable, whether you're designing for the here-and-now or
the ever-after; this is a cost even for
not-designing-for-the-future. (And make no mistake, there is a great
harvest of benefits to be reaped from this approach: increased
comprehensibility and maintainability to name but two.)

The question is: what informs these natural fracture-lines? What makes
encapsulating AB from C more, "Natural," than encapsulating A from BC?

The answer splits the discipline of obect-orientation in three, giving
rise to immediate, tactical, and strategic object-orientation.

If you're really lucky, your requirements will tell you, "We need a C,
but we also need a D and an E which should be swappable with C from
AB's point of view," and your iteration plan will say, "We need C, D,
and E delivered in the first iteration."

Then the solution is clear: you need to employ immediate
object-orientation: you are being told exactly what is varying and
what to encapsulate and when to deliver them altogether. Put C, D,
and E behind the same interface and have AB program to this
interface.

This is an XPer's (and most people's) delight. This is a sure sign
that your product is being driven by solid requirements. This project
will probably deliver a product that somebody (maybe the customer but
certainly Product Management).

If you're a little less lucky, your requirements will say, "We need a
C, but we also need a D and an E which should be swappable with C from
AB's point of view," and your iteration plan will say, "We need C, in
the first iteration, and D and E in the second and fifth iteration."

Then the solution is clear: you need tactical
object-orientation. You're being told exactly what is varying and what
to encapsulate and that they'll be delivered at different times.

Only the shortest of the short-sightest would look at the requirements
for the first iteration in isolation, and decide not to encapsulate C
from AB. So here we are designing for the future, but there are
degrees of future, and this future seems pretty certain.

Of course no future is completely certain, and in the second
iteration, the requirements may change, and the D and E parts may be
dropped, meaning that the fracture-line you've chosen to cut between
AB and C could have been a waste of time; but even if those
requirements hadn't been dropped, you might still have chosen to cut a
fracture-line somewhere in the mass of ABC, just for
comprehensibility/delivery/maintainability - and those benefits are
still accrued from the AB/C split.

Finally, you may have no requirements beyond the end of your project,
and thus don't know what might vary, and so don't know what to
encapsulate. But there are always hints to be found in the nature of
your product. (And this is where a product road-map is essential to
object-orientationists.)

If you're designing an operating system, you probably won't hard-code
it to a particular file system. You have no requirements on your desk
taht say, "We'll have a new file system in three releases' time," but
it's possible, so you may chose to encapsulate the file system from
the kernel.

Similarly, you may be designing a car's engine-control system, and
decide that, in future, an electric engine might come along after the
current diesel engine, and so encapsulate those parts common to
both. In the end, of course, no electric engine may come along, and
that encapsulation work might be completely wasted.

This is strategic engineering, and it is the most dangerous
(uncertain) of the three. XPers seldom invest much effort in this; and
I think they may be right.

I doubt that the best approach to product-development is either a
rabid fear of the future or an all-comsuming addiction to it. The best
(that is, most cost-effective) solutions tends to snake somewhere
between the two.

Gotta love engineering ...

.ed

--
www.EdmundKirwan.com - Home of The Fractal Class Composition.
Chris Uppal - 17 Jan 2006 13:19 GMT
> Object-orientation is based on variance-encapsulation (see GoF), so to
> practice object-orientation you must know:
>
> A) What quality of a system is varying, and
> B) How to encapsulate that quality.

A sensible post, but I want to raise a couple of quibbles.

> Varying necessarily means, "Varying with time," so unless you're
> planning to design a system that's moving into the past, then there is
> some aspect of the future that you'll find yourself contending with.

I don't think that's true.  The variance can occur across several axes.  For
instance, we might want to have AB+C at one site, and AB+D at another.  Or one
product line might include AB+C while another includes AB+D.  Such variances
also supply your "natural fracture lines".

Secondly, and in a way generalising that point, while variance does suggest
object boundaries, I think it's an exaggeration to claim that it's the source
of OO.  If that were true, then in my own (personal) software, written with no
thought to the future ('cos I have no idea what it is) nor consideration of
other possible variance (since it's only used by me, typically for only one
purpose), I would have no idea where to put object boundaries.  Indeed I could
/only/ structure my applications as one big object.  Obviously that's absurd.
Variance is only one of the inputs to OO design, and managing variance over
time is only one of the benefits of OO code.

I don't suggest that you really hold the views I'm disagreeing with above, but
your words could certainly be taken that way.

(None of this has anything to do with the OP's question, of course ;-)

   -- chris
iamfractal@hotmail.com - 17 Jan 2006 13:53 GMT
All good points, Chris.

I should be more careful with my words.

(Late night last night, watching, "Vanilla Sky; don't know why the
critics slammed that so hard.)

.ed

--
www.EdmundKirwan.com - Home of The Fractal Class Composition.
Martin  Ankerl - 17 Jan 2006 12:57 GMT
Actually I think "Design for Extension" can work very well with XP. The
difference from the normal approach is, that whenever you need to
extend a class, you cannot just make a subclass and override a method;
you need to refactor the base class and add an extension hook somewhere
first.

I think this might be a very good way of developing software. These are
the advantages/dissadvantages I see with this approach:

+ No beeing able to forgett to call super() in a subclass
+ Whenever behaviour of the base class is modified, it is done at a
place where it is designed to be extended.

- You have to be able to access and modify all the code you have to be
able to add hooks which can be very problematic with libraries.

Signature

Martin Ankerl | http://martinus.geekisp.com/

Martin  Ankerl - 17 Jan 2006 13:01 GMT
Actually I think "Design for Extension" can work very well with XP. The
difference from the normal approach is, that whenever you need to
extend a class, you cannot just make a subclass and override a method;
you need to refactor the base class and add an extension hook somewhere
first.

I think this might be a very good way of developing software. These are
the advantages/dissadvantages I see with this approach:

+ No beeing able to forgett to call super() in a subclass
+ Whenever behaviour of the base class is modified, it is done at a
place where it is designed to be extended.

- You have to be able to access and modify all the code you have to be
able to add hooks which can be very problematic with libraries.

Signature

Martin Ankerl | http://martinus.geekisp.com/

Chris Uppal - 17 Jan 2006 13:18 GMT
Martin Ankerl wrote:

> Hi! I have recently read about Design for Extension [1], which says
> that all your methods should be [...]

I tend to be extremely sceptical of prescriptive design principles.  Even more
so of Names With Capital Letters.

If I ask someone why some aspect of a design is the way it is, or why something
is coded in a specific way, then I expect to get an explanation in terms of the
other aspects of the design (current, historical, or anticipated).  That's to
say, I want a reasonably concrete explanation.  If the author tells me that
it's because of <some Design Principle>, then s/he has told me nothing except
that s/he quite probably doesn't understand his/her own design.  (The --
important -- exception to this is s/he's using the name of the Design Principle
just as a short-cut for something more concrete that s/he knows I'll be able to
recognise from the name).

In this case, the discipline of making all methods either abstract or final may
well be appropriate in some cases.  But I wouldn't claim that it's appropriate
in all, or even most, cases.  And the decision whether to follow that
discipline in some case should be based on the requirements of that case, not
on the tenets of some Design Principle.

   -- chris
Michael Redlich - 17 Jan 2006 17:47 GMT
> Hi! I have recently read about Design for Extension [1], which says
> that all your methods should be either
[quoted text clipped - 13 lines]
> [1]
> http://checkstyle.sourceforge.net/config_design.html#DesignForExtension

Hi Martin:

The "Design for Extension" section of the article is obviously trying
to point out the importance of good object-oriented design.

As Chris and Ed had already mentioned, it is indeed difficult to
predict common object behavior in an abstract class or interface.  You
obviously want to write software that is robust and easy to maintain.
This is why design patterns are such a big help, but you also need to
be careful because applying a design pattern in the wrong context can
cause more harm than good.

It is important to understand some of the design principles at work,
such as:

"Program to an interface, not an implementation."

For example:

Manager manager = new Manager();

is an example of programming to an implementation.  You are basically
stuck with the defined behavior of a manager object that *cannot* be
changed at runtime.  However:

Employee manager = new Manager();

is an example of programming to an interface (Employee being an
interface), and allows the employee object (manager variable) to be
changed at runtime by, say, with the Decorator design pattern.

Along with the GoF book, I would also recommend the Head First Design
Patterns book.  Check out http://www.wickedlysmart.com/.  There are
links to all of their books and source code from them.

Sincerely,

Mike.

--- ACGNJ Java users Group (http://www.javasig.org/)


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.