Re: каким паттерном можно заменить switch
От: andyag  
Дата: 24.12.13 16:48
Оценка: +1
Здравствуйте, Hard_Club, Вы писали:

H_C>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?


Сильно зависит от того, в чём именно вы видите проблему. В switch нет ничего плохого, даже если он длинный. Главное, чтобы читалось. Если у вас желание наархитектить, можно подумать вот в такую сторону:
// эта штука описывает совокупность признаков, имеющих место быть в одном конкретном случае
interface Context {
  Trait getTrait(String name); // например, признаки - именованные
}

// эта штука смотрит на контекст и говорит, "подходит" он или нет
interface ContextPredicate {
  boolean test(Context context);
}

// это фабрика.
// во-первых она может сказать устраивает её контекст или нет
// во-вторых, если устраивает, она может из этого самого контекста сконструировать нужный объект
interface MyFactory {
  ContextPredicate getContextPredicate();
  MyObject makeObject(Context context);
}

// это репозиторий фабрик
// в нём можно найти фабрику, которая может сконструировать объект глядя на контекст
interface MyFactoryRepository {
  MyFactory findFactoryBasedOnGivenContext(Context context);
}

MyFactoryRepository factoryRepository = new MyFactoryRepository();
factoryRepository.add(new MyFactory1()); // добавляем пару "вот такой контекст" + "вот так конструировать"
factoryRepository.add(new MyFactory2()); // добавляем пару "вот такой контекст" + "вот так конструировать"
factoryRepository.add(new MyFactory3()); // добавляем пару "вот такой контекст" + "вот так конструировать"

Context context = getContextFromSomewhere(); // тут ваш контекст - совокупность признаков
MyFactory factory = factoryRepository.findFactoryBasedOnGivenContext(context); // тут вы получаете наиболее подходящую фабрику
MyObject object = factory.makeObject(context); // тут "конструируете объект по признакам"

Дисклеймер: я бы хорошо взвесил плюсы-минусы, прежде чем пилить такой дизайн
каким паттерном можно заменить switch
От: Hard_Club  
Дата: 24.12.13 13:35
Оценка:
Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?
Re: каким паттерном можно заменить switch
От: Blazkowicz Россия  
Дата: 24.12.13 13:43
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?

Абстрактная фабрика? "Примитив" тут при чем? Что такое "вложенный switch"?
Re: каким паттерном можно заменить switch
От: Blazkowicz Россия  
Дата: 24.12.13 13:52
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?

Возможно имеется ввиду, что если switch реализован по enum, то можно просто сделать абстрактный метод в этом конкретном enum-е и для каждого элемента прописать реализацию.
Re: каким паттерном можно заменить switch
От: ZeroLatency  
Дата: 24.12.13 13:59
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?


Если спрашивают про паттерн на собсеседовании, значит имеют что-то более сложное чем присваивание одной переменной.
Скорее всего, имели ввиду State pattern или Strategy pattern- они очень похожи, назначение немного разное.

State
This pattern is used in computer programming to encapsulate varying behavior for the same routine based on an object's state object

Strategy
The Strategy pattern embodies two such principles—encapsulate the concept that varies and program to an interface, not an implementation.

Если больше ничего не спрашивали, значит это был State. Хотя можно было про оба рассказать.
Re: каким паттерном можно заменить switch
От: megapoliss Украина  
Дата: 24.12.13 14:05
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?


http://refactoring.com/catalog/replaceConditionalWithPolymorphism.html
Re[2]: каким паттерном можно заменить switch
От: ZeroLatency  
Дата: 24.12.13 14:08
Оценка:
Недочитал.

Речь идет про Factory method
Factory methods encapsulate the creation of objects.

http://en.wikipedia.org/wiki/Factory_method_pattern#Java_3

или Simple factory
http://corey.quickshiftconsulting.com/1/post/2009/5/first-post.html
Re[2]: каким паттерном можно заменить switch
От: ZeroLatency  
Дата: 24.12.13 14:10
Оценка:
Здравствуйте, megapoliss, Вы писали:

M>Здравствуйте, Hard_Club, Вы писали:


H_C>>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?


M>http://refactoring.com/catalog/replaceConditionalWithPolymorphism.html



И как вы собираетесь создавать инстансы конкретных объектов, на каких программных основаниях? Нужно же выбор делать при конструировании.
Re[2]: каким паттерном можно заменить switch
От: Hard_Club  
Дата: 24.12.13 14:44
Оценка:
H_C>>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?
B>Возможно имеется ввиду, что если switch реализован по enum, то можно просто сделать абстрактный метод в этом конкретном enum-е и для каждого элемента прописать реализацию.

Можно пример, пожалуйста?
Re[2]: каким паттерном можно заменить switch
От: Hard_Club  
Дата: 24.12.13 14:46
Оценка:
Здравствуйте, ZeroLatency, Вы писали:

