Clean Code – Solving ‘Train Wreck’ Properties Violating Law of Demeter

clean code

I've been reading about law of Demeter and I would like to know how to solve this traversing model properties problem that I see a lot on Objective-C. I know that there is a similar question but in this case I'm not calling a method from the last property that do some calculations, instead, I'm just setting values (Ok, I know that getter are methods but my intention here is just to get the value, not to change the state of some object).

For example:

self.priceLabel.text = self.media.ad.price.value;

Should I change that for something like:

self.priceLabel.text = [self.media adPriceValue];

and inside the Media.m

- (NSString *)adPriceValue {
    return [self.ad priceValue];
}

and inside the Ad.m

- (NSString *)priceValue {
    return [self.price value];
}

Is that a good solution? Or Am I creating unnecessary methods?

Best Answer

After reading the very interesting article posted by Robert Harvey, I'd suggest that if you're still worried about the LoD you do this (forgive me for not using ObjC syntax here, I have no clue how that works):

/* Old code: */
void update() {
  this.priceLabel.text = this.media.ad.price.value;
}

/* New code: */
void update() {
  updateAdInfo(this.media.ad);
}
void updateAdInfo(Ad ad) {
  // Can dive a level deeper here if you want to.
  this.priceLabel.text = ad.price.value;
}

Rationale: By introducing additional getters for sub-properties, you're flattening out your domain model, and that's just horrible: you lose all structure, and increase coupling. (What if you add a property to Ad? Do you now go to every single class that embeds an Ad and add getters for the new property?)

However, if you have a hierarchy of objects and a matching (partial) pseudo-hierarchy of view elements to display them, it makes sense to organize your update functions in a hierarchy as well.

Related Topic