You are only using a portion of an argument's members - reidev275/SignsYouShouldProbablyRefactor GitHub Wiki

Also known as the [Law of Demeter] (http://en.wikipedia.org/wiki/Law_of_Demeter).

Example

Here we have a property listing poco containing data related to a specific real estate property listing. We then have a geocode method which takes address, city, state, and postal code into consideration to populate the Latitude and Longitude properties on the PropertyListing object. The issue here is that the Geocode method has no need of properties like Price, Bedrooms, or any other features of the PropertyListing.

class PropertyListing
{
 public string Address { get; set; }
 public string City { get; set; }
 public string State { get; set; }
 public string PostalCode { get; set; }
 public double Latitude { get; set; }
 public double Longitude { get; set; }
 public double Price { get; set; }
 public int Bedrooms { get; set; }
 ...
}

class Geocoder
{
 void Geocode(PropertyListing listing) { ... }
}

Why is this bad?

  1. We are exposing properties to potential volatility because the Geocode method could have buggy code that mistakenly updated the Price of the listing whenever it was geocoded.
  2. We are not following the Interface Segregation Principal

Resolved

We simply create an interface for the minimal set of properties the Geocode method needs and have our PropertyListing class implement the interface. We can now have any number of other concrete types of IGeocodable objects (real estate agent office locations, nearby schools, etc..)

interface IGeocodable
{
 string Address { get; }
 string City { get; }
 string State { get; }
 string PostalCode { get; }
 double Latitude { get; set; }
 double Longitude { get; set; }
}

class PropertyListing : IGeocodable
{
 public string Address { get; set; }
 public string City { get; set; }
 public string State { get; set; }
 public string PostalCode { get; set; }
 public double Latitude { get; set; }
 public double Longitude { get; set; }
 public double Price { get; set; }
 public int Bedrooms { get; set; }
 ...
}

interface IGeocoder
{
 void Geocode(IGeocodable geocodable);
}