Talk:Law of Demeter

From CSSEMediaWiki
(Difference between revisions)
Jump to: navigation, search
 
(29 intermediate revisions by 3 users not shown)
Line 2: Line 2:
  
 
Just added an example --[[User:Kris Nicholson|Kris]] 00:28, 3 August 2008 (UTC)
 
Just added an example --[[User:Kris Nicholson|Kris]] 00:28, 3 August 2008 (UTC)
 +
 +
----
 +
 +
 +
I spoke to Wal just after the lecture and we were talking about the Law of Demeter, and a situation arose which I have documented below in the UML diagram.
  
 
[[Image:carengine1.jpg]]
 
[[Image:carengine1.jpg]]
 +
 +
It is possible that in this design you could say...
 +
  car.getEngine().start()
 +
 +
But the Law of Demeter states that generally more than one dot in a line of code is a sign that the law has been broken.
 +
 +
 +
 +
We also talked about another way this design could be approached in order to satisfy the Law of Demeter. The below design would satisfy the law because the start() method in the Car class could look a little something like this...
 +
 +
start()
 +
{
 +
    engine.start();
 +
}
 +
 +
[[Image:carengine2.jpg]]
 +
 +
 +
But now I'm a bit confused as to which approach is best? Ken Auer would say that the second approach is messy because it's not using a getter for the engine object.  Maybe the getter in the first design could be set as private and the start() method in the Car class could look like this...
 +
 +
  start()
 +
  {
 +
      getEngine().start();
 +
  }
 +
 +
What does everyone else think? --[[User:Geoffrey Clark|Geoffrey Clark]] 08:43, 12 August 2008 (UTC)
 +
 +
----
 +
 +
 +
