使两个包尽可能松耦合的模式

Patterns for making two packages as loosely coupled as possible

所以我正在学习为软件设计的介绍构建解析器class。

我构建了一个 tokenizer 包,它将我的输入字符串拆分为值和类型都具有 getter 的 Token 对象。我还可以 return 当前令牌的值和类型的原始字符串。

我的 public 来自 Tokenizer 的界面目前看起来像这样。

public Tokenizer(Grammar rules, String input)
public Token getCurrentToken() {...} // Token has public getters similar to the two methods below
public String getCurrentValue() {...}
public String getCurrentType() {...}
public void nextToken() throws InvalidTokenException {...}
public void previousToken() {...}

在我的解析器中 class 我还有一个 TokenReceiver(接口)和一个 TokenizerAdapter class(实现 Receiver 和我的特定标记器)

  public void next();
  public Token getToken();
  public String getType();
  public String getValue();
  public Token getToken();
}

规则是解析中的每个不同步骤都必须使用不同的包来完成,这些包尽可能松散地耦合到其他包的任何实现细节,即理论上解析器应该使用 我找到的任何分词器(例如在Github上),而不仅仅是我自己的分词器实现,只要我为它制作一个适配器。

如果我从 Tokenizer 发回 Token 对象,那么我的解析器将必须了解 Token 对象(具体是 getter 方法),这会增加我的 Tokenizer 实现的耦合度。

直接发回字符串作为值和类型,然后在 Parser 包中创建另一个 Token class 并重新创建 Tokens 对象对我来说本能地感觉是错误的。适配器 class 中令牌的匿名内部 class 是否是一个好的解决方案?

我正在寻找什么样的模式或概念可以帮助我从 Tokenizer 引用我的 Tokens,同时保持与我的特定 tokenizer 实现的松散耦合。

抱歉,如果问题真的很愚蠢而且答案真的很明显,设计模式对我来说仍然非常抽象,我们正在学习其中的很多,我很难知道在不同情况下使用哪一个。

您是否考虑过以下问题

public interface Token {
   String getType();
   String getValue();
}

public interface Tokenizer {
   // either 
   Iterable<Token> parse(String input);

   // or
   Stream<Token> parse(String input);
}

public class GrammarTokenizer implements Tokenizer {
   private final Grammar grammar;

   // constructor 

   // method implementations 
} 

当您想在 类 之间传递一些对象同时试图避免 类 之间的紧密耦合时,实现接口可能会有所帮助。在您的情况下,也许创建一个令牌接口并从您的标记器和解析器引用该接口,而不是直接引用具体的令牌 Class(令牌 Class 应该实现令牌接口)。