java: длинный список условий, что делать?

Мне нужно предложение для правильного подхода к применению условий на Java.

У меня есть 100 условий, на основе которых мне нужно изменить значение переменной String, которое будет отображаться пользователю.

an example condition: a<5 && (b>0 && c>8) && d>9 || x!=4

Больше условий, но переменные одинаковы.

Я делаю это прямо сейчас:

    if(condition1)
    else if(condition2)
    else if(condition3)
    ...

Очевидно, что альтернативный вариант коммутатора будет вложен в if-else's i.e.

if(condition1)
 switch(x)
  {
   case y:
     blah-blah
   }        
else if(condition2)
switch(x)
  {
   case y:
     blah-blah
   }  
else if(condition3)
...

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

<Р> --- Edit ---


enter image description here

Я действительно требую этого на устройстве Android. Но здесь больше построена java.

This is a small snapshots of conditions that I have with me. More will be added if a few are correct. That obviously would require more if-else's and those could be nested also. In that case would the processing go slow.

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

8
nl ja de
Помечено как дубликат stackoverflow.com/questions/1199646/& hellip; - такой очень похожий вопрос был задан в ближайшее время - stackoverflow.com/questions/14136721/…
добавлено автор SpaceTrucker, источник
@pKs Почему следует учитывать производительность, если эти условия используются для пользовательских взаимодействий, которые, естественно, являются очень медленным видом ввода-вывода?
добавлено автор SpaceTrucker, источник
@SpaceTrucker Это на самом деле ситуация, когда я должен обновить элемент пользовательского интерфейса на основе выполнения условия. Больше времени требуется для проверки и обхода в случае, если что-либо или в любом случае.
добавлено автор Prateek, источник
@radai Производительность, как всегда, очень важна для меня, вы правы, она будет деградировать, избегая if-elses.
добавлено автор Prateek, источник
Мне кажется, что у вас слишком много условий. Я думаю, что ваш дизайн должен быть улучшен, добавьте некоторые подробности о задаче высокого уровня, которую вы хотите выполнить с помощью этого кода
добавлено автор mariosangiorgio, источник
pKs - тогда это выдает из окна какой-либо механизм классификации/правила. таблица поиска, предложенная ниже @thkala, является вашим лучшим вариантом, и она может работать быстрее, в зависимости от того, насколько быстро вы можете сгенерировать ключ, учитывая входные данные
добавлено автор radai, источник
насколько важна производительность для вас? потому что некоторые из более «элегантных» решений с точки зрения гибкости и удобочитаемости будут хуже, чем уродливое дерево, если if-elses
добавлено автор radai, источник
IMHO этот вопрос более подходит для codereview.stackexchange.com
добавлено автор Slava Semushin, источник
Я не уверен в том, чтобы избегать строк кода. Но для повышения производительности, более частые случаи в верхней части?
добавлено автор Bharath Mg, источник

4 ответы

В зависимости от количества условных входов вы можете использовать справочную таблицу или даже HashMap , кодируя все входы или даже некоторые относительно простые сложные условия в одном значении:

int key = 0;

key |= a?(1):0;
key |= b?(1<<1):0;
key |= (c.size() > 1)?(1<<2):0;
...

String result = table[key];//Or result = map.get(key);

Эта парадигма обладает дополнительным преимуществом постоянной сложности ( O (1) ), что может быть важно в некоторых случаях. В зависимости от сложности условий у вас может быть даже меньше ветвей в кодовом пути в среднем, в отличие от полного кода if-then-else спагетти, что может привести к повышению производительности.

Возможно, мы сможем помочь вам, если вы добавите больше контекста к своему вопросу. Откуда берутся исходные данные? Какие они?

And the more important question: What is the actual problem that you are trying to solve?

7
добавлено
Я думаю, что это будет трудно поддерживать, потому что в итоге вы получаете длинную последовательность утверждений, где один сам оператор является сложным. Поскольку эти условия используются для пользовательских сообщений, они могут подвергаться изменениям довольно часто. Таким образом, вы создадите точку доступа для обслуживания в своем коде.
добавлено автор SpaceTrucker, источник
@thkala Хотя мой вопрос был закрыт, и я принял ваш ответ, мне все еще нужно предложение относительно создания класса, полного публичных статических строковых сообщений. Должен ли я это делать или нет?
добавлено автор Prateek, источник
@thkala Извините за мой поздний ответ и спасибо за ваше предложение. Сообщение, которое я хочу отобразить, исправлено. Но, как вы предложили таблицу поиска, я собираюсь рассмотреть то же самое для нее. Но что, если бы я просто использовал if-elses, где бы я на самом деле отставал.
добавлено автор Prateek, источник
Я дам ему попробовать.
добавлено автор Prateek, источник
@thkala В принципе это здорово, но я не уверен, как вы можете применить его к конкретному вопросу, где есть возможно более 32 a, b, c ... условий. И я согласен с другими комментариями, что это может быстро стать беспорядком.
добавлено автор assylias, источник
@SpaceTrucker: Я согласен в принципе, хотя это будет зависеть от того, как код действительно выложен и для чего именно он используется. Вполне вероятно, что, как только ОП сообщит нам, что именно это все, мы найдем более элегантное решение для решения задачи высокого уровня, вместо того, чтобы попытаться существенно ответить на вопрос «Как можно кодировать сложный логическая таблица в Java? "
добавлено автор thkala, источник
@pKs: Это зависит ... что действительно отделяет строки от остальной части вашего кода, но это создает несколько проблем модульности. Вы действительно хотите, чтобы все классы в вашем приложении вытаскивали их строки? Если бы я был вами, я бы сначала взглянул на то, как приложения Android поддерживают интернационализацию. Скорее всего, вам придется сделать это в какой-то момент, так почему бы не сделать это правильно с самого начала?
добавлено автор thkala, источник
@assylias: Я не знаю о «великом», но это может быть хорошим выбором в случаях some . Что касается вашего беспокойства о int , размер не имеет значения - вы всегда можете использовать long или даже BitSet . Что касается того, что это становится беспорядком, подходящий стиль кодирования может помочь много - например. используя константы для бит-масок.
добавлено автор thkala, источник

