эффективные и красивые строковые условия в Java - PullRequest
1 голос
/ 20 марта 2012

У меня вопрос по стилю кода:

Давайте предположим, что у меня есть строка, содержащая некоторую информацию (например, «Информация1» или «Информация2»). Исходя из этого, я хочу создавать объекты с фабрикой. Очевидно, я мог бы написать что-то вроде этого:

if(string.equals("Information1")){
  Factory.createInformation1Object();
}
if(string.equals("Information2")){
  Factory.createInformation2Object();
}
if(string.equals("Information3")){
  Factory.createInformation3Object();
}

Теперь мне было интересно, есть ли лучший (и более красивый) способ сделать это. Мне действительно нравится идея множественной отправки шаблона посетителя, но я не вижу способа легко применить это к этой конкретной проблеме.

Ответы [ 5 ]

7 голосов
/ 20 марта 2012

Вы можете использовать абстрактный фабричный шаблон .

Создать абстрактный Factory класс [или интерфейс] и классы, расширяющие его: MyObject1Factory, MyObject2Factory, ...

При предварительной обработке заполните Map<String,Factory> от String до базового экземпляра Factory, это делается только один раз в вашем приложении.

Когда вам нужно создать новый экземпляр - вызовите map.get(string).create(), чтобы создать соответствующий объект соответствующего типа.

Редактировать: Маленький пример с кодом:
Ваши занятия:

public static class MyBase { 
    @Override
    public String toString() {
        return "Base";
    }
}
public static class Class1 extends MyBase { 
    @Override
    public String toString() {
        return "Class1";
    }
}
public static class Class2 extends MyBase { 
    @Override
    public String toString() {
        return "Class2";
    }
}

А ваши заводы будут:

public static abstract class MyFactory {
    public abstract MyBase build();
}
public static class MyFactory1 extends MyFactory {
    @Override
    public Class1 build() {
        return new Class1();
    }
}
public static class MyFactory2 extends MyFactory {
    @Override
    public Class2 build() {
        return new Class2();
    }
}

заполнить карту только один раз за время существования программы:

    Map<String,MyFactory> map = new HashMap<String, Test.MyFactory>();
    map.put("class1", new MyFactory1());
    map.put("class2", new MyFactory2());

и когда вам нужен новый объект, вызовите с помощью:

    MyBase obj = map.get(s).build();
    System.out.println(obj);

(*) Примечание. Статическое ключевое слово для классов здесь, потому что я создал их как внутренние классы - конечно, вам нужно его опустить, если это не ваш случай ....

3 голосов
/ 20 марта 2012

В Java 7 теперь вы можете использовать строки в выражениях switch.

Обратите внимание, что ваш код не является прямым аналогом оператора switch, поскольку теоретически возможно вызывать все три фабричных метода, просто взглянув на структуру кода (например, без else операторов). Но на практике это не может произойти, потому что string не может одновременно иметь все три значения.

0 голосов
/ 20 марта 2012

Лучше использовать switch-case, из-за ненужных проверок, если первая или вторая проверка верны. В разделе по умолчанию вы можете разместить другие действия, такие как выдача исключений или так далее.

0 голосов
/ 20 марта 2012

Вы можете использовать оператор switch заново в Java 7. здесь

0 голосов
/ 20 марта 2012

Я предпочитаю функциональный и читабельный. :-) Если строка равна нулю и вызов ее метода определенно выбросит NPE, рассмотрим следующее:

"Information1".equals(strings)

Возможно, Information1, Information2 и Information3 можно поместить в качестве статической переменной класса, чтобы ее можно было легко ссылать и предотвратить ошибку опечатки.

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