2013-09-18 2 views
3

Пожалуйста, какие-либо идеи о том, как рефакторировать этот код Java, поэтому мне не нужно повторять эти кодовые блоки 3 (или более) раза?рефакторинг обязательный map.get код Java

Integer id = null; 
try { 
    id = (Integer)extradata.get("id"); 
} 
catch(Exception e) { 
    logger.error(e); 
} 

if (id == null) { 
    logger.error("no id set"); 
    task.setStatus(Status.ERROR); 
    DBService.updateTaskStatus(conn, false, task); 
    conn.commit(); 
    return; 
} 

String name = null; 
try { 
    name = (String)extradata.get("name"); 
} 
catch(Exception e) { 
    logger.error(e); 
} 

if (name == null) { 
    logger.error("no name set"); 
    task.setStatus(Status.ERROR); 
    DBService.updateTaskStatus(conn, false, task); 
    conn.commit(); 
    return; 
} 

String city = null; 
try { 
    city = (String)extradata.get("city"); 
} 
catch(Exception e) { 
    logger.error(e); 
} 

if (city == null) { 
    logger.error("no city set"); 
    task.setStatus(Status.ERROR); 
    DBService.updateTaskStatus(conn, false, task); 
    conn.commit(); 
    return; 
} 
+1

Что у них общего? Где они отличаются? Создайте функцию, которая использует предыдущую, и берет последнюю как параметры. –

+1

И ты действительно хочешь идти в лицо всем исключениям? Ловить 'Исключение' почти * всегда * плохая идея. –

+0

Да, это основная идея, как я делал во многих других случаях ... но в этом случае это кажется сложнее, потому что кажется странным для внешней функции, которая просто получит значение переменной для фиксации соединения mysql (не только для получения значения conn в качестве параметра) – Lem0n

ответ

1
Integer id = null; 
String name = null; 
String city = null; 

try { 
    id = (Integer)extradata.get("id"); 
    name = (String)extradata.get("name"); 
    city = (String)extradata.get("city"); 
catch(Exception e) { 
    logger.error(e); 
} 

if (id == null || name == null || city == null) { 
    String msg = (id == null ? "id" : name == null ? "name" : "city"); 
    logger.error("no "+msg+" set"); 
    task.setStatus(Status.ERROR); 
    DBService.updateTaskStatus(conn, false, task); 
    conn.commit(); 
    return; 
} 
+1

, который выглядит как хорошее решение! – Lem0n

+0

Протестирован тройной .. oh boy – Cruncher

+1

@Cruncher давай, это не так плохо: D – alfasin

1

Вы можете определить метод, который проверяет строку для null, и обновляет статус, как это:

private static boolean isValid(
    Object obj 
, String msg 
, Connection conn 
, Task task) { 
    if (obj != null) return true; 
    logger.error(msg); 
    task.setStatus(Status.ERROR); 
    DBService.updateTaskStatus(conn, false, task); 
    conn.commit(); 
    return false; 
} 

Теперь вы можете изменить основной метод для вызова checkValidString неоднократно:

Integer id = null; 
try { 
    id = (Integer)extradata.get("id"); 
} catch(Exception e) { 
    logger.error(e); 
} 
if (!isValid(id, "no id set", conn, task)) return; 

String name = null; 
try { 
    name = (String)extradata.get("name"); 
} catch(Exception e) { 
    logger.error(e); 
} 
if (!isValid(name, "no name set", conn, task)) return; 

String city = null; 
try { 
    city = (String)extradata.get("city"); 
} 
catch(Exception e) { 
    logger.error(e); 
} 
if (!isValid(city, "no city set", conn, task)) return; 
+0

Приятно, но он все равно должен использовать 3 разных try/catch с этим решением;) – alfasin

0

Попробуйте следующее:

Integer id = null; 
    try { 
     id = (Integer)extradata.get("id"); 
    } 
    catch(Exception e) { 
     logger.error(e); 
    } 

    if (id == null) { 
     handleNullVariable("id"); 
     return; 
    } 

    String name = null; 
    try { 
     name = (String)extradata.get("name"); 
    } 
    catch(Exception e) { 
     logger.error(e); 
    } 

    if (name == null) { 
     handleNullVariable("name"); 
     return; 
    } 

    String city = null; 
    try { 
     city = (String)extradata.get("city"); 
    } 
    catch(Exception e) { 
     logger.error(e); 
    } 

    if (city == null) { 
     handleNullVariable("city"); 
     return; 
    } 

    void handleNullVariable(String variableName) 
    { 
    logger.error("no "+ variableName + " set"); 
    task.setStatus(Status.ERROR); 
     DBService.updateTaskStatus(conn, false, task); 
     conn.commit(); 
     } 
+0

это лучше, но все же повторяю много кода – Lem0n

3

Вы можете использовать статический универсальный метод:

private static final <T> T getValue(Map<String, Object> extradata, String key, Class<T> clazz) { 
    Object val = extradata.get(key); 
    if (val == null) { 
     handleNullVariable("name"); 
     return null; 
    }   
    return clazz.cast(val); 
} 

Тогда вы можете назвать его:

Integer id = getValue(extradata, "id", Integer.class); 
String name = getValue(extradata, "name", String.class); 
+1

+1 красивый! (избегая исключений, всегда хорошая идея!) :) – alfasin

0
class NotFoundException extends Exception { 
} 
... 
Object getValue(String name) { 
    Object res; 
    try { 
     res=extradata.get(name); 
    } catch(Exception e) { 
     logger.error(e); 
    } 
    if (res == null) { 
     logger.error("no "+name+" set"); 
     task.setStatus(Status.ERROR); 
     DBService.updateTaskStatus(conn, false, task); 
     conn.commit(); 
     throw new NotFoundException(); 
    } 
} 
... 
try { 
    Integer id = (Integer)getValue("id"); 
    String name = (String)getValue("name"); 
    String city = (String)getValue("city"); 
} catch(Exception e) { 
    return; 
} 
+0

Проблема, которую я вижу с этим решением, заключается в том, что для функции getValue() нужны параметры extradata, conn и task (если я не хочу объявлять их как поля, безопасность), которая кажется уродливой (т. е. вне сферы действия того, что она должна делать) – Lem0n

+0

и теперь являются локальными переменными 'extradata, conn и task'? –

0
public static <E> E getData(String key) 
{ 
    E ret = null; 
    try { 
     ret = (E)extradata.get(key); 
    } 
    catch(Exception e) { 
     logger.error(e); 
    } 

    if (ret == null) { 
     throw new Exception(key); 
    } 
    return ret; 
} 

Назовите это с

try 
{ 
    Integer id = getData("id"); 
    String name = getData("name"); 
    String city = getData("city"); 
} 
catch(Exception e) 
{ 
    logger.error("no " + e.getMessagE() + " set"); 
    task.setStatus(Status.ERROR); 
    DBService.updateTaskStatus(conn, false, task); 
    conn.commit(); 
    return; 
} 
+0

Тот же комментарий, что и для Алексея: проблема, которую я вижу в этом решении, заключается в том, что функции getData() потребуются параметры extradata, conn и task (если я не хочу объявлять их как поля, а также заботиться о безопасности потоков), что кажется уродливым (т. е. вне сферы действия того, что он должен делать) – Lem0n

+0

Я не уверен, что проблема с параметрами передачи – Cruncher

+0

Я думаю, что обычно люди будут считать, что функция, называемая «getData», не будет передавать что-либо в базу данных. Конечно, вы могли бы назвать это getDataAndActOnErrors, но для меня это кажется подсказкой, что-то не так. – Lem0n

Смежные вопросы