“ Demeter法”是否适用于公共/ API方法签名?


10

鉴于对API /公共方法签名的更改应尽可能少,以防止破坏使用这些方法的客户端代码,我想知道Demeter法则是否不适用于这些方法。

一个简单的例子:

class Account() {
   double balance;
   public void debit(Transaction t) {
      balance -= t.getAmount();
   }
}

请注意,借记方法传递的是交易对象,而不是仅仅两倍的金额(据我所知,``德米特尔法则''会说只传递所需的信息,在这种情况下,只是传递金额,而不是交易对象... )。其背后的原因是因为将来该方法可能需要除数量之外的其他一些交易属性。据我了解,这将防止将来通过添加新参数来破坏方法签名。

那么,这是否使之成为明智的选择?还是我错过了什么?

Answers:


3

但这并没有违反Demeter定律。

更正式地讲,函数的Demeter定律要求对象O的方法M只能调用以下类型的对象的方法:

  • O本身
  • M的参数
  • 在M中创建/实例化的任何对象
  • O的直接组成对象
  • M范围内的O可以访问的全局变量

维基百科:得墨meter耳定律

事务是借记方法的一个参数,因此调用t.getAmount()很好。

编辑:误解了,您是说LoD会让您传递交易金额,而不是交易对象。如果是这样,那么是的,我想这是一个打破它的好地方,因为您知道将来您将需要从Transaction对象中获得更多的东西。同样,将原语封装在域级对象中也是另一种良好的编程习惯。

编辑2:阅读了将来可能需要的更多内容后,人们还可以将其视为不必要的镀金。提供一个现在需要加倍的方法(或更好的Money类)就足够了。如果以后确实需要使用Transaction参数,则提供第二个使用Transaction的签名并不是灾难性的,但是继续支持原始签名。并不是要实现两个方法,一个方法会调用另一个方法。


感谢您的输入。我同意在域对象中封装原语。但是,就您在Edit 2中的观点而言,您说添加新的第二个签名并不是灾难性的,但这意味着将代码更改为现在应该传递2个参数而不是一个参数的客户端代码。关于第二点,我有点犹豫要同意...
Carlos Jaime C. De Leon

我同意,编辑2是主观的。
肖恩

0

如果您打算Account将来扩展该类,那么我想说的是,使Transaction对象具有更广泛的用途将是对法律规则的良好弯曲。

例如:

public class Amount {

    public void process( Transaction t ) {
        ....
    }
}

public abstract class Transaction {

    public String getType();

}

我认为我对最初的问题有些偏离,但是我的观点是,尽管您可能担心自己偏离了《得墨meter耳定律》,但这样做的好处远大于缺点。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.