有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

用于消息/名称定义的java巨型构造函数

我想在我的lexer和parser中都可以自定义名称和消息。解析器/词法分析器必须能够选择特定的消息或名称,例如:

messageManager.tokenName.eofToken

在这里,eofToken将是一个StringtokenName将是lexer标记的一组名称,messageManager将是类似{ parserMessage, lexerMessage, contextName, tokenName }的结构

然而,我希望消息定制非常直接地构建。我不想要这样的东西:

TokenName tokenName = new TokenName();
tokenName.eofToken = "end of file";
tokenName.identifier = "identifier";
tokenName.keyword = "keyword";
tokenName.regExpLiteral = "regexp' literal";
// much more...

我想要这样的东西:

new TokenName(
    "end of file",
    "identifier",
    "keyword",
    ...
)

我知道我们只需要定义参数并将它们分配给相应的变量,但我不想要一个像我之前的解析器中那样庞大的构造函数:

public TokenNames(
    String booleanLiteral,
    String eofToken,
    String identifier,
    String punctuator,
    String keyword,
    String numericLiteral,
    String nullLiteral,
    String regExpLiteral,
    String stringLiteral,
    String xmlName,
    String xmlMarkup,
    String xmlPunctuator,
    String xmlTagCharacters,
    String xmlText
)
{
    this.booleanLiteral = booleanLiteral;
    this.eofToken = eofToken;
    this.identifier = identifier;
    this.punctuator = punctuator;
    this.keyword = keyword;
    this.numericLiteral = numericLiteral;
    this.nullLiteral = nullLiteral;
    this.regExpLiteral = regExpLiteral;
    this.stringLiteral = stringLiteral;
    this.xmlName = xmlName;
    this.xmlMarkup = xmlMarkup;
    this.xmlPunctuator = xmlPunctuator;
    this.xmlTagCharacters = xmlTagCharacters;
    this.xmlText = xmlText;
}

我相信使用数组或varargs(更可读)是可能的。怎么做


共 (2) 个答案

  1. # 1 楼答案

    当然,builder模式是这里最明显的解决方案(也是正确的解决方案)

    但我想提请大家注意,有很多字段可以用它们自己的类进行封装

    以下字段可以收集到XMLDescription类中:

    String xmlName;
    String xmlMarkup;
    String xmlPunctuator;
    String xmlTagCharacters;
    String xmlText;
    

    下一个可以按LiteralDescription类分组:

    String numericLiteral;
    String nullLiteral;
    String regExpLiteral;
    String stringLiteral;
    

    再仔细考虑一下这个问题:如果有机会将字段数缩短到3(根据良好实践,这是一个极限界限),可以使用构造函数而不是生成器

    I believe it's possible with arrays or varargs (more readable).

    请不要这样做——这是一种容易出错的方法。将数组的索引与相应的字段耦合。这样的代码很难维护和记录,会导致API用户

    • 阅读提供的文件(如有)
    • 在没有提供的情况下,查看来源
    • 遵循API的任何更改,相信什么都没有更改
  2. # 2 楼答案

    这样定义类:

    public class Token {
    
        private String booleanLiteral;
        private String eofToken;
    
        ...
    
        public Token withBooleanLiteral(String booleanLiteral) {
          this.booleanLiteral = booleanLiteral;
          return this;
        }
    
        public Token withEofToken(String eofToken) {
          this.eofToken = eofToken;
          return this;
        }
    
        ...
    
      }
    

    你会得到

    Token token = new Token()
        .withBooleanLiteral("something");
    

    查看Lombok库和@Wither注释。它为你做了一切