得墨忒耳定律和OOP混淆

时间:2011-08-02 21:11:22

标签: asp.net oop law-of-demeter

我最近一直在阅读并遇到了得墨忒耳法。现在,我所阅读的一些内容非常有意义,例如:报童应该永远不能通过顾客的口袋,抓住钱包并拿走钱。钱包是客户应该控制的,而不是paperboy

让我了解法律,也许我只是误解了整个事情,将字符串属性与功能/信息的层次结合起来是非常有用的。例如.NETs 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的新手,所以请放轻松:)

3 个答案:

答案 0 :(得分:6)

德米特定律(也是“函数/方法的德米特定律”)想要通过说“只使用一个点”来减少是因为在一种方法中你不应该假设这样的大量背景提供了论据。这增加了类的依赖性并使其不太可测试。

这并不意味着您不能使用上述所有示例,但它建议客户不再使用您的方法访问钱包并从中检索钱:

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

您只需将paperboy所需的内容传递给方法,如果可能的话,减少方法的依赖性:

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

您的好处将是您不依赖于客户将钱包放在左侧口袋中,而只是处理客户给您的钱。这是你必须根据个人情况做出的决定。较少的依赖性使您可以更轻松地进行测试。

答案 1 :(得分:3)

我认为将德米特法应用于个别课程的时间有点太过分了。我认为更好的应用程序是将其应用于代码中的 layers 。例如,您的业务逻辑层不需要访问有关HTTP上下文的任何内容,并且您的数据访问层不需要访问表示层中的任何内容。

是的,通常通常是设计对象界面的好习惯,这样你就不需要进行大量的属性链接,但想象一下如果你尝试过的那么可怕的复杂界面要对您提供的DataTableHttpContext类作为示例执行此操作。

答案 2 :(得分:1)

法律并未规定您不应该在课堂上访问任何信息,而是只能以不容易滥用信息的方式访问信息。

例如,您可以通过为Count属性分配任何内容来在数据表中添加列:

DataTable.Columns.Count = 42;

而是使用Add对象的Columns方法,该方法允许您以一种所有需要的有关列的信息的方式添加列,并且还可以设置数据表该列的数据。