Если есть конструирование объекта с помощью вложенного 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();
}
Здравствуйте, 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); // тут "конструируете объект по признакам"
Дисклеймер: я бы хорошо взвесил плюсы-минусы, прежде чем пилить такой дизайн
Здравствуйте, 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 и есть ветвление.
А>И вообще вопрос был не об этом
Ну, просвяти, о чем же был тогда вопрос?