2011-08-02 16 views
5

私は最近いくつかの読書をしており、デメテルの法則に遭遇しました。今私が読んだことのいくつかは完璧な意味を持ちます。ペーパーポーは、顧客のポケットに銃をかけて、財布をつかんでお金を引き取ることはできません。財布は、顧客が管理するべきものであり、paperboyではありません。デメテルの法則とOOPの混乱

私は法律について迷惑を掛けていますが、おそらく私はすべてのことを誤解しているかもしれません。機能性/情報の階層構造とともにストリングプロパティーが非常に役立つかもしれません。例えば.NETのHTTPContextクラス。

は以下のようなコードではないでしょう:

If DataTable.Columns.Count >= 0 Then 
    DataTable.Columns(0).Caption = "Something" 
End If 

それとも

Dim strUserPlatform as string = HttpContext.Current.Request.Browser.Platform.ToString() 

それとも

If NewTerm.StartDate >= NewTerm.AcademicYear.StartDate And 
    NewTerm.EndDate <= NewTerm.AcademicYear.EndDate Then 
    ' Valid, subject to further tests. 
Else 
    ' Not valid. 
End If 

この法律を破ること?私は(おそらく誤って)OOPのポイントは、部分的に素敵な階層構造の関連クラスへのアクセスを提供することだと考えました。私が好きな

、例えば、電子メールを送信すると便利な文字列メソッドをカプセル化するなど、繰り返し作業を回避するために、ページクラスで使用できるユーティリティツールキットを参照のアイデア:

Dim strUserInput As String = "London, Paris, New York" 
For Each strSearchTerm In Tools.StringManipulation.GetListOfString(strUserInput, ",") 
    Dim ThisItem As New SearchTerm 
    ThisItem.Text = strSearchTerm 
Next 

はどれ透明性があることでしょう偉大な...現時点では法律がどのようにストリングのプロパティとメソッドを一緒に追い払うように見えるのかを調和させることはできません...それは私には奇妙なことです。私はかなりOOPを推測しているかもしれませんので、簡単に行ってください:)

+5

これらの「法律」は真の法律ではありません。熱力学の法則とは違って、好きな時に曲げたり折ったりできます。あなたが狂ってしまうのを止めるには、それをデメテルの「ガイドライン」と考えるようにしてください。あなたがそれを宗教的に従えば、それはあなたのために働くことになります。節度のあるすべてのこと...節度を含む。 –

+0

^---------それ! – Dan

+0

ありがとうバイナリ:) –

答えて

6

デメテルの法則(「関数/メソッドのデモータ」とも呼ばれる)は、「1つのドットのみを使用する」と言って減らそうとしているのは、メソッド内でそのような多くのコンテキストを提供された議論。これにより、クラスの依存関係が増加し、テスト可能性が低下します。

それはあなたが上記の例のすべてを使用できないことを意味するものではありませんが、それは示唆している代わりに、あなたの方法、その後の財布にアクセスし、そこからお金を取得し、顧客を与える:

function getPayment(Customer customer) 
{ 
    Money payment = customer.leftpocket.getWallet().getPayment(100); 
    ... 
    // do stuff with the payment 
} 

それが可能だ場合は、代わりにのみペーパーボーイ真夏の引力は、メソッドに必要なものを渡し、そのようにメソッドの依存を減らすこと:

function getPayment(Money money) 
{ 
    // do stuff with the payment 
} 

をそれからあなたの利益はあなたが財布を持っている顧客に依存してはいけないということになります左のポケットが代わりにちょうどproces顧客があなたに与える金額。それはあなたが個々のケースに基づいて判断しなければならない決定です。より少ない依存性により、より簡単にテストすることができます。

+0

ありがとうございました。それは、必要でないときにオブジェクトが別のオブジェクトについてあまり知ってはいけないということは、私には意味があります。最初の例を使用すると、将来的にそのシステムに挿入されるウィンドウクリーナーなどの他のクラスは、あなたが示唆している限り、同じMoney Pay = customer.leftpocket.getWallet()。getPayment(100)ステートメントを持つ必要があります。得意先にgetPaymentメソッドを提供します。 –

+0

+1:^ ---------そう!確かに :) –

3

私は個々のクラスにDemeterの法則を適用することは少し遠すぎると考えています。私はより良いアプリケーションはの層にあなたのコードでそれを適用することだと思う。たとえば、ビジネスロジックレイヤーはHTTPコンテキストに関するものにアクセスする必要はなく、データアクセスレイヤーはプレゼンテーションレイヤーにアクセスする必要はありません。

はい、それはあなたがそれを行うことを試みた場合は、プロパティチェーンのトンをしなければならないが、あなたが持っていると思い恐ろしく複雑なインターフェースを想像しないように、あなたのオブジェクトのインタフェースを設計する通常良い習慣ですあなたが例として挙げたDataTableHttpContextのクラスです。

+0

私は両方とも、ペーパーボイの例のようなクラスを設計するときには、実際に顧客の機能性が紙のボーイの一部になるべき状況を持たないようにすべきであり、あなたが提案する方法で別れた。 –

1

法律では、クラス内のどの情報にもアクセスするべきではないと言っているわけではありませんが、簡単に誤用しないように情報にアクセスする必要があります。

あなたが例えばCountプロパティに何かを割り当てることにより、データテーブルに列を追加することはできません。

DataTable.Columns.Count = 42; 

代わりに、あなたがそのように列を追加することができますColumnsオブジェクトのAddメソッドを使用します列に関する必要なすべての情報がそこにあり、データ表にその列のデータが設定されるようにします。