得墨忒耳定律 - 为什么我需要使用吸气剂?

win*_*ama 5 java list law-of-demeter

我有一个关于Demeter法与Java中其他对象中包含的列表相关的问题.我有以下课程.

public class Conversation
{
    Person person;
    List<Message> conversationList;

    public List<Message> getConversationList()
    {
        return conversationList;
    }
}
Run Code Online (Sandbox Code Playgroud)

要向此类中的conversationList添加新的Message对象,我通常会执行以下操作.

Conversationc = new Conversation();
c.getConversationList().add(new Message());
Run Code Online (Sandbox Code Playgroud)

经过一段时间的阅读后,这似乎违反了得墨忒耳定律,并且如下所述为Converstaion添加了一种方法,这将是"更好"的方法.

public List<Message> addMessageToList(Message msg)
{
    conversationList.add(msg);
}
Run Code Online (Sandbox Code Playgroud)

然而,这对我来说似乎完全矫枉过正.在这种情况下,最佳做法是什么?

dre*_*ore 9

然而,这对我来说似乎完全矫枉过正.

啊,我记得在我刚开始的时候反复问自己这个问题 - 当时封装这个词是我为测试学到的东西,但并没有真正理解它的"必要性".

我这样说是因为封装是我们在这里谈论的 - 对你的问题的单词答案:

conversationList通过getter访问- 这是您在此处发布的第二种模式 - 将会话列表封装在对话类中.当你正在编写的程序有三到四个顶级并且要求既简单又固定时,很难理解为什么这很重要:当你仍然围绕这些小程序如何工作时,这整个概念"添加一个吸气剂"而不是直接访问字段似乎只是还有一件事要做,还有一件事你不明白你为什么要这么做,还有一个地方你可以搞砸了.

当然,这种感觉会随着你变得更加自信而消失,而其他一些事情将会发生,你将开始思考和研究更大,更复杂的应用程序,并且它们的需求会发生变化(在实际和随着时间的推移,这对他们的感知,这通常意味着你的程序需要改变 - 而且当封装开始变得非常有意义时:

现在:假装你的老师改变了他明天给你的这项任务,为你正在研究的这个项目添加了一个无法预料的要求(顺便说一下,我认为这对教师来说是一件明智的事).想象一下,您可以满足该要求的唯一方法是将对话列表保留为a Map而不是a List,这样您就可以将每个对话列表映射到其他值.

如果你一直在使用"你的第一种方法" - 调用conversationsList.add()直接在许多不同的类中访问该字段,那么你将不得不通过并改变每个类来调用conversations.put()而不是.add().

但是如果你一直在使用第二种方法 - 通过getter访问你的集合 - 那么你可以更改你需要的那个集合,而你只需要做一次更改 - 到那个getter:

 public void addMessageToList(Message msg)
{
    this.myMessagesManager.put(msg, new ArrayList<SomeValue>);
    //or .put(msg, null) or whatever
}
Run Code Online (Sandbox Code Playgroud)

你的其他课程永远不会知道任何改变,这很好,因为这意味着你写的代码更少,特别好,因为它让你不必做很多最糟糕的编码 - 所有的头发和gnashing牙齿经常涉及捕捉由于你在对其中一个类别进行这些小改动之一时所犯的小错误而产生的错误.

(另请参阅我对此问题的回答以获得更好的说明)

  • 好答案.所以,如果我想引入一个返回消息列表的getMessageList()方法.我应该使这个返回的列表不可变,所以它不能在Conversation类之外修改吗?或者我应该在这里做些不同的事情? (2认同)