ZL>Здравствуйте, Hard_Club, Вы писали:


H_C>>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?


ZL>Если спрашивают про паттерн на собсеседовании, значит имеют что-то более сложное чем присваивание одной переменной.

ZL>Скорее всего, имели ввиду State pattern или Strategy pattern- они очень похожи, назначение немного разное.

ZL>State

ZL>This pattern is used in computer programming to encapsulate varying behavior for the same routine based on an object's state object

ZL>Strategy

ZL>The Strategy pattern embodies two such principles—encapsulate the concept that varies and program to an interface, not an implementation.

ZL>Если больше ничего не спрашивали, значит это был State. Хотя можно было про оба рассказать.


Правильный ответ был именно State и Strategy. только непонятно, как ими заменить switch, коструирующий по-разному объект в своих ветках
Re[3]: каким паттерном можно заменить switch
От: Аноним  
Дата: 24.12.13 15:05
Оценка:
H_C>Правильный ответ был именно State и Strategy. только непонятно, как ими заменить switch, коструирующий по-разному объект в своих ветках

у меня есть подозрение что вы не все рассказали, поэтому мы не можем вас понять.
Если правильный ответ State и Strategy, то, скорее всего, имеется ввиду что объект создается один и тот же, просто в него еще State или Strategy объект инжектится и во время выполнения, чтобы не запускать switch и для конкретного объекта выполнять конкретный код, просто выполняется конкретный State или Strategy.
Re[4]: каким паттерном можно заменить switch
От: Hard_Club  
Дата: 24.12.13 15:16
Оценка:
Здравствуйте, Аноним, Вы писали:


H_C>>Правильный ответ был именно State и Strategy. только непонятно, как ими заменить switch, коструирующий по-разному объект в своих ветках


А>у меня есть подозрение что вы не все рассказали, поэтому мы не можем вас понять.

А>Если правильный ответ State и Strategy, то, скорее всего, имеется ввиду что объект создается один и тот же, просто в него еще State или Strategy объект инжектится и во время выполнения, чтобы не запускать switch и для конкретного объекта выполнять конкретный код, просто выполняется конкретный State или Strategy.

Объект и в правду создается один, только с вызовом разных конструкторов.
Re[3]: каким паттерном можно заменить switch
От: Blazkowicz Россия  
Дата: 24.12.13 15:48
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>>>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?

B>>Возможно имеется ввиду, что если switch реализован по enum, то можно просто сделать абстрактный метод в этом конкретном enum-е и для каждого элемента прописать реализацию.

H_C>Можно пример, пожалуйста?


За точность синтаксиса не ручаюсь. Но идея, полагаю, понятна?
public enum BeanType {
   BeanTypeA{
     @Override  
     public BeanA create(){
        return new BeanA();
     }
   },
   BeanTypeB{
     @Override  
     public BeanB create(){
        return new BeanB();
     }
   }

   public abstract AbstractBean create();
}
Re[4]: каким паттерном можно заменить switch
От: Hard_Club  
Дата: 24.12.13 15:53
Оценка:
B>За точность синтаксиса не ручаюсь. Но идея, полагаю, понятна?
B>
B>public enum BeanType {
B>   BeanTypeA{
B>     @Override  
B>     public BeanA create(){
B>        return new BeanA();
B>     }
B>   },
B>   BeanTypeB{
B>     @Override  
B>     public BeanB create(){
B>        return new BeanB();
B>     }
B>   }

B>   public abstract AbstractBean create();
B>}
B>


А как это вызывать?
Re[5]: каким паттерном можно заменить switch
От: Blazkowicz Россия  
Дата: 24.12.13 17:30
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>А как это вызывать?


BeanType bType = ... ;//Retrieved from an external source
AbstractBean bean = bType.create(); //Instance class depends on the type
Re[3]: каким паттерном можно заменить switch
От: Blazkowicz Россия  
Дата: 24.12.13 17:48
Оценка:
Здравствуйте, ZeroLatency, Вы писали:

ZL>И как вы собираетесь создавать инстансы конкретных объектов, на каких программных основаниях? Нужно же выбор делать при конструировании.

Из короткого описания, достаточно сложно понять какой изначально предполагается код и какую задачу он реализует. Но посыл верный — замена ветвления полиморфизмом.
Re[4]: каким паттерном можно заменить switch
От: Аноним  
Дата: 24.12.13 18:03
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Здравствуйте, ZeroLatency, Вы писали:


ZL>>И как вы собираетесь создавать инстансы конкретных объектов, на каких программных основаниях? Нужно же выбор делать при конструировании.

B>Из короткого описания, достаточно сложно понять какой изначально предполагается код и какую задачу он реализует. Но посыл верный — замена ветвления полиморфизмом.

