Java: Обход параметров? - PullRequest
       3

Java: Обход параметров?

3 голосов
/ 10 января 2020

У меня есть этот код:

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);
         //...
    }
}

Как видите, параметр 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);
            //...
        }
    }
}

Это очень простой c пример, иллюстрирующий случай передачи параметра ко всем методам, даже если он используется не самим методом, а следующим (или более глубоким).

Я ищу название этой проблемы (возможно, анти-паттерн) . В заголовке я поставил (Обход параметров) , но это может быть не так или означать другое.

Ответы [ 2 ]

0 голосов
/ 17 января 2020

Мне кажется, что вы пытаетесь изменить передачу параметров в глобальное состояние.

0 голосов
/ 14 января 2020

Первая версия вашего кода, в которой вы неоднократно передавали параметры через стек вызовов, называется «бродячими данными». Вы можете прочитать об этом в аналогичный вопрос на сайте Software Engineering . Я думаю, вы пытаетесь использовать Dependency Injection . Я говорю «пытаюсь», потому что вы сами не внедряете свои зависимости в Compiler экземпляр.

Вместо этого я бы сказал, что на самом деле вы используете действительно маленький версия шаблона ограниченного контекста . Под этим я подразумеваю, что ваш класс InnerCompiler является ограниченным контекстом, как описано в «Управляемом доменом дизайне», и может иметь более точное название: CompilerContext. При этом ограниченные контексты обычно представляют собой конструкции уровня домена, которые вы используете для инкапсуляции сложных наборов данных уровня обслуживания. Набор из трех параметров обычно не заслуживает термина «ограниченный контекст», но этот порог является довольно субъективным IMO, и вы могли бы упростить свой код здесь ради понятного MCVE.

Для использования шаблон 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);
    //...
  }
}

Это позволяет добиться того, что вы делаете сейчас, не прибегая к искусственному внутреннему классу.

Обратите внимание, что если вам действительно нужно что-то вроде компилятора для использования в качестве синглтона, как в вашей версии кода, рассмотрите возможность использования класса CompilerFactory с методом newCompiler(), который вызовет конструктор и внедрит зависимости.

Я надеюсь, что это отвечает на ваш вопрос. Я знаю, что этот ответ не является шаблоном из книги «Шаблоны проектирования» «Банды четырех», но IMO ни один из шаблонов в этой книге действительно не отражает ваш код или ваше намерение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...