[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
RE: RE: [platform-swt-dev] org.eclipse.swt.SWT
|
First,
I must say I take offense at "The other believe in API"
in your note. I have written many very successful APIs at work, keeping
the API open and the implementation details hidden (similar to the "internal"
packages in Eclipse).
My
point of view is "make things open and subclassable",
not "subclass everything". Very big difference. I
have never stated "you should subclass or reuse as much as possible", nor
would I want to suggest that. You need to add at least one more crowd
in the world
I've
come to this POV after several years of finding classes in APIs that do 90% of
what I need, but I can't subclass them just because someone has marked them
final, or I can't get the behavior I need because the data is exposed publicly
instead of through accessors, or I can't override behavior because it's in a
private method. The following opinions are strictly from my
15 years of experience. <g>
There's nothing more frustrating to me as a programmer than having to
make a copy of a class just to change 10% of it. That defeats the whole concept
of inheritance...
An Example in Eclipse
As a
good example of this in Eclipse, take a look at class org.eclipse.ui.views.properties.PropertySheetEntry. There's a ton of private methods in there
that could have been made protected. Think about what happens if someone
subclasses -- the private createChildEntries() method
specifically creates instances of PropertySheetEntry. Thus, if you subclass,
your kids won't be the right type. (Factory methods really should never be
private, of they should be implemented as template methods that call
smaller public/protected factory methods).
GEF
wanted to make an Undoable version of this class. However, due to the above
restriction, they had to make a complete copy of the code (org.eclipse.gef.internal.ui.properties.UndoablePropertySheetEntry).
I
wanted to tweak it to change the sorting order, and again, I had to make a
complete copy of the code.
Basically, if you expose something, my point is that you should expose it
well, make sure you protect your data and be flexible for your
subclass so you can change the implementation details, while allowing others to
extend if they see fit.
If
you keep the class open, others can decide if it's usable, rather than you
specifically predicting when things might be desireable for subclassing.
Don't try to play Kreskin; noone can predict the future.
"Need to Know" vs. "Need to
Protect"
In the DoD world right now, they're trying to change some policies
from "need to know" to "need to protect". This concept is very similar to
programming, IMHO, and "need to protect" is the
key.
Basically, your strategy is akin to "need to know" in that only
those things that you think other people need to subclass are made easily
extensible.
My strategy is "need to protect", where I make everything as open
as possible in case someone finds it
useful.
One thing that hasn't come up in this discussion is the concept of
implementation classes. The way the Eclipse project marks classes as
implementation detail (by placing them in packages marked "internal") is an
excellent way to protect implementation
detail.
The basic strategy, IMHO, is figure out what you need to protect,
and place those in the "internal" packages. Anything in non-internal packages
should be considered "API", which should have a goal of non-breaking
change as much as possible.
Back to "Point" for a second (which
again, I'm not suggesting we change!), it's in an API
package (non-protected) and therefore can be assumed by programmers to be
non-volatile (meaning it's API won't change often if ever). Because of this
assumption, subclassing it is fair game.
So... because it can be subclassed, it should
have protected its data and provided proper state manipulation
methods.
On the
other hand, classes in "internal" packages are labeled such as fair warning to
outsiders. You're explicitly stating that these things are implementation
detail, with not even a suggestion that they'll even exist or keep a stable
API. If anyone subclasses or references these, it's clearly "at
risk".
Think about the Bridge Pattern
If
you're concerned about openness restricting your implementation options, then
you've hit the reason the GoF Bridge Pattern exists. You can put any impl
details you want in an "internal" class and call them from the API class. This
allows people to extend your API classes, tweaking some parts if they want,
leaving other behavior as is. Back to my rule #4: In the API classes, all the
methods should be public or protected.
(I
need to update my "rules of reuse" article to talk about "internal"
packages...)
The Bottom Line
What it boils
down to for me is that you're playing with the line between interface and
implementation. If you really want that separation, take advantage of the
"internal" packages, and use Bridge to connect the API classes with them. This
works wonders for openness, protection, and such.
Later,
--
Scott
Scott, what is missing in your analysis is the concept
of ownership. There is almost no way that
a class, no matter how well written, will be reusable by subclassing
unless it has been designed
that way
in the first place. From the point of view of code maintenance,
ModelPoint is the correct
answer
because "fancy SWT Point" is unlikely to have all the capability that the
application needs
and ModelPoint as a
subclass of "fancy SWT Point" is subject to breakage when the
superclass
changes. ModelPoint,
subclass of Object is stable over time.
Basically, there are two crowds in the world. Some people believe
in subclassing everything and
attempting reuse as much as possible. The other believe in API
and subclassing only those classes
that have been written with the intention of subclassing.
| Scott Stanchfield
<scott@xxxxxxxxxxxx> Sent by: platform-swt-dev-admin@xxxxxxxxxxx
02/28/2003 11:40 AM Please respond to platform-swt-dev
| To:
platform-swt-dev@xxxxxxxxxxx cc:
Subject: RE: RE:
[platform-swt-dev] org.eclipse.swt.SWT
|
I
think you missed my point...
The point is that should be no need to
reinvent the wheel here.
In a drawing tool, a Point model *is* a set of
coordinates. There's no
difference between intended use. I'm using a Point
object to keep track
of some location somewhere. Whether it's used for
actually drawing on
the screen or keeping track of data that's not
currently display, makes
no difference.
Subclasses could tweak the
usage for specific scenarios if needed.
-- Scott
>
-----Original Message-----
> From:
platform-swt-dev-admin@xxxxxxxxxxx
>
[mailto:platform-swt-dev-admin@xxxxxxxxxxx]On Behalf Of
>
vellapillli_h.indukumar@xxxxxxxxxx
> Sent: Friday, February 28, 2003
10:42 AM
> To: platform-swt-dev@xxxxxxxxxxx
> Subject: RE: RE:
[platform-swt-dev] org.eclipse.swt.SWT
>
>
> With respect to
SWT or Swing for that matter, I believe that
> Point need not
>
have getters and setters. If you are using SWT/Swing to
> create a
drawing
> tool, you would be better off using your own custom class
to
> represent a
> point. In case of a drawing tool, Point is a
model and not
> coordinates. In
> SWT/Swing, a Point represents a
coordinate. There are conceptual
> differences between them. So I would
suggest you have
> something in the line
> of PointModel with
getters, setters etc.
>
>
>
>
>
>
Scott Stanchfield
>
>
<scott@xxxxxxxxxxxx>
To:
> platform-swt-dev@xxxxxxxxxxx
>
Sent by:
cc:
>
>
platform-swt-dev-admin@
> Subject:
RE: RE: [platform-swt-dev]
>
eclipse.org
>
org.eclipse.swt.SWT
>
>
>
>
>
>
>
02/28/2003 04:27 PM
>
>
Please respond to
>
>
platform-swt-dev
>
>
>
>
>
>
>
>
> I agree with your points if the Point class is to be used
> >
inside a Drawing Tool.
>
>
This is the problem, IMHO. When someone designs a class,
> there's no
way
> they can know all the possible places that class is truly
useful.
>
> Why should there have to be multiple Point classes?
The concept should
> be incredibly reusable. If it had been
designed
>
> class Point {
> private
int _x, _y;
> public int getX() {return _x;}
>
public int getY() {return _y;}
> public void
setX(int x) {_x = x;}
> public void setY(int y) {_y =
y;}
> }
>
> it could later be modified or subclassed
to provide
> additional services
> such as notification, or
different implementations such as automatic
> origin
translation.
>
> As it currently exists, the only way to have a
notifying Point, is to
> create an entirely new class...
>
Something that could have been infinitely reusable, isn't...
>
>
Bottom line: Three of my "rules of reuse" apply here:
>
> * (rule
1) All data must be private
> * (rule 2) Most (if not all) data should
be exposed as JavaBean
> properties (ie getters/setters)
> * (rule
4) The get/set methods should be protected (or
> better,
public),
> so subclasses can override and call
>
> (I think
I might need to add another rule -- all objects must
> be
created
> via factories, so the factory could replace the actual type of
object
> returned with a subclass under certain circumstances...
hmmm...)
> -- Scott
>
>
>
_______________________________________________
> platform-swt-dev
mailing list
> platform-swt-dev@xxxxxxxxxxx
>
http://dev.eclipse.org/mailman/listinfo/platform-swt-dev
>
>
>
>
>
>
>
>
_______________________________________________
> platform-swt-dev
mailing list
> platform-swt-dev@xxxxxxxxxxx
>
http://dev.eclipse.org/mailman/listinfo/platform-swt-dev
>
>
>
_______________________________________________
platform-swt-dev
mailing
list
platform-swt-dev@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/platform-swt-dev