|
From: Daniel T. on 6 Aug 2007 14:56 John Carter <joNhOn.ScPaArMteErV(a)EtRait.co.nz> wrote: > ie. Ways in which bad designs allow us to subtly bypass the invariant > protection. One of my favorite examples: struct Point { int x; int y; }; class Rectangle { public: Point& getTopLeft(); Point& getBotRight(); // invariant: // getTopLeft().x < getBotRight().x && // getTopLeft().y < getBotRight().y ); }; void fn1( Point& p ) { p.x = 455; } void fn2( Rectangle& r ) { fn1( r.getTopLeft() ); } Was the Rectangle object's invariant broken? Maybe, maybe-not... There is nothing inherently wrong with the two functions, however in combination, they are forcing a change in the state space of the rectangle without proper permission. A general solution to these problems is to never return an object's internal state from any method. In C++, as an optimization, you can also return a "const T&" which makes the return faster while also disallowing outside code to change the rectangle's internal state inappropriately. However, most languages don't have the concept of a "constant reference". In those languages one must either make a full (deep) copy of the state, or create a special "constant" wrapper class. There is another solution in other languages though, if the server can be assured that all clients will follow the LoD, then the server can safely return that internal state because it knows that clients will not be modifying it.
From: John Carter on 6 Aug 2007 19:07 On Mon, 06 Aug 2007 18:56:29 +0000, Daniel T. wrote: > John Carter <joNhOn.ScPaArMteErV(a)EtRait.co.nz> wrote: > >> ie. Ways in which bad designs allow us to subtly bypass the invariant >> protection. > > One of my favorite examples: A lovely example! Exactly the class of thing I'm talking about! Thank you! > Was the Rectangle object's invariant broken? Maybe, maybe-not... There > is nothing inherently wrong with the two functions, however in > combination, they are forcing a change in the state space of the > rectangle without proper permission. Nicely put. > However, most languages don't have the concept of a "constant > reference". In those languages one must either make a full (deep) copy > of the state, or create a special "constant" wrapper class. There is > another solution in other languages though, if the server can be assured > that all clients will follow the LoD, then the server can safely return > that internal state because it knows that clients will not be modifying > it. Nicely put again... One of the areas where I suspect this whole chain of thought leads to is that Law of Demeter (in some form) falls out as a hard and fast rule, not a guideline. Still that's a post for another day. I used up my time allotment for now. John Carter
|
Pages: 1 Prev: DbC, OOD and Stroustrup's Rule, a concrete example Next: How LoD is useful. |