Demeter Law

Hello, how are you?

Let us talk today about the Demeter Law. It is a pattern of Object Orientation that helps us to lower our coupling, decrease our maintenance impact and the raise adaptability of our systems.

What is utility for those “weird” words? If you have to do any maintenance in your application, it will have a lesser impact; your classes will only know the classes that it should know, and your code changes will be quicker and with less impact in your system.

Just advantages in the Demeter law, right? Let us take it easy; in the end of this post we will see the disadvantage of this approach.

If you want to see another post about OO just click in the link: “Tell, do not ask!

Take a look in the code bellow, what could we do to make it better?

package com;

public class Main {

    public static void main(String[] args) {
        IAddress address = new Address();
        address.setName("01");
        address.setZipCode("000001");

        IHouse house = new House();
        house.setAddress(address);

        IPerson person = new Person();
        person.setHouse(house);

        // Print the person zip code
        System.out.println(person.getHouse().getAddress().getZipCode());
    }
}

The code above will run as expected; we are coding to interface, our code is wellindented and well formatted. What could we do to “upgrade” our code?

The Demeter law says that a class may not know more then one friendly class. WHAT? Let us take small steps and analyze the code above; notice that our Main class wants to print the Person ZipCode, but to do this the Main class get to know two more classes. If you did not noticed, there is a coupling there.

To print de ZipCode our class Main is going through the Person, House and finally Address class. What is this a bad approaching? Imagine if out Annalist decide to remove our Address class from the system and the House class will be responsible to keep the ZipCode.

In our cod ewill be very easy to change; but imagine now if we had a huge system with the ZipCode printed for more than 100 code lines. You would have to change 100 lines of codes at your system.

The Demeter law came to help us with this kind of situation, with a little change in our Person and House classes; we can avoid this huge impact when we remove the Address class. Take a look in our new code.

package com;

public class Main {

    public static void main(String[] args) {
        IAddress address = new Address();
        address.setName("01");
        address.setZipCode("000001");

        IHouse house = new House();
        house.setAddress(address);

        IPerson person = new Person();
        person.setHouse(house);

        // Print the person zip code
        System.out.println(person.getZipCode());
    }
}
package com;

public interface IPerson {

    void setHouse(IHouse house);

    IHouse getHouse();

    String getZipCode();

}
package com;

public class Person implements IPerson {
    
    private IHouse house;

    @Override
    public void setHouse(IHouse house) {
        this.house = house;
    }

    @Override
    public IHouse getHouse() {
        return house;
    }

    @Override
    public String getZipCode() {
        return house.getZipCode();
    }
}
package com;

public interface IHouse {

    void setAddress(IAddress address);

    IAddress getAddress();

    String getZipCode();

}
package com;

public class House implements IHouse {

    private IAddress address;

    @Override
    public void setAddress(IAddress address) {
        this.address = address;
    }

    @Override
    public IAddress getAddress() {
        return address;
    }

    @Override
    public String getZipCode() {
        return address.getZipCode();
    }
}
package com;

public interface IAddress {

    void setName(String string);

    void setZipCode(String string);

    String getZipCode();

    public abstract String getName();

}
package com;

public class Address implements IAddress {

    private String name;
    private String zipCode;

    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void setZipCode(String zipCode) {
        this.zipCode = zipCode;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getZipCode() {
        return zipCode;
    }
}

Look at our new code, think now where you will need to change if you need to remove the Address class. Only the Home class will be edited, the rest of our code will remain the same.

This is the greatest advantage of the Demeter law. When you have to do maintenance your project will have a small impact. The new features will be easily adapted, simpler code editions, and with a small cost. In code that we saw today only one class would be impacted. The other classes of your system would remain the same and your system will have a small coupling.

The disadvantage of this approach is an impact on the system performance. You may have a low performance if you use this approach in loops like “While, For, …” .In this case you will have to see which code of your system will not have the performance impacted with the Demeter law.

I believe that even with this disadvantage in the performance in some code pieces this approach is useful and worth of use it in our systems; Demeter law could be used in almost all code of our system.

I hope this post might help you

If you have any doubt or question just post it.

See you soon! o_

Tell, don’t ask.

Sometimes when we are programming OO we are facing some situations when we are tempted to put a value into an attribute in the fastest way. It happens because we have to deliver the code soon, or because we are doing a big change and don’t have a lot of time to expend in little details. So, it’s easier to be dominated by circumstances than analysing what we are doing.

Suppose we have a Door class and we want to know when it’s open or not but we want more, we want to change its state when it’s open we might close it and vice-versa. An easy way it would be to create a class and put a boolean attribute:

 public class Door {  
     private boolean doorIsOpen = false;  
}

So far we are ok, but now we can feel some danger. How are we going to make this attribute change its value? Shall we choose to let this attribute changing be handled by the Door class or by the object that is calling this Door Object? The most usual solution we can see in the market: is to make a get/set as the first programmers did a lot:

public void setDoorIsOpen(boolean doorIsOpen) {  
	this.doorIsOpen = doorIsOpen;  
}

public boolean getDoorIsOpen() {  
	return doorIsOpen;  
}  

// To close the Door  
if (door.getDoorIsOpen() == true)  
	door.setDoorIsOpen(false);  

// To open the Door
if (door.getDoorIsOpen() == false)  
	porta.setDoorIsOpen(true); 

Think with me, what if, this condition of questioning (if + get) and the set attribute value were in more than 30 places of your project, and the customer asks for a new business rule. How should it look? How would it be coded? Let’s supose that, the user wants the door closed. The Doors Alarm must be active:

  public class Door {  
       private boolean doorIsOpen = false;  
       private boolean alarmIsActive = true;  
       public boolean getAlarmIsActive() {  
            return alarmIsActive;  
       }  
  }  
  // To close the Door  
  if (door.doorIsOpen() && door.getAlarmIsActive ())  
       door.setDoorIsOpen(false); 

With this type of code, it would be necessary to change all project method that is using this code. Imagine all the hard work to change this code overall project…

To avoid all this hard work, just tell the object Door what to do, do not ask its attribute state and then changing it.

By applying this concept, this code change would happen only in one part of the project and the other 30 places would remain the same. The start code before the new customer request (activated alarm), would be like this:

  public class Door {  
      private boolean doorIsOpen = false;  
      private boolean alarmIsActive = true;  
      public boolean getAlarmIsActive() {  
           return alarmIsActive;  
      }  
      public boolean isOpen() {  
           return doorIsOpen;  
      }  
       public void closeDoor(){  
          doorIsOpen = false;  
       }  
       public void openDoor(){  
            doorIsOpen = true;  
       }  
  }   

The code to close the Door it would be simpler:

  // Closes the Door
  if (door.isOpen())  
       door.closeDoor();  
  // Opens the Door
  if (!door.isOpen())  
       door.openDoor();   

After this refactoring we just have to put the alarm condition inside the method that closes the Door; changing one line in one class and all the rest of the project will remain the same:

  public void closeDoor(){  
       if (alarmIsActive)  
            doorIsClose = false;
  }   

Now, every time that the business rule changes (like close the Door), we just have to change the method of a specific class and, all the project classes, will be intact.

By this principle, we lose coupling between the classes, and your code is ready to be used by all your project.

It’s a good tip!

Inspired by: “The pragmatic Bookshelf – Alec Sharp”

Edit: Refactor at last code. Tip by H. Fernandes (at porguese post)