「デメテルの法則」はパブリック/ APIメソッドの署名に適用できますか?


10

API /パブリックメソッドシグネチャへの変更は、これらのメソッドを使用するクライアントコードを壊さないようにするために最小限でなければならないので、デメテル法則はこれらにあまり適用されないのではないかと思っていました。

簡単な例:

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

debitメソッドは、2倍の金額ではなくTransactionオブジェクトを渡すことに注意してください( 'Law of Demeter'は、私が理解しているように、必要な情報だけを渡すと言います。この場合、Transactionオブジェクトではなく、金額だけを渡します... )。この背後にある理由は、将来のメソッドでは、金額の他にいくつかのトランザクションプロパティが必要になる可能性があるためです。私が理解していることから、これは将来的に新しいパラメータを追加することによってメソッドのシグネチャを壊すことを防ぎます。

これはそれを賢明な選択にしますか?それとも何か不足していますか?

回答:


3

しかし、これはデメテルの法則を壊しません。

より正式には、関数のデメテルの法則は、オブジェクトOのメソッドMが次の種類のオブジェクトのメソッドのみを呼び出すことを要求します。

  • O自体
  • Mのパラメータ
  • M内で作成/インスタンス化されたオブジェクト
  • Oの直接コンポーネントオブジェクト
  • Mのスコープ内でOからアクセス可能なグローバル変数

ウィキペディア:デメテルの法則

トランザクションは借方メソッドの引数であるため、t.getAmount()を呼び出しても問題ありません。

編集:誤解ですが、LoDはTransactionオブジェクトではなく、トランザクションの量を渡す必要があると言っています。その場合は、そうです。将来的にはTransactionオブジェクトからさらに必要になることを知っているので、これはそれを壊すのに適した場所だと思います。また、ドメインレベルのオブジェクトにプリミティブをカプセル化することも、プログラミングの優れたプラクティスです。

編集2:将来必要になる可能性があることを読んだ後、これを不要な金メッキと見なすこともできます。現在doubleを受け取るメソッド(または、より良いMoneyクラス)を提供することで十分です。後でTransaction引数が必要になった場合、トランザクションを取得する2番目の署名を提供することは悲惨ではありませんが、元の署名を引き続きサポートします。2つのメソッドを実装するのではなく、1つはもう1つを呼び出します。


ご入力いただきありがとうございます。ドメインオブジェクトのプリミティブのカプセル化について同意します。ただし、編集2でのポイントは、新しい2番目の署名を追加することは悲惨なことではないと言いますが、これは、1つではなく2つのパラメーターを渡す必要があるクライアントコードへのコード変更を意味します。その2番目の点、私は同意することに少しためらっています...
Carlos Jaime C. De Leon

編集2は主観的であると私は同意します。
Sean

0

Account将来クラスを拡大するつもりなら、これはTransactionオブジェクトをより一般的な目的にすることは法の規則をうまく曲げることになる状況だと思います。

例えば:

public class Amount {

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

public abstract class Transaction {

    public String getType();

}

私は元の質問から少し逸脱していると思いますが、私の意見は、あなたがデメテルの法則から逸脱していることを心配しているかもしれませんが、そうすることの利点はネガティブさを上回るということです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.