Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 调用另一个类中的方法';让我们试一下拦网_Java_Design Patterns - Fatal编程技术网

Java 调用另一个类中的方法';让我们试一下拦网

Java 调用另一个类中的方法';让我们试一下拦网,java,design-patterns,Java,Design Patterns,我有一些遵循这种模式的方法 try(Connection connection = MySqlConnection.getConnection()){ PreparedStatement statement = connection.prepareStatement( "Insert into db values (NULL ,?,?,?,?,?, NULL , ?)", Statement.RETURN_GENER

我有一些遵循这种模式的方法

try(Connection connection = MySqlConnection.getConnection()){
        PreparedStatement statement = connection.prepareStatement(
                "Insert into db values (NULL ,?,?,?,?,?, NULL , ?)",
                Statement.RETURN_GENERATED_KEYS);
        ...
        statement.executeUpdate();
        ...
    }
    catch(SQLException e) {
        throw new RuntimeException(e);
    }

我被告知将try-catch-with-connection提取到类MySqlConnection,并创建一个新方法,该方法将执行所有逻辑并封装创建连接。因此,我不太了解这种方法,也不知道如何在不编写一些难看的模板或策略的情况下解决它。还是保持原样比较好,或者可以简单地实现?

使用java功能接口将异常处理与业务逻辑分开,如下所示:

public class ExceptionHandler() {

    public R execute(Function<T,R> function, T argument) {
        try {
           return function.apply(argument)
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
    }
}
public void doSomeUpdate() {
    ConnectionHelper.doWithConnection(connection -> {
        PreparedStatement statement = connection.prepareStatement(
                "Insert into db values (NULL ,?,?,?,?,?, NULL , ?)",
                Statement.RETURN_GENERATED_KEYS);
        statement.executeUpdate();
    });
}
public boolean doSomeQuery() {
    return ConnectionHelper.doWithConnection(connection -> {
        PreparedStatement statement = connection.prepareStatement("SELECT * FROM table");
        return statement.execute();
    });
}
public类异常处理程序(){
公共R执行(函数,T参数){
试一试{
返回函数.apply(参数)
}捕获(例外e){
抛出新的运行时异常(e);
}
}
}
现在,您可以将包含逻辑的任何函数传递给上面的类,并且处理异常将是独立的

此外,通过这种方式,您可以创建许多有用的方法和类,这些方法和类的工作方式类似于代理,或者每个操作都需要这些方法和类,它们将独立于您的业务逻辑

例如,以同样的方式,您可以编写:

  • 您自己的交易管理
  • 记录输入和输出
  • 检查用户和权限
  • 以及任何其他拦截器

  • 创建一个将处理异常的ConnectionHelper。这有点棘手,您必须定义自己的功能接口,因为标准使用者无法处理选中的SQLExceptions:

    public class ConnectionHelper {
    
        @FunctionalInterface
        public interface ConnectionConsumer {
            void accept(Connection connection) throws SQLException;
        }
    
        public static void doWithConnection(ConnectionConsumer connectionConsumer) {
            try (Connection connection = MySqlConnection.getConnection()) {
                connectionConsumer.accept(connection);
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
    
    然后像这样使用它:

    public class ExceptionHandler() {
    
        public R execute(Function<T,R> function, T argument) {
            try {
               return function.apply(argument)
            } catch (Exception e) {
               throw new RuntimeException(e);
            }
        }
    }
    
    public void doSomeUpdate() {
        ConnectionHelper.doWithConnection(connection -> {
            PreparedStatement statement = connection.prepareStatement(
                    "Insert into db values (NULL ,?,?,?,?,?, NULL , ?)",
                    Statement.RETURN_GENERATED_KEYS);
            statement.executeUpdate();
        });
    }
    
    public boolean doSomeQuery() {
        return ConnectionHelper.doWithConnection(connection -> {
            PreparedStatement statement = connection.prepareStatement("SELECT * FROM table");
            return statement.execute();
        });
    }
    
    只要您不必从数据库中返回任何内容(这种情况很少发生),这种方法就可以很好地工作。因此,我们需要使用另一个函数接口来扩展helper,
    ConnectionFunction
    ,以便在需要返回对象时使用:

    public class ConnectionHelper {
    
        @FunctionalInterface
        public interface ConnectionConsumer {
            void accept(Connection connection) throws SQLException;
        }
    
        public static void doWithConnection(ConnectionConsumer connectionConsumer) {
        ...
        }
    
        @FunctionalInterface
        public interface ConnectionFunction<T> {
            T apply(Connection connection) throws SQLException;
        }
    
        public static <T> T doWithConnection(ConnectionFunction<T> connectionFunction) {
            try (Connection connection = MySqlConnection.getConnection()) {
                return connectionFunction.apply(connection);
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
    
    更新 使用
    SQLIntegrityConstraintViolationException
    的2种解决方案:

    自身,运行时异常: 由于这是一个运行时异常,您只需在需要的地方添加try-catch

    public static class MySQLIntegrityConstraintViolationException extends RuntimeException {
        public MySQLIntegrityConstraintViolationException(Throwable cause) {
            super(cause);
        }
    }
    
    public static void doWithConnection(ConnectionConsumer connectionConsumer)       {
        try (Connection connection = MySqlConnection.getConnection()) {
            connectionConsumer.accept(connection);
        } catch (SQLIntegrityConstraintViolationException e) {
            throw new MySQLIntegrityConstraintViolationException(e);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    
    插入连接
    doWithConnection()
    的专用版本。同样,仅在适用的情况下使用

    public static void insertWithConnection(ConnectionConsumer connectionConsumer) throws SQLIntegrityConstraintViolationException {
        try (Connection connection = MySqlConnection.getConnection()) {
            connectionConsumer.accept(connection);
        } catch (SQLIntegrityConstraintViolationException e) {
            throw e;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    

    “有人告诉我”问告诉你的人。你问题中提供的代码看起来已经符合规范,或者你不确定如何实现
    MySqlConnection.getConnection()
    ?@AndyTurner,我期望这个问题=)。奇怪的是,我现在不能联系这个人,但工作必须完成。@Anguium这种事情可以很容易地用intellij中的结构化搜索和替换之类的东西进行重构。始终如一地编写所有方法,然后在知道如何完成的人返回后一次性重构它们。我们提出的任何建议都可能不是他们想要的,所以无论如何你都必须重做。这看起来像是我尝试做的更好的版本,但仍然存在一些问题。当用于插入数据时,它可以为重复条目抛出SQLIntegrityConstraintVIolationException。为了简单地重新显示它,我必须将它添加到doWithConnection签名中。这就是事情变得复杂的地方。由于这个签名,我必须捕获前面提到的异常,比如当我“选择”数据时,它不可能被抛出。没有任何意义,对吗?@Anguium有两种解决方案:要么创建自己的运行时,要么创建IntegrityViolationException。或者在帮助器中创建一个
    insertWithConnection()
    。查看我的更新。