для того чтобы был полиморфизм нужно ветвление для инициализации конкретным классом. И вообще вопрос был не об этом
Re[2]: каким паттерном можно заменить switch
От: Аноним  
Дата: 25.12.13 03:26
Оценка:
Здравствуйте, andyag, Вы писали:

A>Здравствуйте, Hard_Club, Вы писали:


H_C>>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?


A>Сильно зависит от того, в чём именно вы видите проблему. В switch нет ничего плохого, даже если он длинный. Главное, чтобы читалось. Если у вас желание наархитектить, можно подумать вот в такую сторону:

A>
A>// эта штука описывает совокупность признаков, имеющих место быть в одном конкретном случае
A>interface Context {
A>  Trait getTrait(String name); // например, признаки - именованные
A>}

A>// эта штука смотрит на контекст и говорит, "подходит" он или нет
A>interface ContextPredicate {
A>  boolean test(Context context);
A>}

A>// это фабрика.
A>// во-первых она может сказать устраивает её контекст или нет
A>// во-вторых, если устраивает, она может из этого самого контекста сконструировать нужный объект
A>interface MyFactory {
A>  ContextPredicate getContextPredicate();
A>  MyObject makeObject(Context context);
A>}

A>// это репозиторий фабрик
A>// в нём можно найти фабрику, которая может сконструировать объект глядя на контекст
A>interface MyFactoryRepository {
A>  MyFactory findFactoryBasedOnGivenContext(Context context);
A>}

A>MyFactoryRepository factoryRepository = new MyFactoryRepository();
A>factoryRepository.add(new MyFactory1()); // добавляем пару "вот такой контекст" + "вот так конструировать"
A>factoryRepository.add(new MyFactory2()); // добавляем пару "вот такой контекст" + "вот так конструировать"
A>factoryRepository.add(new MyFactory3()); // добавляем пару "вот такой контекст" + "вот так конструировать"

A>Context context = getContextFromSomewhere(); // тут ваш контекст - совокупность признаков
A>MyFactory factory = factoryRepository.findFactoryBasedOnGivenContext(context); // тут вы получаете наиболее подходящую фабрику
A>MyObject object = factory.makeObject(context); // тут "конструируете объект по признакам"
A>

A>Дисклеймер: я бы хорошо взвесил плюсы-минусы, прежде чем пилить такой дизайн



А что в findFactoryBasedOnGivenContext не будет ветвления или выборки по какому-нибудь хэш-коду на уровне java алгоритмов?
Re[3]: каким паттерном можно заменить switch
От: andyag  
Дата: 25.12.13 04:50
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, andyag, Вы писали:


A>>Здравствуйте, Hard_Club, Вы писали:


H_C>>>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?


A>>Сильно зависит от того, в чём именно вы видите проблему. В switch нет ничего плохого, даже если он длинный. Главное, чтобы читалось. Если у вас желание наархитектить, можно подумать вот в такую сторону:


А>А что в findFactoryBasedOnGivenContext не будет ветвления или выборки по какому-нибудь хэш-коду на уровне java алгоритмов?


Ветвление есть всегда и у всех, но в зависимости от подхода к реализации, оно либо будет торчать развесистым деревом из программы и своими ветками выкалывать глаза всем читающим, либо будет настолько неявным и незаметным, что о нём даже могут и забыть. Задача ТС вообще сводится к тому, чтобы выполнить N сравнений и в одном из них получить true. Есть примерно 2 способа выполнить N сравнений — написать N сравнений руками или выполнить 1 сравнение N раз. Первый способ грозит написанием одной длинной функции, которая будет становиться ещё длиннее при развитии программы. Второй способ грозит обвинениями в ООП головного мозга, хотя лишён недостатков первого
Re[5]: каким паттерном можно заменить switch
От: Blazkowicz Россия  
Дата: 25.12.13 07:40
Оценка:
Здравствуйте, Аноним, Вы писали:

А>для того чтобы был полиморфизм нужно ветвление для инициализации конкретным классом.

switch и есть ветвление.

А>И вообще вопрос был не об этом

Ну, просвяти, о чем же был тогда вопрос?
Re[2]: каким паттерном можно заменить switch
От: Hard_Club  
Дата: 25.12.13 09:19
Оценка:
жесть!
Re: каким паттерном можно заменить switch
От: iZEN СССР  
Дата: 28.12.13 15:36
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?


Command Map и ServiceLocator.

Если до этого условная логика использовалась для диспетчеризации запросов (по анализу некоторых признаков) и выполнения соответствующего действия (конструирование подходящего объекта), то нужно для каждого действия создать команду (шаблон Command), хранить команды в коллекции (Map), заменить условную логику кодом, выбирающим и выполняющим соответствующую команду (ServiceLocator выдаёт на выполнение команду, соответствующую "признакам").
Re[2]: каким паттерном можно заменить switch
От: ZeroLatency  
Дата: 29.12.13 01:29
Оценка:
Здравствуйте, iZEN, Вы писали:

