#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 в одной строке) не только сработает, но и не сильно отличается от вашей первоначальной идеи с точки зрения строк, символов и количества аргументов.
Удачи!