Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Law of Demeter and OOP confusion

I've been doing some reading recently and have encountered the Law of Demeter. Now some of what I've read makes perfect sense e.g. the paperboy should never be able to rifle through a customers pocket, grab the wallet and take the money out. The wallet is something the customer should have control of, not the paperboy.

What throws me about the law, maybe I'm just misunderstanding the whole thing, is that stringing properties together with a heirarchy of functionality/information can be so useful. e.g. .NETs HTTPContext class.

Wouldn't code such as :

If DataTable.Columns.Count >= 0 Then
   DataTable.Columns(0).Caption = "Something"
End If

Or

Dim strUserPlatform as string = HttpContext.Current.Request.Browser.Platform.ToString()

Or

If NewTerm.StartDate >= NewTerm.AcademicYear.StartDate And 
   NewTerm.EndDate <= NewTerm.AcademicYear.EndDate Then
   ' Valid, subject to further tests.
Else
   ' Not valid.
End If

be breaking this law? I thought (perhaps mistakenly) the point of OOP was in part to provide access to related classes in a nice heirarchical structure.

I like, for example, the idea of referencing a utility toolkit that can be used by page classes to avoid repetitive tasks, such as sending emails and encapsulating useful string methods:

Dim strUserInput As String = "London, Paris, New York"
For Each strSearchTerm In Tools.StringManipulation.GetListOfString(strUserInput, ",")
    Dim ThisItem As New SearchTerm
    ThisItem.Text = strSearchTerm 
Next

Any clarity would be great...at the moment I can't reconcile how the law seems to banish stringing properties and methods together...it seems strange to me that so much power should be disregarded? I'm pretty new to OOP as some of you might have guessed, so please go easy :)

like image 923
trucker_jim Avatar asked Aug 02 '11 21:08

trucker_jim


People also ask

What violates the principle of least knowledge or Law of Demeter?

The Law of Demeter principle states that a module should not have the knowledge on the inner details of the objects it manipulates. In other words, a software component or an object should not have the knowledge of the internal working of other objects or components.

What is the Law of Demeter trying to prevent?

The Law of Demeter asks us to minimize coupling between classes and avoid reaching out to the third object in order in order to make refactoring and developing new features easily.

What is a result of adhering to the Law of Demeter principle?

High Cohesion (HC): Adhering to the Law of Demeter often results in additional methods that mirror methods of aggregated objects. As these objects have other responsibilities, the additional methods have fewer commonalities with the “real” methods of the class, which results in a lower cohesion.

Why is it called the Law of Demeter?

It is so named for its origin in the Demeter Project, an adaptive programming and aspect-oriented programming effort. The project was named in honor of Demeter, “distribution-mother” and the Greek goddess of agriculture, to signify a bottom-up philosophy of programming which is also embodied in the law itself.


2 Answers

What the Law of Demeter (also "Law of Demeter for Functions/Methods") wants to reduce with saying "only use one dot" is that in a method you shouldn't have to assume such a lot of context from the provided arguments. This increases the dependency of the class and makes it less testable.

It doesn't mean that you can't use all of the above examples but it suggests that instead of giving your method the customer which then accesses the wallet and retrieves the money from it:

function getPayment(Customer customer)
{
    Money payment = customer.leftpocket.getWallet().getPayment(100);
    ...
    // do stuff with the payment
}

that you instead only pass what the paperboy needs to the method and as such reduce the dependency for the method if it's possible:

function getPayment(Money money)
{
    // do stuff with the payment
}

Your benefit from it will be that you dont depend on the customer to have the wallet in the left pocket but instead just process the money the customer gives you. It's a decision you have to base on your individual case though. Less dependencies allow you to test easier.

like image 152
Dan Avatar answered Oct 14 '22 13:10

Dan


I think applying the Law of Demeter to individual classes is taking it a bit too far. I think a better application is to apply it to layers in your code. For example, your business logic layer shouldn't need to access anything about the HTTP context, and your data access layer shouldn't need to access anything in the presentation layer.

Yes, it's usually good practice to design the interface of your object so that you don't have to do tons of property chaining, but imagine the hideously complex interface you'd have if you tried to do that to the DataTable and HttpContext classes you gave as examples.

like image 27
Jacob Avatar answered Oct 14 '22 11:10

Jacob