所以我正在学习为软件设计入门课构建一个解析器。
我已经构建了一个tokenizer包,它将我的输入字符串分割成Token对象,这些对象都有对应值和类型的getter。我还可以返回当前令牌的值和类型的原始字符串。
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() {...}
在我的Parser类中,我也有一个TokenReceiver(接口)和一个TokenizerAdapter类(实现Receiver和我的特定tokenizer)
public void next();
public Token getToken();
public String getType();
public String getValue();
public Token getToken();
}
规则是解析中的每个不同步骤都必须与不同的包一起完成,这些包与其他包的任何实现细节尽可能松散耦合,即解析器理论上应该与任何一起工作。我找到的tokenizer(例如在Github上),不仅仅是我自己的tokenizer实现,只要我为它做一个适配器。
如果我从Tokenizer发送回Token对象,那么我的解析器将不得不知道Token对象(特别是getter方法),这将为我的Tokenizer实现增加耦合。
直接发回值和类型的字符串,然后在Parser包中创建另一个Token类并重新创建Token对象,对我来说直觉上是错误的。在适配器类中为Token提供匿名内部类是一个好的解决方案吗?
我正在寻找什么样的模式或概念可以帮助我从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
}
当您想要在类之间传递一些对象,同时试图避免类之间的紧密耦合时,实现接口可能会有所帮助。在您的情况下,也许可以创建一个令牌接口,并从您的令牌器和解析器中引用该接口,而不是直接引用具体的令牌类(令牌类应该实现令牌接口)。