Обертка кода с общей функциональностью при передаче параметра - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть следующий код:

public void createProject() throws ServiceException {
    Project project = new ProjectMapper().map(pipeline);

    // repeating code
    Connection conn;
    try {
        conn = JDBCConnectionManager.getConnection(POOL_NAME, DB_CONNECTION_TIMEOUT);
    } catch (SQLException e1) {
        e1.printStackTrace();
        throw new ServiceException(e1);
    }
    try {
    // end repeating code

        ProjectAccess.writeProject(conn, project);

    // repeating code
    } catch (SQLException | JsonProcessingException e) {
        e.printStackTrace();
        throw new ServiceException(e);
    } finally {
        try {
            releaseConnection(conn);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(e);
        }
    }
    // end repeating code
}

В основном я хочу избавиться от двух блоков try / catch и поместить их в оболочку, поскольку они всегда одинаковы. Я подумал об использовании функционального интерфейса, и он почти работает, за исключением того, что я должен передать переменную conn в мой код, который не работает с моим решением:

@FunctionalInterface
interface DatabaseLogic {        
    public void execute() throws SQLException, JsonProcessingException;        
}

public void executeSql(DatabaseLogic dl) throws ServiceException {
    Connection conn;
    try {
        conn = JDBCConnectionManager.getConnection(POOL_NAME, DB_CONNECTION_TIMEOUT);
    } catch (SQLException e1) {
        e1.printStackTrace();
        throw new ServiceException(e1);
    }
    try {
        dl.execute(conn);
    } catch (SQLException | JsonProcessingException e) {
        e.printStackTrace();
        throw new ServiceException(e);
    } finally {
        try {
            releaseConnection(conn);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(e);
        }
    }
}


    new DatabaseRunner().executeSql(() -> {
        IDataCursor pipelineCursor = pipeline.getCursor();
        String projectName = IDataUtil.getString(pipelineCursor, "projectName");
        // how can I access the conn object here?
        ProjectAccess.deleteProject(conn, projectName);
    });

Итак, как я писал в комментарий, есть ли способ использовать функциональный интерфейс и получить доступ к переменной из метода вложения?

1 Ответ

1 голос
/ 19 февраля 2020

Хммм, конечно, я понял это через несколько минут. Мне просто нужно добавить параметр Connection в интерфейс:

public void execute(Connection conn) throws SQLException, JsonProcessingException;

new DatabaseRunner().executeSql((conn) -> {
    IDataCursor pipelineCursor = pipeline.getCursor();
    String projectName = IDataUtil.getString(pipelineCursor, "projectName");
    ProjectAccess.deleteProject(conn, projectName);
});
...