Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Law of Demeter confusion in Java

Am I breaking the “Law of Demeter”? For example i create a Class person which contains name, phone and id and it match the column in my database. When I want to fill my Order info using person's id.I do like this.

 public static void fill(Order order) {
    DatabaseComponent databaseComponent = new DatabaseComponent();
    Person person = databaseComponent.getById(order.getUserId());
    order.setName(person.getName());
    order.setPhone(person.getPhone());
}

I use getName and getPhone return by databaseComponent.That's break LoD. Somebody recommend that I can do like this

 public void fill(Order order) {
    DatabaseComponent databaseComponent = new DatabaseComponent();
    Person person = databaseComponent.getById(order.getId());
    fillOrder(order,person);

}
private void fillOrder(Order order,Person person){
    order.setPhone(person.getPhone());
    order.setName(person.getName());
    return;
}

But I think in public method it still break the LoD.Some people use this method.

public class Util {
public static void fillOrder(Order order,Person person){
    order.setPhone(person.getPhone());
    order.setName(person.getName());
    return;
}}

Yeah Maybe it doesn't break LoD. But why?May be Client isn't coupled to the class Person.But it is coupled to Util. What are the advantages of LoD on this occasion.

like image 873
JainPing Avatar asked Sep 15 '17 12:09

JainPing


1 Answers

LoD says:

More formally, the Law of Demeter for functions requires that a method m of an object O may only invoke the methods of the following kinds of objects:[2]

O itself

m's parameters

Any objects created/instantiated within m

O's direct component objects

A global variable, accessible by O, in the scope of m

You are creating objects in your method (order and person); and then you call methods on them. Or to be precise: you are creating one and instantiating another one.

Seems fine to me - no violation of LoD here.

I would rather be worried about tell don't ask here. You fetch all these properties of a Person to push that into an Order. Why not have a method on the order class like public void setRecipient(Person p) or something alike?

On the other hand, that could mean to break the single responsibility of Order. In that sense your code could still be ok, for example if to be found within some SetupOrderService support class.

like image 89
GhostCat Avatar answered Oct 02 '22 19:10

GhostCat