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

Reply via email to