【问题标题】:Law of Demeter confusion in JavaJava中的得墨忒耳法则混乱
【发布时间】:2017-09-15 12:35:22
【问题描述】:

我是否违反了“得墨忒耳法则”? 例如,我创建了一个包含姓名、电话和 ID 的班级人员,它与我的数据库中的列匹配。 当我想使用人的身份填写我的订单信息时。我喜欢这样。

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

我使用由 databaseComponent 返回的 getName 和 getPhone。这是中断 LoD。 有人建议我可以这样做

 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;
}

但我认为在公共方法中它仍然会破坏 LoD。有些人使用这种方法。

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

是的,也许它不会破坏 LoD。但是为什么呢?可能是Client 没有耦合到Person 类。但是它耦合到了Util。 LoD在这个场合有什么优势。

【问题讨论】:

    标签: java law-of-demeter


    【解决方案1】:

    LoD 说:

    更正式地说,函数的得墨忒耳定律要求对象 O 的方法 m 只能调用以下类型对象的方法:[2]

    O 本身

    m的参数

    在 m 中创建/实例化的任何对象

    O 的直接组件对象

    一个全局变量,可以被O访问,在m范围内

    您正在方法中创建对象(订单和人员);然后你调用它们的方法。或者更准确地说:您正在创建一个并实例化另一个。

    对我来说似乎很好 - 这里没有违反 LoD。

    我宁愿担心告诉不要问。您获取 Person 的所有这些属性以将其推送到 Order 中。为什么没有像public void setRecipient(Person p) 这样的订单类的方法?

    另一方面,这可能意味着破坏 Order 的单一职责。从这个意义上说,您的代码仍然可以,例如,如果在某个 SetupOrderService 支持类中找到。

    【讨论】:

    • 对象 person 是由 MyBatis 创建的。你的意思是等于我在我的方法中创建了一个人对象?我不确定。
    • 仔细阅读 - 它说“创建或实例化”。但我更新了我的答案,以便在这里更清楚。
    • 还有什么?我有一个名为 A 的类,它有 4 个字段。 field1 到 field 4.Then 在我的代码中,我像这样使用它们, if (souce == 1) A.setField1(value) else (source == 2) a.setField2(value) else if(source == 3) A.setField3(value) 否则 A.setFeild4(value).
    • 然后我想把它移到 A 类中。然后在 a.public void setField(int source,String value){ if()field = value else ...} 中有一个方法。是否违反了 SRP?以及如何做得更好?
    • @JainPing 请不要开始在 cmets 中问更多的事情。如果你有足够的内容,然后提出一个 new 问题(请随时给我留言)并在此处删除 cmets。在接近不可读的 cmets 中询问 other 内容是没有意义的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    相关资源
    最近更新 更多