Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Какой паттерн использовать чтоб заменить многочисленные ифы? / 25 сообщений из 34, страница 1 из 2
06.04.2015, 12:48
    #38927913
redwhite90
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
На собеседовании спросили следующий вопрос:

Есть метод:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
public void foo(SomeObject o){
    if(o.matches(constant1)){
          doSomething1(); 
    }else if(o.matches(constant2)){
          doSomething2(); 
    }
    }else if(o.matches(constant3)){
          doSomething3(); 
    }
    ....
}



Вопрос звучал, как отрефакторить такой метод.

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

Сейчас я думаю, что от меня хотели услышать паттерн "состояние".

Правильно?
...
Рейтинг: 0 / 0
06.04.2015, 12:50
    #38927915
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
Кто его знает что имел ввиду интервьювер. Это паттерн рефакторинга - замена условия полиморфизмом. Ограничен ли набор правильных ответов GoF - это вопрос открытый.
...
Рейтинг: 0 / 0
06.04.2015, 12:53
    #38927917
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
redwhite90,

Состояние, в принципе, подходит. Вопрос только в том почему SomeObject является внешним для this, реализующего doSomething().
...
Рейтинг: 0 / 0
06.04.2015, 12:57
    #38927921
rema174
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
может нужно было увязать константы с соответсвующими методами?
...
Рейтинг: 0 / 0
06.04.2015, 13:04
    #38927929
redwhite90
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
Blazkowiczredwhite90,

Состояние, в принципе, подходит. Вопрос только в том почему SomeObject является внешним для this, реализующего doSomething().

В оригинале это была строка, но как я заикнулся, что если строка, то можно в switch запихнуть мне сказали, что может быть и не строка
...
Рейтинг: 0 / 0
06.04.2015, 13:13
    #38927946
redwhite90
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
rema174может нужно было увязать константы с соответсвующими методами?

Не понял в чём идея. Даже не понял, что Ваша фраза значит. каким образом увязать?
...
Рейтинг: 0 / 0
06.04.2015, 13:28
    #38927971
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
redwhite90Не понял в чём идея. Даже не понял, что Ваша фраза значит. каким образом увязать?
Ну, он и имеет ввиду State

Код: java
1.
2.
3.
4.
public void foo(SomeObject o) {
    ConstantType c = findMatch(o);
    c.doSomethingVirtual(this);
}
...
Рейтинг: 0 / 0
06.04.2015, 13:35
    #38927983
rema174
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
если предположить, что константы это String
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
String[] constans = {"constant1", "constant2", "constant3", ...};

Map<String const, String method> strategyMap = new HashMap<>();
strategyMap.put("constant1", "doSomething1");
strategyMap.put("constant2", "doSomething2");
strategyMap.put("constant3", "doSomething3");
...

public void foo(SomeObject o) {
    for(int i = 0; i < constans.length; i++) {
        if(o.matches(constant)) {
            Method method = YourClass.class.getMethod(myMap.get(constant), null);
            method.invoke(null);
        }
    }
}
...
Рейтинг: 0 / 0
06.04.2015, 13:55
    #38928012
redwhite90
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
rema174если предположить, что константы это String
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
String[] constans = {"constant1", "constant2", "constant3", ...};

Map<String const, String method> strategyMap = new HashMap<>();
strategyMap.put("constant1", "doSomething1");
strategyMap.put("constant2", "doSomething2");
strategyMap.put("constant3", "doSomething3");
...

public void foo(SomeObject o) {
    for(int i = 0; i < constans.length; i++) {
        if(o.matches(constant)) {
            Method method = YourClass.class.getMethod(myMap.get(constant), null);
            method.invoke(null);
        }
    }
}



Как-то сложно) через рефлекшн.

Хотя про стратегию. тоже версия есть...

и про chain of responsibility
...
Рейтинг: 0 / 0
06.04.2015, 15:16
    #38928164
redwhite90
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
rema174,

при переименовании метода будет ай-ай-ай
...
Рейтинг: 0 / 0
06.04.2015, 15:23
    #38928171
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
redwhite90при переименовании метода будет ай-ай-ай
С переименованием идея-то справится. Но при наличии Callable и лямбд такой код просто моветон.
...
Рейтинг: 0 / 0
06.04.2015, 15:37
    #38928187
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
redwhite90,
по мне, так это паттерн "команда" в чистом виде. При чем тут "состояние" - непонятно. Вот примерно так:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
interface Command {
  void execute();
}
class DoSomething1 implements Command {
}
...
class DoSomethingN implements Command {
}

String[] constans = {"constant1", "constant2", "constant3", ...};

Map<String, Command> commandMap = new HashMap<String,Command>();
commandMap.put("constant1", new DoSomething1());
...
commandMap.put("constantN", new DoSomethingN());
...

public void foo(SomeObject o) {
    for(int i = 0; i < constans.length; i++) {
        if(o.matches(constant)) {
            Command command = commandMap.get(constant);
            command.execute();
        }
    }
}
...
Рейтинг: 0 / 0
06.04.2015, 15:49
    #38928206
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
ivanra,

Не-не-не. Команда это вообще не то. Она отвязывает получателя команды от отправляющего. Здесь либо состояние. Правда, не понятно почему оно передаётся из вне. Либо стратегия.
...
Рейтинг: 0 / 0
06.04.2015, 16:08
    #38928239
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
redwhite90, этот метод не является неправильным или некорректным с точки зрения Java.
Нормальный себе такой метод. Правил языка не нарушает.

