views:

206

answers:

5

See what you think of this line of code:

if ([pickerViewController.picker.bvc.currentResolve.name isEqualToString:message])
  ...

Would you consider this to be excessive use of the dot operator?

If not, I can leave it as-is.

But if so, what's the preferred alternative?

A: 

I don't think there is excessive use of the property notation. If an object has a property, access it as such; it demonstrates to the reader what the programmer means.

Oh, and pre-empting the "looks like a struct" brigade; if you can't tell a struc from an object in your code, refactor your code.

Graham Lee
+8  A: 

This is more of a Law of Demeter violation than a problem with the dot operator. The "cleaner" way to do this would be to give the object the logic to figure this out itself, so you could do something like

if ([pickerViewController hasPickedName:message])
Chuck
I'm going to second this. You don't have to be an avid and strict user or fan of LoD to appreciate gross abuses of it, and perhaps take effort to code these kinds of things away.
Will Hartung
Agreed. Your top level object has far too much knowledge of the inner workings of too many lower-level objects that have likely exposed properties that should be private.On a related note, a public property should never have a name like "bvc" (which sounds suspiciously like another view controller, suggesting perhaps muddying of MVC). Objective-C is founded on clarity in reading, not brevity in writing. The lack of strong compiler checks makes brutally consistent naming one of the strongest safeguard against bugs.
Rob Napier
A: 

So long as each use of the dot operator there really is fetching a property (i.e. not a method which is chiefly concerned with doing work for purposes other than returning a value), then that's fine. In fact, if you check Wil Shipley's blog, he's actually a fan of chaining as many function calls together into a single line as is necessary (he dislikes excessive use of local variables).

Jim Dovey
A: 

I find that debugging this sort of thing is always more trouble than it's worth, so I tend to create intermediate variables for each of the property accesses. Or, as others suggested, refactor this so it looks simpler at the usage site (by putting the smarts in a method).

Mark Bessey
A: 

I agree with Chuck and commenters. Your method is dependent on too many other objects, but putting hasPickedName: on pickerViewController means pickerViewController still has to do [picker.bvc.currentResolve.name isEqualToString:message] somehow.

Instead, you could put hasPickedName: on bvc and inject bvc as a delegate (typed id<NamePickerDelegate> maybe) into your top-level object using Interface Builder. To be truly Demeter-compliant, make currentResolve grow a method nameMatches: that shortcuts [currentResolve.name isEqualToString:message].

You should look carefully at the complexity caused by the problem verses the complexity that would be introduced by each solution. If you judge that the original code is simpler and easier to maintain than the alternatives, keep it.

Will Harris