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?
- We are exposing properties to potential volatility because the
Geocode
method could have buggy code that mistakenly updated thePrice
of the listing whenever it was geocoded. - 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);
}