Шаблон команды против отражения

У меня есть контроллер, который выполняет некоторые команды в соответствии с именем команды, взятым из URL-адреса. Суть в том, чтобы не использовать предложения if и switch. Насколько я знаю, есть ТОЛЬКО два способа сделать это - 1) шаблон команды 2) отражение.

//Command pattern
class Controller{
  private HashMap<String,Command> commands;
  public void executeCommand(String commandName){
    commands.get(commandName).execute();
  }
  ...
}

//reflection
class Controller{
  public void readCommand(){
    ....
  }
  public void executeCommand(String commandName){
    this.getClass().getMethod(commandName+"Command").invoke(this);
  }
  ...
}

Итак вопросы:

  1. Какой лучше?
  2. Нормально ли в одном приложении позволять разработчикам использовать один из методов, которые они хотят.
  3. Есть ли другие способы?

person Community    schedule 21.11.2014    source источник
comment
Что произойдет, если пользователь введет execute? Приведет ли это к тому, что executeCommand попытается вызвать себя рекурсивно? Использование отражения таким образом, когда вы используете строку, введенную пользователем, чтобы определить, какое имя метода следует выполнить, выглядит очень опасным. С таким же успехом можно было бы поставить на своей программе табличку с надписью Эй, киберпреступники! СЮДА!!!   -  person ajb    schedule 21.11.2014
comment
@ajb Спасибо за ваш комментарий. Я это знаю, поэтому мы используем сопоставитель URL через xml (url ->component,command). Я написал взято из URL, чтобы передать идею.   -  person    schedule 21.11.2014


Ответы (3)


  1. первый способ лучше, используйте отражения только тогда, когда нет других вариантов.
  2. в одном приложении должен быть один подход к решению одного вида задач.
  3. Я думаю, что первый подход хорош. (гораздо лучше, чем блоки if/else)
person Kamil.H    schedule 21.11.2014

Какой лучше?

Понятно, что первый лучше. Несмотря на то, что вы указали, что используете шаблон Command, это не полный шаблон «Command». Шаблон команды будет иметь команду (абстрактную), конкретную команду, получателя, вызывающего и клиентского.

Взгляните на этот вопрос:

Использование шаблона проектирования команд

Помимо Command Patten, я хотел бы выделить плюсы и минусы рефлексии.

Плюсы:

  1. Обработка внедрения зависимостей
  2. Разработка фреймворков plug and play

Минусы:

  1. Вызовы отражения медленнее
  2. Вы можете нарушить безопасность и взорвать приложение с плохим намерением (например, установив частные переменные класса, которые невидимы для другого класса)

Взгляните на связанный вопрос SE относительно Reflection :

Что такое отражение и почему оно полезно?

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

Разработчики обычно выбирают лучший метод для решения конкретной проблемы.

Есть ли другие способы?

Это зависит от типа проблемы, которую вы собираетесь решать. Шаблоны проектирования обеспечивают решения повторяющихся проблем.

Все решения не могут быть вписаны в существующие шаблоны проектирования. Возможно, вы разработали новые шаблоны для решения вашей проблемы.

person Ravindra babu    schedule 11.02.2016

Я думаю, что есть 2 разных способа для вашего первого подхода. Каждая команда может быть подклассом абстрактного класса Command. Или каждая команда может быть экземпляром команды класса. Это зависит от того, насколько гибким все это должно быть, и являются ли параметры и возвращаемые значения для команд? С подклассами это будет выглядеть так (просто для понимания):

abstract public class Command {
    abstract public void execute();
}

public class LsCommand extends Command
{
    @Override
    public void execute() {
        try {
            Runtime.getRuntime().exec("ls");
        } catch (IOException e) {}
    }
}

public class ChdirCommand extends Command
{
    @Override
    public void execute() {
        try {
            Runtime.getRuntime().exec("chdir");
        } catch (IOException e) {}
    }
}

Вот мои ответы:

  1. Ваш первый способ лучше. Всегда предпочитайте шаблоны проектирования отражениям.
  2. Извините, я не понимаю вопрос 2. Но в нем все равно нет вопросительного знака, поэтому я просто пропускаю его :)
  3. Вы можете изучить шаблон разработки стратегии, где каждая команда может даже состоять из разных частей. подкоманд. Другой идеей может быть шаблон проектирования Factory. В этом случае вы должны поместить каждую команду в класс, а затем использовать ClassLoader для загрузки класса по имени.
person Kenyakorn Ketsombut    schedule 21.11.2014
comment
Спасибо за ваш ответ. Мне кажется, вы немного неправильно поняли вопрос. Шаблон команды о том, как динамически выбирать нужный метод по строке. Например, строка aaa - method1(),bbb - method2() без использования if и переключателей. - person ; 21.11.2014