Но есть некоторые векторы развития этого приложения если рассматривать его не в вакууме
а в совокупности. Например - прогнозируется рост количества методов foo2, foo3, .... fooN
с похожим паттерном сравнения - надо думать о RCWP или стратегиях. Прогнозируется добавление новых
констант в количестве превашающем разумное число классов - надо думать о рефлексии.
...
Рейтинг: 0 / 0
06.04.2015, 16:12
    #38928245
rema174
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
и скаждой новой версией код становится все жирнее )
...
Рейтинг: 0 / 0
06.04.2015, 16:14
    #38928247
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
Эта злая судьба - для всех проектов.
...
Рейтинг: 0 / 0
06.04.2015, 16:20
    #38928260
redwhite90
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
Blazkowiczredwhite90при переименовании метода будет ай-ай-ай
С переименованием идея-то справится. Но при наличии Callable и лямбд такой код просто моветон.

В джава есть ещё какой-то Callable помимо многопточного?
...
Рейтинг: 0 / 0
06.04.2015, 16:29
    #38928284
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
Blazkowiczivanra,
Не-не-не. Команда это вообще не то. Она отвязывает получателя команды от отправляющего. Здесь либо состояние. Правда, не понятно почему оно передаётся из вне. Либо стратегия.
Точно, правильное название - "стратегия". В алгоритме написал одно, в названии другое :). Но поскольку в условиях задачи ничего не говорится о зависимости от внутреннего состояния, о все-таки это не "состояние"
...
Рейтинг: 0 / 0
06.04.2015, 17:26
    #38928387
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
rema174если предположить, что константы это String
А через Map на интерфейс не проще ли (Ну или Лямду).
Хотя для трех элементов овчинка выделки не стоит.
...
Рейтинг: 0 / 0
06.04.2015, 17:27
    #38928389
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
Сергей Арсеньев А через Map на интерфейс не проще ли (Ну или Лямду).
Хотя для трех элементов овчинка выделки не стоит.
Виртуальный метод это лучший Map.
...
Рейтинг: 0 / 0
06.04.2015, 18:13
    #38928428
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
Blazkowicz,

Вот еще прокси к самому себе городить.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
import java.util.*;

public class TestLambda {

 public static interface ThisRunnable {
  public void run(TestLambda th);
 }

 private final String id = UUID.randomUUID().toString();

 private void do1() {
  System.out.println(1);
 }

 private void doId() {
  System.out.println(id);
 }

 private static final Map<Object,ThisRunnable> DEEDS_MAP= new HashMap<Object,ThisRunnable>();

 static {
  DEEDS_MAP.put("!",(TestLambda th) -> {th.doId();});
  DEEDS_MAP.put("1",(TestLambda th) -> {th.do1();});
 }

 public void doSomething(Object o) {
  DEEDS_MAP.get(o).run(this);
 }

 public static void main(String[] args) {
  TestLambda tl = new TestLambda();
  if (args.length>0) {
   tl.doSomething(args[0]);
  }
  tl = new TestLambda();
  if (args.length>1) {
   tl.doSomething(args[1]);
  }
 }

}

...
Рейтинг: 0 / 0
06.04.2015, 18:17
    #38928433
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
Сергей Арсеньев,

А нет, Только сейчас прочел нужен matches, не equals
...
Рейтинг: 0 / 0
06.04.2015, 18:19
    #38928434
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
Сергей Арсеньев[src java]
public static interface ThisRunnable {
public void run(TestLambda th);
}

java.util.function.Function ?
...
Рейтинг: 0 / 0
07.04.2015, 09:15
    #38928763
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
Blazkowicz,

ну да. Но учитывая matches, Map не нужен. Все равно все перебирать и в определенном порядке массива хватит. Так что рефакторинг почти бессмыслен. Разве что ради динамики.
...
Рейтинг: 0 / 0
07.04.2015, 09:46
    #38928800
silvan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Какой паттерн использовать чтоб заменить многочисленные ифы?
redwhite90На собеседовании спросили следующий вопрос:

Есть метод:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
public void foo(SomeObject o){
    if(o.matches(constant1)){
          doSomething1(); 
    }else if(o.matches(constant2)){
          doSomething2(); 
    }
    }else if(o.matches(constant3)){
          doSomething3(); 
    }
    ....
}



Вопрос звучал, как отрефакторить такой метод.



rema174 - занесло..


создать интерфейс и классы
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
public interface Somethinger {

    public void doSomething();
}

public class MySomethinger implements Somethinger {

    public void doSomething() {
        //Code here
    }
}


карту
Код: java
1.
2.
3.
4.
5.
Map<String, Somethinger > typeMap = new HashMap<String, Somethinger >();

typeMap.put("constant1", new MySomethinger ());
typeMap.put("constant2", new MySomethinger2 ());
typeMap.put("constant3", new MySomethinger3 ());


и
Код: java
1.
2.
Somethinger somethinger = typeMap.get(type);
converter.doSomething();



в патернах не селен как звать не знаю
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Какой паттерн использовать чтоб заменить многочисленные ифы? / 25 сообщений из 34, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]