我打破了"得墨忒耳法则"吗?

Jus*_*tin 11 oop refactoring object

我刚刚开始意识到得墨忒耳法则.

像很多事情一样,我意识到这是我已经在做的事情,但没有名字.虽然有几个地方我似乎违反了它.

例如...

我可能有一个Address对象:

public class Address : IAddress
{
   public string StreetAddress { get; set; }
   public string City { get; set; }
   public int Zip { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

和一个Customer对象:

public class Customer : ICustomer
{
   private IAddress address;

   Customer()
   {
      Address = null;
   }
   public string Name { get; set; }
   public IAddress
   {
      get
      {
         if (address == null)
         {
            address = new Address();
         }
         return address;
      }
      set
      {
         address = value;
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

好吧,这是假代码,所以你可能不必跳我使用IoC消除new Address()或任何东西,但它几乎是我正在做的一个例子.我没有包含接口,因为我希望它们是显而易见的.

然后我会在我的代码中使用它来代替int zip = customer.Address.Zip;customer.Address.City = "Vancouver";

据我了解,我通过操纵客户地址的详细信息违反了德米特定律.

然后,似乎框架也是如此.毕竟,不会解决.City.Length是违规?我应该在Address中添加方法来处理访问字符串属性吗?可能不是.那么,为什么地址混乱呢?

我真的不能只添加仅与客户相关的Address方法.我有会员,员工,受抚养人,供应商,雇主等等都有地址的对象.

有没有更好的方法来处理这个?如果我按照现在的方式使用Address,我会冒什么样的问题?

对于Java人员,如果有帮助,则Address类可能看起来更像以下内容:

public class Address extends AddressInterface
{
   private String m_city;

   public String getCity() { return m_city; }
   public void setCity(String city) { m_city = city; }
}
Run Code Online (Sandbox Code Playgroud)

我必须承认,customer.getAddress().setCity("Vancouver");戒指比customer.Address.City = "Vancouver";我的戒指更多.也许我应该转用Java一段时间.

Ian*_*cer 11

本文:http://haacked.com/archive/2009/07/14/law-of-demeter-dot-counting.aspx对您正在讨论的问题有很好的解释.

正如他所指出的那样,这不是一个点数计算练习,而是一个耦合问题.目前你CustomerAddress班级的联系太紧密.对于初学者,Customer不应该创建新地址,也许是Address使用构造函数传递.至于你是否应该使用多个点来访问地址的一部分,请阅读文章......

Martin Fowler:"我更喜欢将其称为Demeter的偶尔有用的建议."