Обобщение функции в Java

#java #processing #generalization

#java #обработка #обобщение

Вопрос:

Как я могу обобщить pendulumManagement(), чтобы принимать в качестве аргументов имена запускаемых функций и логическое значение для выбора? Я использую java и библиотеку обработки.

 void pendulumManagement()
{
  if (pendul) {
    singlePendulumManagement();
  } else {
    dublePendulumManagement();
  }
}
 

Комментарии:

1. Объявите ее как void pendulumManagement(final Runnable onTrue, final Runnable onFalse) { if ( pendul ) { onTrue.run(); } else { onFalse.run(); } } , а затем вызовите ее как pendulumManagement(this::singlePendulumManagement, this::doublePendulumManagement) .

2. @fluffy Ваш метод не работает. У меня есть эти ошибки: imgur.com/a/qTqJ4O2

3. Ваш метод не работает. Вы читали, что я прокомментировал?

4. Я сделал то, что вы написали, но это не работает.

5. Итак, вы застряли в предварительной Java 8. Конечно, это не может работать для вас. Неважно.

Ответ №1:

Кажется, вы хотите использовать аргумент флага. Из этой статьи:

Аргумент флага — это своего рода аргумент функции, который сообщает функции выполнить другую операцию в зависимости от ее значения.

[…]

Моя общая реакция на аргументы флага — избегать их. Вместо того, чтобы использовать аргумент флага, я предпочитаю определять отдельные методы.

[…]

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

Я бы посоветовал еще раз подумать об этом выборе дизайна и пересмотреть, действительно ли вы должны делать это таким образом. В упомянутой выше статье содержится более подробная информация о случаях, подобных тому, который вы описываете.

Комментарии:

1. Вот как выглядит мой проект: github.com/Rafhub69/Everythig . Как бы вы это сделали?

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

3. Я вижу, что это не проблема XY. Это будет нелегко, если вы действительно этого хотите.

Ответ №2:

Хотя мне нравится обобщение как общее правило, я не думаю, что ваша программа выиграет от этого в этом случае. Тем не менее, я тоже чувствую привлекательность сокращения их до однострочных.

Вы все равно можете записать их как однострочные и получить аналогичный результат, например:

 if (pendul) { singlePendulumManagement(); } else { dublePendulumManagement(); }
 

Но проблема в том, что если вы используете автоформатирование, оно вернется к нескольким строкам. Другим вариантом было бы использовать оператор троичного присваивания ‘?’, Но для этого вам нужно, чтобы ваши методы имели возвращаемый тип и использовали его для присвоения значения, что было бы плохой практикой, если бы не было необходимости. Тем не менее, вот как это можно было бы сделать на простом примере:

 void setup() {
  size(800, 600);
  background(255);

  boolean isRect = true;
  boolean whatever;
  
  whatever = isRect ? drawRectangle() : drawCircle();
  isRect = false;
  whatever = isRect ? drawRectangle() : drawCircle();
}

void draw() {
}

boolean drawRectangle() {
  rect(100, 100, 200, 100);
  return true;
}

boolean drawCircle() {
  circle(600, 300, 100);
  return true;
}
 

В этом примере whatever логическое значение не имеет реальной цели, как и возврат метода, поэтому мне не нравится эта идея, но если бы ваши методы имели возвращаемые типы, вы могли бы реально использовать этот трюк, чтобы ваши вызовы выглядели так:

 boolean whatever;
switch(mode) {
case 1: //1 - gravitation
  whatever = field ? centralFieldManagement() : homogeneousFieldManagement();
  break;
case 2: //2 - pendulum
  whatever = pendul ? singlePendulumManagement() : dublePendulumManagement();
  break;
// etc etc..
}
 

Что, как я уже сказал, не очень хорошо. Если вы вообще не используете автоформат, использование первой формы (для записи if в одной строке) не только сработает, но и не сильно отличается от вашей первоначальной идеи с точки зрения строк, символов и количества аргументов.

Удачи!