Здравствуйте, 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, Вы писали:
H_C>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?
Абстрактная фабрика? "Примитив" тут при чем? Что такое "вложенный switch"?
Здравствуйте, Hard_Club, Вы писали:
H_C>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?
Возможно имеется ввиду, что если switch реализован по enum, то можно просто сделать абстрактный метод в этом конкретном enum-е и для каждого элемента прописать реализацию.
Здравствуйте, 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. Хотя можно было про оба рассказать.
Здравствуйте, Hard_Club, Вы писали:
H_C>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?
Здравствуйте, megapoliss, Вы писали:
M>Здравствуйте, Hard_Club, Вы писали:
H_C>>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?
M>http://refactoring.com/catalog/replaceConditionalWithPolymorphism.html
И как вы собираетесь создавать инстансы конкретных объектов, на каких программных основаниях? Нужно же выбор делать при конструировании.
H_C>>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть? B>Возможно имеется ввиду, что если switch реализован по enum, то можно просто сделать абстрактный метод в этом конкретном enum-е и для каждого элемента прописать реализацию.
Здравствуйте, 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.
H_C>>Правильный ответ был именно State и Strategy. только непонятно, как ими заменить switch, коструирующий по-разному объект в своих ветках
А>у меня есть подозрение что вы не все рассказали, поэтому мы не можем вас понять. А>Если правильный ответ State и Strategy, то, скорее всего, имеется ввиду что объект создается один и тот же, просто в него еще State или Strategy объект инжектится и во время выполнения, чтобы не запускать switch и для конкретного объекта выполнять конкретный код, просто выполняется конкретный State или Strategy.
Объект и в правду создается один, только с вызовом разных конструкторов.
Здравствуйте, 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();
}
Здравствуйте, 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 алгоритмов?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, andyag, Вы писали:
A>>Здравствуйте, Hard_Club, Вы писали:
H_C>>>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?
A>>Сильно зависит от того, в чём именно вы видите проблему. В switch нет ничего плохого, даже если он длинный. Главное, чтобы читалось. Если у вас желание наархитектить, можно подумать вот в такую сторону:
А>А что в findFactoryBasedOnGivenContext не будет ветвления или выборки по какому-нибудь хэш-коду на уровне java алгоритмов?
Ветвление есть всегда и у всех, но в зависимости от подхода к реализации, оно либо будет торчать развесистым деревом из программы и своими ветками выкалывать глаза всем читающим, либо будет настолько неявным и незаметным, что о нём даже могут и забыть. Задача ТС вообще сводится к тому, чтобы выполнить N сравнений и в одном из них получить true. Есть примерно 2 способа выполнить N сравнений — написать N сравнений руками или выполнить 1 сравнение N раз. Первый способ грозит написанием одной длинной функции, которая будет становиться ещё длиннее при развитии программы. Второй способ грозит обвинениями в ООП головного мозга, хотя лишён недостатков первого
Здравствуйте, Аноним, Вы писали:
А>для того чтобы был полиморфизм нужно ветвление для инициализации конкретным классом.
switch и есть ветвление.
А>И вообще вопрос был не об этом
Ну, просвяти, о чем же был тогда вопрос?
Здравствуйте, Hard_Club, Вы писали:
H_C>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?
Command Map и ServiceLocator.
Если до этого условная логика использовалась для диспетчеризации запросов (по анализу некоторых признаков) и выполнения соответствующего действия (конструирование подходящего объекта), то нужно для каждого действия создать команду (шаблон Command), хранить команды в коллекции (Map), заменить условную логику кодом, выбирающим и выполняющим соответствующую команду (ServiceLocator выдаёт на выполнение команду, соответствующую "признакам").
Здравствуйте, iZEN, Вы писали:
ZEN>Здравствуйте, Hard_Club, Вы писали:
H_C>>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?
ZEN>Command Map и ServiceLocator.
ZEN>Если до этого условная логика использовалась для диспетчеризации запросов (по анализу некоторых признаков) и выполнения соответствующего действия (конструирование подходящего объекта), то нужно для каждого действия создать команду (шаблон Command), хранить команды в коллекции (Map), заменить условную логику кодом, выбирающим и выполняющим соответствующую команду (ServiceLocator выдаёт на выполнение команду, соответствующую "признакам").
Это из области JEE, компонентов и вэб-фреймворков, как я понимаю, что не может квалифицироваться на решение столь простой проблемы тяжеловесным решением.
Здравствуйте, ZeroLatency, Вы писали:
ZL>Здравствуйте, iZEN, Вы писали:
ZEN>>Здравствуйте, Hard_Club, Вы писали:
H_C>>>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?
ZEN>>Command Map и ServiceLocator.
ZEN>>Если до этого условная логика использовалась для диспетчеризации запросов (по анализу некоторых признаков) и выполнения соответствующего действия (конструирование подходящего объекта), то нужно для каждого действия создать команду (шаблон Command), хранить команды в коллекции (Map), заменить условную логику кодом, выбирающим и выполняющим соответствующую команду (ServiceLocator выдаёт на выполнение команду, соответствующую "признакам").
ZL>Это из области JEE, компонентов и вэб-фреймворков, как я понимаю, что не может квалифицироваться на решение столь простой проблемы тяжеловесным решением.
Это вообще к Java никак не относится.
У Джошуа Кириевски разве что в похожей комбинации отсутствует ServiceLocator. Но этот компонент я ввёл для специальной обработки многокритериального выбора от простой функции Map — выдачи объекта по ключу. Нужный ключ к Map должен сформировать ServiceLocator, исходя из признаков, предъявляемых пользователем, и поставить действительно нужный объект.
ZL>>Это из области JEE, компонентов и вэб-фреймворков, как я понимаю, что не может квалифицироваться на решение столь простой проблемы тяжеловесным решением.
ZEN>Это вообще к Java никак не относится.
ZEN>У Джошуа Кириевски разве что в похожей комбинации отсутствует ServiceLocator. Но этот компонент я ввёл для специальной обработки многокритериального выбора от простой функции Map — выдачи объекта по ключу. Нужный ключ к Map должен сформировать ServiceLocator, исходя из признаков, предъявляемых пользователем, и поставить действительно нужный объект.
У этого Джошуа — ServiceLocator + Command.
Здесь в других ветках предлагалось — State или Strategy/Factory + FactoryRepository
Здравствуйте, Hard_Club, Вы писали:
H_C>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?
Здравствуйте, TarasB, Вы писали:
TB>Здравствуйте, Hard_Club, Вы писали:
H_C>>Если есть конструирование объекта с помощью вложенного switch с помощью анализа некоторых признаков, то каким паттерном проектирования / примитивом это можно перекрыть?
TB>А надо ли?
Если SWITCH — большой, то, в принципе, не помешает: ведь анализируется всего один параметр и принимается решение как конструировать, если всё это распихать по Command Map/Command патернам с правильно названными классами, будет читаться нормально.
Но это — простой и понятный случай, в SWITCH один параметр. Вот мне бы интересно мнение сообщества если здесь бы был не SWITCH а несколько экранов IF'ов где анализируются несколько параметров и в ветках по разному конструируется один и тот же объект.
Как определить ту границу когда стоит оставить метод с IF'ами где, в принципе, логика собрана в одном месте, либо раскидать эту логику по разным классам следуя каким-либо паттернам? Кто что думает?
Здравствуйте, Antei, Вы писали:
A>Но это — простой и понятный случай, в SWITCH один параметр. Вот мне бы интересно мнение сообщества если здесь бы был не SWITCH а несколько экранов IF'ов где анализируются несколько параметров и в ветках по разному конструируется один и тот же объект. A>Как определить ту границу когда стоит оставить метод с IF'ами где, в принципе, логика собрана в одном месте, либо раскидать эту логику по разным классам следуя каким-либо паттернам? Кто что думает?
Универсальных рецептов нет. Это то, что по модному именуется "common sense".