Well we already talked, but I think the last method is the most extensible. Car can change its implementation of engine (through subclassing or otherwise, and all that needs to be changed is car.start() (and/or car.getEngine() depending). If car.getEngine().start() was being called in several places, this is a good win. --[[User:Kris Nicholson|Kris]] 22:55, 12 August 2008 (UTC)
 +
 +
----
 +
 +
 +
I added my example to the main page of this topic as Wal recommended it. --[[User:Geoffrey Clark|Geoffrey Clark]] 04:02, 14 August 2008 (UTC)
 +
 +
----
 +
 +
 +
Well sometimes I break this rule for maintainability, ie. avoid duplicating methods, and to avoid [[Large_class_smell]]. Method names on Car could get pretty long if we added more sub-sub-sub-components of Engine, and would create chains of methods to maintain..a balancing act. [[User:Lindsay|Lindsay Kay]]
 +
 +
----
 +
 +
 +
"Method names on Car could get pretty long if we added more sub-sub-sub-components of Engine, and would create chains of methods to maintain..a balancing act." Just wondering if you could clarify what you mean by this? Even if Engine had objects that it held, wouldn't Car just called it's start() method regardless and Engine would handle the starting of it's own sub-components? --[[User:Geoffrey Clark|Geoffrey Clark]] 06:37, 22 September 2008 (UTC)
 +
 +
--
 +
 +
Well, imagine that over time you added lots of components within your engine, with lots of methods on those components, and you wanted to expose those methods through Car. Maybe you'd do that so that you can have <b>fine grained operations</b> on those components...you might end up with:
 +
 +
  car.getEngineCrankshaftCylinderTemperature();
 +
 +
where Cylinder is a component of a Crankshaft, which is a component of Engine. You would have to add/delete/rename those little methods on Crankshaft, Engine and Car every time you want to add/delete/rename them on Cylinder, so it can lead to a bit of a <b>maintenance bottleneck</b> if you need to have all those little methods on Car. If thats the case, I reckon it can be better to have
 +
 +
  car.getEngine().getCrankshaft().getCyllinder().checkTemperature().
 +
 +
Just wanted to point out that one situation where I don't apply this otherwise useful law. Of course if you are happy to wrap those little operations up in a method like this:
 +
 +
  car.checkAllTemperatures()
 +
 +
then law of demeter is cool.
 +
 +
[[User:Lindsay|Lindsay Kay]]
 +
 +
---
 +
 +
There's something I can't decide, a minor design impasse. In a case where I was to compose a Car by plugging an Engine into it's constructor, it would be good design to provide a getter method on Car to get the Engine that I plugged into it right? Kind of symmetrical..? So while I'm at it, why don't I just use methods on Engine to get what I need from it? It just feels better. Any comments?
 +
 +
[[User:Lindsay|Lindsay Kay]]

Latest revision as of 21:17, 24 September 2008

I started this page with a short description and basic solution...a couple of days ago --Kris 03:34, 1 August 2008 (UTC)

Just added an example --Kris 00:28, 3 August 2008 (UTC)



I spoke to Wal just after the lecture and we were talking about the Law of Demeter, and a situation arose which I have documented below in the UML diagram.

Carengine1.jpg

It is possible that in this design you could say...

  car.getEngine().start()

But the Law of Demeter states that generally more than one dot in a line of code is a sign that the law has been broken.


We also talked about another way this design could be approached in order to satisfy the Law of Demeter. The below design would satisfy the law because the start() method in the Car class could look a little something like this...

start()
{
    engine.start();
}

Carengine2.jpg


But now I'm a bit confused as to which approach is best? Ken Auer would say that the second approach is messy because it's not using a getter for the engine object. Maybe the getter in the first design could be set as private and the start() method in the Car class could look like this...

  start()
  {
      getEngine().start();
  }

What does everyone else think? --Geoffrey Clark 08:43, 12 August 2008 (UTC)



Well we already talked, but I think the last method is the most extensible. Car can change its implementation of engine (through subclassing or otherwise, and all that needs to be changed is car.start() (and/or car.getEngine() depending). If car.getEngine().start() was being called in several places, this is a good win. --Kris 22:55, 12 August 2008 (UTC)



I added my example to the main page of this topic as Wal recommended it. --Geoffrey Clark 04:02, 14 August 2008 (UTC)



Well sometimes I break this rule for maintainability, ie. avoid duplicating methods, and to avoid Large_class_smell. Method names on Car could get pretty long if we added more sub-sub-sub-components of Engine, and would create chains of methods to maintain..a balancing act. Lindsay Kay



"Method names on Car could get pretty long if we added more sub-sub-sub-components of Engine, and would create chains of methods to maintain..a balancing act." Just wondering if you could clarify what you mean by this? Even if Engine had objects that it held, wouldn't Car just called it's start() method regardless and Engine would handle the starting of it's own sub-components? --Geoffrey Clark 06:37, 22 September 2008 (UTC)

--

Well, imagine that over time you added lots of components within your engine, with lots of methods on those components, and you wanted to expose those methods through Car. Maybe you'd do that so that you can have fine grained operations on those components...you might end up with:

  car.getEngineCrankshaftCylinderTemperature();

where Cylinder is a component of a Crankshaft, which is a component of Engine. You would have to add/delete/rename those little methods on Crankshaft, Engine and Car every time you want to add/delete/rename them on Cylinder, so it can lead to a bit of a maintenance bottleneck if you need to have all those little methods on Car. If thats the case, I reckon it can be better to have

  car.getEngine().getCrankshaft().getCyllinder().checkTemperature().

Just wanted to point out that one situation where I don't apply this otherwise useful law. Of course if you are happy to wrap those little operations up in a method like this:

  car.checkAllTemperatures()

then law of demeter is cool.

Lindsay Kay

---

There's something I can't decide, a minor design impasse. In a case where I was to compose a Car by plugging an Engine into it's constructor, it would be good design to provide a getter method on Car to get the Engine that I plugged into it right? Kind of symmetrical..? So while I'm at it, why don't I just use methods on Engine to get what I need from it? It just feels better. Any comments?

Lindsay Kay

Personal tools