Для этого есть много возможностей. Не зная о своем домене, я бы создал что-то вроде (вы можете думать о лучших именах: P)

 public interface UserFriendlyMessageBuilder {
      boolean meetCondition(FooObjectWithArguments args);

      String transform(String rawMessage);
 }

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

public class MessageProcessor {
    private final Set messageBuilders;

    public MessageProcessor(Set messageBuilders) {
        this.messageBuilders = messageBuilders;
    }

    public String get(FooWithArguments args, String rawMsg) {

        for (UserFriendlyMessageBuilder msgBuilder : messageBuilders) {
            if (msgBuilder.meetCondition(args)) {
                return msgBuilder.transform(rawMsg);
            }
        }
        return rawMsg;    
    }
}
4
добавлено
@RalfHoppen if-elses не вложены в мой случай, но это может быть вопросом выбора. Позволяет также отметить его, чтобы добавить предложение о погоде, которую я посещаю с гнездом или нет
добавлено автор Prateek, источник
который будет иметь время поиска O (N) (N - количество таких классификаторов), а не probbaly - более низкая сложность для дерева if-else (log (N) идеально для дерева)
добавлено автор radai, источник
@radai Я вижу вашу мысль. ~ Log (N) произойдет только в том случае, если он if/elses, где вложен внутри другого, если/elses. Если нет, то они будут одинаковыми O (N). Кроме того, я думаю, что для этого случая простых сравнений затраченное время будет действительно низким.
добавлено автор Caesar Ralf, источник

Это дополнительная возможность, которую стоит рассмотреть.

Возьмите каждое сравнение и вычислите его правду, а затем посмотрите на полученное в результате значение boolean [] в таблице истинности. Существует много существующих работ по упрощению таблиц истинности , которые вы могли бы применить. У меня есть упрощение таблицы истинности апплет Я написал много лет назад. Вы можете найти его исходный код полезным.

Стоимость этого - все сравнения или, по крайней мере, те, которые необходимы для оценки выражения с использованием упрощенной таблицы истинности. Преимуществом является организованная система управления сложным сочетанием условий.

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

0
добавлено

Мне кажется, что «вы уделяли очень мало внимания разработке продукта в модулях» Что является основным фактором использования языка ООП.

например: Если у вас есть 100 условий, и вы можете сделать 4 модуля, тогда вы можете выбрать что-либо, чтобы выбрать 26 условий.

0
добавлено
pro.jvm
pro.jvm
3 503 участник(ов)

Сообщество разработчиков Java Scala Kotlin Groovy Clojure Чат для нач-их: @javastart Наш сайт: projvm.com projvm.ru Наш канал: @proJVM Вакансии: @jvmjobs Конфы: @jvmconf

Java & Co
Java & Co
2 370 участник(ов)

Можно обсуждать с матом и без всё, что касается жабы, вплоть до холиваров. НЕ ИМЕЕТ ОТНОШЕНИЯ К САЙТУ JAVARUSH.RU ПРАВИЛА - https://t.me/javarush/75723 Вакансии сюда - https://telegram.me/joinchat/B7IzvUCnfo6d8t3yIxKguQ По вопросам - @thedude

learn.java
learn.java
1 888 участник(ов)

Чат для начинающих и не только Статистика: https://combot.org/chat/-1001083535868 Основной чат - @jvmchat

Java Underground
Java Underground
169 участник(ов)

https://vk.com/javatutorial

Javanese Questions
Javanese Questions
109 участник(ов)

Чат предназначен для обмена знаниями строго в формате в вопрос-ответ. Тема — Java, Kotlin и Android. Вопрос должен быть предварительно прогуглен, понятно и грамотно сформулирован, помечен хэштегами. Ответ — тем более. Куски кода размером в несколько строк можно писать прямо здесь, для больших кусков кода стоит использовать http://gist.github.com/, http://pastebin.com/, https://codeshare.io/ или любой аналогичный сервис. В некоторых случаях можно прикреплять скриншоты. Стикеры и гифки запрещены. Дополнять и уточнять вопросы и ответы — редактированием исходного сообщения. Обсуждения должны приводить к редактированию вопроса/ответа и удаляться. По хештегам можно искать существующие вопросы и овтеты: #вопрос #ответ #git #generics #java #server #awt #javafx #swing #kotlin #anko #tornadofx #ktor #android #recyclerView #performance #arch #network #permissions #storage #async