Есть несколько классов, далее идет проверка классов через instanceof, если передали такой класс тогда выполнить такие то действия. Какой паттерн можно использовать.
getParams(SomeClass some) {
if (some instanceof SomeNoth) {
...
...
...
... }
if (some instanceof SomeNoth2) {
...
...
...
... }
if (some instanceof SomeNoth3) {
...
...
...
... }
if (some instanceof SomeNoth4) {
...
...
...
... }
if (some instanceof SomeNoth5) {
...
...
...
... }
Так как вы настаиваете на примере, приведу простой для понимания. Наши тестовые классы:
public class Test1 {
public void method1() { System.out.print("Test1.method1"); }
}
public class Test2 {
public void method2() { System.out.print("Test2.method2"); }
}
Далее, небольшая архитектура:
public interface IHandler {
void run(Object obj);
boolean isTypeof(Object obj);
}
Под неё делаем две реализации хандлеров:
public class Test1Handler implements IHandler {
@Override
public void run(Object obj){
Test1 test = (Test1)obj;
// Здесь любой код...
test.method1(); // для примера
}
@Override
public boolean isTypeof(Object obj){
return obj instanceof Test1;
}
}
public class Test2Handler implements IHandler {
@Override
public void run(Object obj){
Test2 test = (Test2)obj;
// Здесь любой код...
test.method2(); // для примера
}
@Override
public boolean isTypeof(Object obj){
return obj instanceof Test2;
}
}
Всё, архитектура готова, реализация есть, теперь можно всё свернуть в один универсальный метод:
public class ServiceChecker {
private static ServiceChecker instance;
private List<IHandler> handlers = new ArrayList<IHandler>();
public ServiceChecker(){
handlers.add(new Test1Handler());
handlers.add(new Test2Handler());
}
public static ServiceChecker getInstance(){
if(instance==null){
instance = new ServiceChecker();
}
return instance;
}
public void check(Object some){
for(IHandler handler : handlers){
if(handler.isTypeof(some)){
handler.run(some);
break;
}
}
}
}
Теперь можно смело использовать:
ServiceChecker.getInstance().check(new Test2());
ServiceChecker.getInstance().check(new Test1());
Что вообще этот подход вам даст:
Является ли это паттерном? Честно скажу - я не знаю. Скорее всего, нечто такое уже придумали.
Можно сделать изящно и красиво - использовать фабрику. А именно:
Map<Class, Runnable> actions = new HashMap<>();
....
void registrationAction(Class<?> cl, Runnable action){
actions.put(cl, action);
}
void actionOn(SomeClass cl){
actions.get(cl.getClass()).run();
}
Начиная с Java 7 можно использовать String
в switch
, следовательно можно хакнуть так:
getParams(SomeClass some) {
String clzName=some.getClass().getSimpleName();
switch(clzName) {
case "SomeNoth":
break;
case "SomeNoth2":
break;
//blah-blah
}
}
Update
Для поборников чистоты можно сделать так:
interface Doable {
public void doSome();
}
class ExSomeClass extends SomeClass implements Doable {
public void doSome() {
//blah-blah
}
}
class ExSomeNoth extends SomeNoth implements Doable {
public void doSome() {
//blah-blah
}
}
class ExSomeNoth2 extends SomeNoth2 implements Doable {
public void doSome() {
//blah-blah
}
}
В итоге ваш метод будет работать так:
getParams(Doable some) {
some.doSome();
}
Никаких кастов, instanceof
и упаси боже модификации исходных классов.
Что бы действовать подобным образом, надо иметь очень веские на то причины. Стандартным решением будет объявить интерфейс с методом getParams
и имплиментировать его для всех ваших классов.
public interface SomeNothInterface{
public Params getParams();
}
public class SomeNoth implements SomeNothInterface{
....
public Params getParams(){
//логика
}
И вызывать так
public Params getParams(SomeNothInterface someClass) {
return someClass.getParams();
}
У вас тут самый настоящий антипаттерн. Правильный объектно-ориентированный код работает с максимально узкой абстракцией и ему не требуется проверять конкретный тип. Если такая необходимость вдруг появилась, значит вы нарушаете принципы SOLID. К тому же, instanceof
ещё и медленный оператор.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Ну удается запустить websphere application server после изменения настроек памяти, начальный размер кучи и максимальный я оставил поля пустыми, не запускается...
Например: JAS (Java Algebra System)Вопрос в том, какие еще библиотеки существуют для использования? И какие из них можно использовать на Android?
Прошу объяснить, чем опасна "слепая инициализация" на каком-нибудь примере из практики?