Home > Static Code Analysis > “Law of Demeter” as a Software Metric

“Law of Demeter” as a Software Metric

June 3rd, 2012

The “Law of Demeter” (LoD) is one important principle to achieve low coupling in your code. And it could be turned into a software metric easily.

To measure the coupling, you could count the “LoD violations” per method. “0” means that no violations occured and the result is increased by 1 for every violation that was found.

I am wondering if someone implemented such a metric and if it could be used in Eclipse or NetBeans.

Here is a small example.


Example (before refactoring)
We have four classes Alfa, Bravo, Charlie and Delta which are arranged in a structure like a chain. So you could do something like alfa.getBravo().getCharlie().getDelta();.
This code violates the Law of Demeter two times and would get a “demeter distance” of 2.

The detailed code is here:

package lawofdemeter;
 
public class Main
{
 
    public static void main(String[] args)
    {
        Alfa alfa = new Alfa();
        alfa.getBravo().        // This is allowed, according to Law of Demeter
                getCharlie().   // Violation of Law of Demeter
                getDelta();     // Violation of Law of Demeter
    }
 
    private static class Alfa
    {
 
        private final Bravo bravo;
 
        public Alfa()
        {
            bravo = new Bravo();
        }
 
        public Bravo getBravo()
        {
            return bravo;
        }
    }
 
    private static class Bravo
    {
 
        private final Charlie charlie;
 
        public Bravo()
        {
            charlie = new Charlie();
        }
 
        public Charlie getCharlie()
        {
            return charlie;
        }
    }
 
    private static class Charlie
    {
 
        private final Delta delta;
 
        public Charlie()
        {
            delta = new Delta();
        }
 
        Delta getDelta()
        {
            return delta;
        }
    }
 
    private static class Delta
    {
    }
}

Example (after refactoring)

To improve the measurement to its optimum, one possibility is to insert the green marked methods. Now it is possible to write the whole code with a “demeter distance” for each method to 0. Here is the corresponding code:

package lawofdemeter;
 
public class Main2
{
 
    public static void main(String[] args)
    {
        Alfa alfa = new Alfa();
        alfa.getDelta();
    }
 
    private static class Alfa
    {
 
        private final Bravo bravo;
 
        public Alfa()
        {
            bravo = new Bravo();
        }
 
        public Bravo getBravo()
        {
            return bravo;
        }
 
        public Delta getDelta() {
            return bravo.getDelta();
        }
    }
 
    private static class Bravo
    {
 
        private final Charlie charlie;
 
        public Bravo()
        {
            charlie = new Charlie();
        }
 
        public Charlie getCharlie()
        {
            return charlie;
        }
 
        public Delta getDelta() {
            return charlie.getDelta();
        }
    }
 
    private static class Charlie
    {
 
        private final Delta delta;
 
        public Charlie()
        {
            delta = new Delta();
        }
 
        Delta getDelta()
        {
            return delta;
        }
    }
 
    private static class Delta
    {
    }
}

I believe that the second variant is (generally speaking) better than the first. But why?

One important point is readability. You have an alfa and you want to get a delta. So it is more intuitive to a reader to just read the alfa.getDelta(). And if he is really interested in how you get the delta, he will step into the getDelta() and find the details there.

The second point is – as already mentioned – the coupling. In the first version, you are dependend that an alpha has a bravo, which has a charlie, which has delta. Your code will only work under those conditions and will break if this path changes. And your code is less adaptable to other scenarios.

In the refactored version, you only depend on the fact that there is a direct way from alfa to get the delta and you delegate the details to the classes, which already know the details anyway.

Comments are closed.