On Apr 21, 2009, at 9:45 AM, Steve Schafer wrote:
On Mon, 20 Apr 2009 12:40:08 -0700, you wrote:
I wrote a blog post that may be helpful.
http://www.patmaddox.com/blog/demeter-is-for-encapsulation
Basically,
when you have structural objects as in this case, demeter isn't
useful.
I agree 100%.
That's a good example as far as it goes, but I think it makes a
distinction that isn't quite the true distinction. For example, I
remember dragsters from the '60s that had as many as four engines.
What
does car.engine.name do in that case? And the car I drive these days
has
a pair of electric motors in addition to an internal combustion
engine...
Likewise with the stereo--some minivans and SUVs come with two
independent stereo/entertainment systems, one for the front seat
passengers and one for the rear. When I invoke
car.stereo.has_cd_player,
am I asking about the "default" front-seat stereo, or do I only care
whether or not the car has a cd player somewhere?
The point, of course, is that digging down into the structure of an
object, even if structural information is what you're after, requires
that you make assumptions about that structure. And _that_ should be
the
criterion. You have to ask yourself:
(a) What implicit assumptions am I making by doing this?
(b) Is is safe to make those assumptions?
If you can reasonably answer yes to the second question, then you're
in
good shape. But you still have to accept that future changes to the
design can lead to structural changes that retroactively invalidate
your
answer.
I'm not sure how this ties to the application of Demeter's law. I
think Pat's point was that if what you're interested in is an object's
structure(such as to display information about the engine/engines in a
web page because customers want to see that) then applying Demeter's
law is just "needless indirection without any benefits". The decision
to model a car with Car#stereo Car#engine vs. Car#engines Car#stereos
has to be made(risk and assumptions considered here). If that
changes, things that renderinformation about the car engine
information WILL have to change. At that point I don't see how
Car#engine_name, Car#engine_type is of any benefit over
Car#engine.name. Car#engine_type. This is in contrast to the same
references in the context of behavior(e.g. car.start() vs.
car.engine.start()). I'm REALLY missing how applying GoF Builder
solution from *Everything.You.Know.is.Wrong to avoid getters/setters
buys me anything at all. I guess it would prevent the possibility of
behavior type code that violates Demeter's law, but it seems like it
comes at high cost. Unnecessary redundancy and class
explosion(importer/exporter interface for every domain class). This
seems more doable in a dynamic language with method_missing type
stuff, but I can't even imagine this in Java. Now every time I need to
add a new attribute to a class, I have to change all the Importer/
Exporter implementations regardless of their interest in said
attribute? How does that make my code simpler and more maintainable?
-lenny
*
http://www.holub.com/publications/notes_and_slides/Everything.You.Know.is.Wrong.pdf
-Steve
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users