5

我最近一直在做一些阅读,并遇到了得墨忒耳法则。现在我读到的一些内容非常有道理,例如报童永远不能从顾客的口袋里翻出来,抓起钱包把钱拿出来。钱包是客户应该控制的东西,而不是报童

让我对法律感到困惑的是,也许我只是误解了整个事情,将属性与功能/信息的层次结构联系在一起可能非常有用。例如.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 很陌生,所以请放轻松:)

4

3 回答 3

6

得墨忒耳定律(也称为“函数/方法的得墨忒耳定律”)想要减少“只使用一个点”的说法是,在一种方法中,您不必从提供的参数中假设如此多的上下文。这增加了类的依赖性并使其不易测试。

这并不意味着您不能使用上述所有示例,但它建议不要将您的方法提供给客户,然后客户访问钱包并从中取回钱:

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
}

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

于 2011-08-02T21:40:19.797 回答
3

我认为将得墨忒耳法则应用于个别班级有点过分了。我认为更好的应用是将它应用到代码中的。例如,您的业务逻辑层不需要访问有关 HTTP 上下文的任何内容,并且您的数据访问层不需要访问表示层中的任何内容。

是的,设计对象的接口通常是一种好习惯,这样您就不必进行大量的属性链接,但是想象一下,如果您尝试对您提供的DataTableHttpContext类执行此操作,您将拥有极其复杂的接口例子。

于 2011-08-02T21:26:57.890 回答
1

法律并没有说你不应该在课堂上访问任何信息,但你应该只能以一种你不能轻易滥用它的方式访问信息。

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

DataTable.Columns.Count = 42;

取而代之的是,您可以使用对象的Add方法来Columns添加列,以使有关该列的所有所需信息都在那里,并且还可以使用该列的数据设置数据表。

于 2011-08-02T21:33:40.537 回答