简体   繁体   English

去耦-OOP

[英]Decoupling - OOP

I have a simple question (working with Java). 我有一个简单的问题(使用Java)。 I have two classes, one represents a Document, a second represents a Word. 我有两个类,一个代表一个文档,第二个代表一个单词。

The Document class needs to know some info about the words that is kept in Word. Document类需要了解有关Word中保留的单词的一些信息。 My question is, what's the best way to decouple the two classes? 我的问题是,分离两个类的最佳方法是什么? I have 2 options in mind: 我有两个选择:

  1. Have no connection between the classes, and each time I call a method in Document, I pass it an object of Word (so I have a third class with a main method that initiates both Document and Word). 这些类之间没有连接,并且每次我在Document中调用一个方法时,都会向它传递Word的对象(因此,我有第三个类,它具有同时启动Document和Word的main方法)。

  2. Declare a private object of Word inside Document. 在文档中声明Word的私有对象。

One thing to note, I only have one object for Word and one for Document. 需要注意的一件事,我对于Word只有一个对象,对于文档只有一个对象。 I don't create a new object for every new document or word. 我不会为每个新文档或单词创建一个新对象。 I store a list of the entire documents in Document, and a list pf the entire words in Word. 我在文档中存储了整个文档的列表,在Word中存储了整个单词的列表。

Thanks! 谢谢!

I don't agree with your understanding of Decoupling. 我不同意您对解耦的理解。 Decoupling is not just about which objects create other objects, it's also about which objects know about the behaviour of other objects and (crucially) what needs to change in (your example) Document if Word changes. 解耦不仅涉及哪些对象创建其他对象,还涉及哪些对象了解其他对象的行为,以及(至关重要)如果Word发生更改(您的示例)文档中需要更改的内容。

However, also I really don't understand what your mean by these two phrases: 但是,我也真的不明白这两个短语的意思:

I only have one object for Word and one for Document. 我只有一个对象用于Word,一个对象用于文档。 I don't create a new object for every new document or word. 我不会为每个新文档或单词创建一个新对象。 I store a list of the entire documents in Document, and a list pf the entire words in Word 我将整个文档的列表存储在文档中,并将整个单词的列表存储在Word中

Start from Document. 从文档开始。 What can objects of this class do? 此类对象可以做什么? You seem to be saying that 你好像是在说

class Document {

     private List<??OfWhat??> allDocuments;
}

If class Document contains a List, what's it a List of? 如果Document类包含一个List,它的List是什么? I think you need: 我认为您需要:

class Shelf {
      private List<Document> allDocuments;
}

class Document{
      private List<Word> wordInOneDocument;
}

class Word {
      private String wordContents;
}

Now a Shelf could offer methods such as getRecentDocumets() findDocumentsContaining(String text) and Document could contain getWordCount() and insertParagraph(List, START); 现在,一个架子可以提供诸如getRecentDocumets()findDocumentsContaining(String text)之类的方法,而Document可以包含getWordCount()和insertParagraph(List,START); and so on. 等等。

To have a better discussion we need to see a bit more of what you had in mind, a bit more about behaviour. 为了进行更好的讨论,我们需要更多地了解您的想法,更多地了解行为。

I do agree with your general thought that there is Something other than Document and Word out there. 我确实同意您的一般想法,即文档和Word之外还有其他内容。 Something that can reasonably invoke methods such as createDocument() and insertParagraph() 可以合理调用诸如createDocument()和insertParagraph()之类的方法的东西

From my point of view... 从我的角度来看...

public class Document{

  private List<Word> words = new ArrayList<Word>();

  public void setWord(ArrayList<Word> words){this.words = words;}
  public ArrayList<Word> getWord(return this.words;)
}

It's a reasonable approach. 这是一个合理的方法。 In this example you can create a Document without any Word's , which makes for an empty Document, which is valid. 在此示例中,您可以创建一个不带任何Word's Document ,这将使一个空文档有效。

You could still create a third class as you suggest, however, I don't see the benefit with it. 您仍然可以按照您的建议创建第三类,但是,我看不到它的好处。

Your problem should be solved by composition. 您的问题应该通过组成解决。 Thus having a List of Word seems to be a valid approach. 因此,拥有Word列表似乎是一种有效的方法。 By separating out Documents and Words, you have already achieved the required de-coupling. 通过分离文档和单词,您已经实现了所需的去耦。 I do not get your exact point of de-coupling Document and Word objects. 我不了解将文档和Word对象分离的确切含义。

Your question is 你的问题是

what's the best way to decouple the two classes? 分离两个类的最佳方法是什么? I have 2 options in mind: 我有两个选择:

Neither option satisfies your request. 两种选择均不能满足您的要求。 If they are going to work together, then they are going to be coupled. 如果他们要一起工作,那么他们将被耦合在一起。 The only thing is how tight or loose the coupling is. 唯一的问题是联轴器有多紧或松动。

Both of your options sound like tight coupling. 您的两种选择听起来都像是紧密耦合。 A form of looser coupling would be to store an interface reference and take it in on a constructor or setter method. 松散耦合的一种形式是存储interface引用,并将其引入构造函数或setter方法中。

If you want to decouple the classes, one standard way is to use an interface: 如果要解耦类,一种标准方法是使用接口:

public interface IWord {
...
}

public class Word implements IWord {
...
}

public class Document {
    public boolean append(IWord word) { ... }

    ...
}

This way both Class and Word depend on IWord, but neither class nor Word depends on the other. 这样,Class和Word都依赖于IWord,但是class和Word都不依赖于另一个。 This is known as Dependency Inversion. 这就是所谓的依赖倒置。

Well first of all I think you're naming your classes incorrectly. 首先,我认为您对课程的命名不正确。

I don't create a new object for every new document or word. 我不会为每个新文档或单词创建一个新对象。 I store a list of the entire documents in Document, and a list pf the entire words in Word. 我在文档中存储了整个文档的列表,在Word中存储了整个单词的列表。

Judging by what you said here you have something like this: 从您在这里所说的话来看,您有这样的事情:

public class Words {
    private List<Word> = new ArrayList<Word>;
    // getters+setters
}

public class Documents {
    private List<Document> = new ArrayList<Document>;
    // getters+setters
}

And you want to use the Words class in the Documents. 您想在文档中使用Words类。 If you want to do that, that means you can't decouple it (as it's against the very definition of the word "decouple"). 如果要这样做,则意味着您不能将其解耦(因为这与“解耦”一词的定义完全相反)。 I'm guessing here again, but I think you want to code it so you can change the implementation of the Documents class so in the future it could use another class like for example BetterWords. 我再次在这里猜测,但我想您想对其进行编码,以便可以更改Documents类的实现,以便将来可以使用另一个类,例如BetterWords。

In order to do that I would create either an abstract class or an interface (depending on the rest of your architecture) and then make the Words class either extend it or implement. 为此,我将创建一个抽象类或一个接口(取决于您的体系结构的其余部分),然后使Words类扩展或实现它。 Then you can do something like this: 然后,您可以执行以下操作:

public class Documents {
    private List<Document> = new ArrayList<Document>;

    private IWords wordsInterface = new Words(); //in case you want to make an interface
    private AbstractWords wordsAbstract = new Words(); //in case you want to make an abstract class

    // getters+setters
}

Or you can put it in the Document class (the words), don't really know where you want them. 或者,您也可以将其放在Document类(单词)中,而不真正知道它们的位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM