Java:参数遍历?

bub*_*les 5 java refactoring

我有这个代码:

public class Compiler {

    public void compile(String template, Object o, Object params) {
         //...
        context(o, params);
         //...
    }

    private void context(Object o, Object params) {
         //...
         substitue(o, params);
         //...
    }

    private void substitue(Object o, Object params) {
         //...
         print(params);
         //...
    }

    private void print(Object params) {//use parameter params here, only here 
         //...
         System.out.println(params);
         //...
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,该参数params仅在方法中使用print,而不是在compile,context或 中使用substitue。问题是将 添加params到所有方法的签名中,直至print

一般来说,当我遇到这个问题时,我会重构我的代码,如下所示:

public class Compiler {


    public void compile(String template, Object o, Object params) {
        //...
        new InnerCompiler(template, o, params).compile();
        //...
    }

    private static class InnerCompiler {
        private final String template;
        private final Object o;
        private final Object params;

        InnerCompiler(String template, Object o, Object params) {
            this.template = template;
            this.o = o;
            this.params = params;
        }

        private void compile() {
            //...
            context();
            //...
        }


        private void context() {
            //...
            substitue();
            //...
        }

        private vois substitue() {
           //...
           print();
           //...
        }

        private void print() {
            //...
            System.out.println(this.params);
            //...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个非常基本的示例,用于说明将参数传递给所有方法的情况,即使该方法本身没有使用该参数,而是下一个(或更深层)方法使用该参数。

我正在寻找这个问题的名称(也许是反模式)。在标题中,我放置了(参数遍历),但它可能是错误的,或者它意味着另一件事。

ent*_*erd 2

您通过调用堆栈重复传递参数的代码的第一个版本称为“临时数据”。您可以在软件工程网站上的类似问题中阅读相关内容。我认为您想要做的是使用Dependency Injection。我说“尝试”是因为您没有将依赖项注入实例Compiler本身。

相反,我认为您实际使用的是有界上下文模式的一个非常小的版本。我的意思是,您的类是一个有界上下文,如领域驱动设计中所述,并且可能更恰当地命名为:。话虽这么说,有界上下文通常是域级构造,用于封装复杂的服务级数据集。一组三个参数通常不值得使用术语“有界上下文”,但在我看来,该阈值相当主观,并且为了易于理解的 MCVE,您可能会过度简化代码。InnerCompilerCompilerContext

为了以更标准的形式使用 DI 模式,我会将您的代码更改为如下所示:

public class Compiler {

  private final String template;
  private final Object o;
  private final Object params;

  Compiler(String template, Object o, Object params) {
    this.template = template;
    this.o = o;
    this.params = params;
  }

  public void compile() {
    //...
    context();
    //...
  }

  private void context() {
    //...
    substitute();
    //...
  }

  private void substitute() {
    //...
    print();
    //...
  }

  private void print() {
    //...
    System.out.println(this.params);
    //...
  }
}
Run Code Online (Sandbox Code Playgroud)

这实现了您现在正在做的事情,而无需诉诸人工内部类。

请注意,如果您确实需要像您的代码版本中那样将编译器之类的东西用作单例,请考虑使用带有调用构造函数并注入依赖项的方法的类CompilerFactorynewCompiler()

我希望这回答了你的问题。我知道这个答案不是四人帮的《设计模式》书中的模式,但在我看来,该书中的模式都没有真正反映您的代码或您的意图。