ZEN>Здравствуйте, Hard_Club, Вы писали:


H_C>>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?


ZEN>Command Map и ServiceLocator.


ZEN>Если до этого условная логика использовалась для диспетчеризации запросов (по анализу некоторых признаков) и выполнения соответствующего действия (конструирование подходящего объекта), то нужно для каждого действия создать команду (шаблон Command), хранить команды в коллекции (Map), заменить условную логику кодом, выбирающим и выполняющим соответствующую команду (ServiceLocator выдаёт на выполнение команду, соответствующую "признакам").


Это из области JEE, компонентов и вэб-фреймворков, как я понимаю, что не может квалифицироваться на решение столь простой проблемы тяжеловесным решением.
Re[3]: каким паттерном можно заменить switch
От: iZEN СССР  
Дата: 29.12.13 16:39
Оценка:
Здравствуйте, ZeroLatency, Вы писали:

ZL>Здравствуйте, iZEN, Вы писали:


ZEN>>Здравствуйте, Hard_Club, Вы писали:


H_C>>>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?


ZEN>>Command Map и ServiceLocator.


ZEN>>Если до этого условная логика использовалась для диспетчеризации запросов (по анализу некоторых признаков) и выполнения соответствующего действия (конструирование подходящего объекта), то нужно для каждого действия создать команду (шаблон Command), хранить команды в коллекции (Map), заменить условную логику кодом, выбирающим и выполняющим соответствующую команду (ServiceLocator выдаёт на выполнение команду, соответствующую "признакам").


ZL>Это из области JEE, компонентов и вэб-фреймворков, как я понимаю, что не может квалифицироваться на решение столь простой проблемы тяжеловесным решением.


Это вообще к Java никак не относится.

У Джошуа Кириевски разве что в похожей комбинации отсутствует ServiceLocator. Но этот компонент я ввёл для специальной обработки многокритериального выбора от простой функции Map — выдачи объекта по ключу. Нужный ключ к Map должен сформировать ServiceLocator, исходя из признаков, предъявляемых пользователем, и поставить действительно нужный объект.
Re[4]: каким паттерном можно заменить switch
От: Hard_Club  
Дата: 30.12.13 08:33
Оценка:
ZL>>Это из области JEE, компонентов и вэб-фреймворков, как я понимаю, что не может квалифицироваться на решение столь простой проблемы тяжеловесным решением.

ZEN>Это вообще к Java никак не относится.


ZEN>У Джошуа Кириевски разве что в похожей комбинации отсутствует ServiceLocator. Но этот компонент я ввёл для специальной обработки многокритериального выбора от простой функции Map — выдачи объекта по ключу. Нужный ключ к Map должен сформировать ServiceLocator, исходя из признаков, предъявляемых пользователем, и поставить действительно нужный объект.


У этого Джошуа — ServiceLocator + Command.
Здесь в других ветках предлагалось — State или Strategy/Factory + FactoryRepository

Так все же???
Re: каким паттерном можно заменить switch
От: TarasB  
Дата: 30.12.13 08:40
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?


А надо ли?
Re[2]: каким паттерном можно заменить switch
От: Antei США  
Дата: 31.12.13 01:46
Оценка:
Здравствуйте, TarasB, Вы писали:

TB>Здравствуйте, Hard_Club, Вы писали:


H_C>>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?


TB>А надо ли?

Если SWITCH — большой, то, в принципе, не помешает: ведь анализируется всего один параметр и принимается решение как конструировать, если всё это распихать по Command Map/Command патернам с правильно названными классами, будет читаться нормально.

Но это — простой и понятный случай, в SWITCH один параметр. Вот мне бы интересно мнение сообщества если здесь бы был не SWITCH а несколько экранов IF'ов где анализируются несколько параметров и в ветках по разному конструируется один и тот же объект.
Как определить ту границу когда стоит оставить метод с IF'ами где, в принципе, логика собрана в одном месте, либо раскидать эту логику по разным классам следуя каким-либо паттернам? Кто что думает?
Re[3]: каким паттерном можно заменить switch
От: devcoach  
Дата: 31.12.13 06:35
Оценка:
Здравствуйте, Antei, Вы писали:

A>Но это — простой и понятный случай, в SWITCH один параметр. Вот мне бы интересно мнение сообщества если здесь бы был не SWITCH а несколько экранов IF'ов где анализируются несколько параметров и в ветках по разному конструируется один и тот же объект.

A>Как определить ту границу когда стоит оставить метод с IF'ами где, в принципе, логика собрана в одном месте, либо раскидать эту логику по разным классам следуя каким-либо паттернам? Кто что думает?
Универсальных рецептов нет. Это то, что по модному именуется "common sense".
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.