Java 对我的代码的批评/建议

Java 对我的代码的批评/建议,java,Java,在我进一步研究之前,我很高兴知道到目前为止我的程序中是否存在任何主要的设计缺陷。在我继续之前有什么值得改变的吗 模型 Servlet public class Service extends HttpServlet { @SuppressWarnings("rawtypes") protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletExceptio

在我进一步研究之前,我很高兴知道到目前为止我的程序中是否存在任何主要的设计缺陷。在我继续之前有什么值得改变的吗

模型

Servlet

public class Service extends HttpServlet {

    @SuppressWarnings("rawtypes")
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("Movies!");
        MovieDatabase movies = new MovieDatabase();

        try {
            List results = movies.queryMovies();
            Iterator it = results.iterator();

            while(it.hasNext()) {
                MovieBean movie = new MovieBean();
                movie = (MovieBean)it.next();
                out.println(movie.getYear());
            }
        }
        catch(SQLException e) {

        }

    }
}
豆子


这是非常简单和直接的,没有大问题。我唯一要指出的是,您正在执行一个
SELECT*
,然后参考列索引的结果集。这在这个阶段不是问题,但是如果您的模式发生了更改(例如,在中间添加了一个字段),那么您的代码就会中断。我将明确选择列名:

SELECT id, title, year, rating FROM movie

以下是几点建议:

  • 您的MovieDatabase中嵌入了连接创建。您不会以这种方式使用连接池
  • 在代码中嵌入连接参数(例如,驱动程序类、URL等)。最好将它们外部化
  • 您不会清理任何JDBC资源。这肯定会给你带来悲伤
  • 你有空的挡块。这是一个令人发指的错误。记录堆栈跟踪。你将无法知道是否有任何错误的编码
  • 电影豆?名字很重要——让它成为电影
  • 默认构造函数什么都不做,它是您提供的唯一构造函数。对标题的字符串引用将为空。我认为您应该有一个构造函数来正确初始化所有字段
  • 您的服务不应该扩展Servlet。我认为您应该有一个POJO接口和一个与HTTP无关的实现。没有web,您无法使用(或测试)此服务
  • 又是一个空的抓块——你在自找麻烦。您什么时候学习打印堆栈跟踪
  • 我不会有电影数据库;我会使用具有CRUD操作的MovieDao界面,如下所示:
包持久化;
公共界面电影
{
列表查找();
电影查找(int-id);
列表查找(字符串标题);
无效保存(电影);
无效更新(电影);
作废删除(电影);
}

以下大部分是风格,不一定是“正确”的方式,当然也不是唯一的方式

  • 我会移动数据库连接 到servlet的doGet中的try块。我会通过考试的 连接到 电影数据库#查询视频。这个 原因是,如果在同一个请求中您需要 使用另一个查询执行另一个查询 上课?你的电话接通了 MovieDatabase和另一个类 我将无法访问它。如果两个类都可以更新数据库,则无法回滚整个事务。不太好
  • 我会在doGet中“成功”路径的末尾添加一个commit语句
  • 我会在包含数据库连接的after-try块中添加一个异常块,在该异常块中我会发出回滚。因此,如果出现异常,每次都会执行回滚
  • 我将在中关闭数据库连接 #多吉特终于成功了。这是最重要的编辑-有关示例,请参见下面的伪代码
  • 如果不将连接移动到servlet中,则直接 你应该把它关上 queryMovies’finally中的连接 条款
  • 如果这是一个更大的项目,我会使用Hibernate及其工具 生成DAO和模型。冬眠 将为您生成一个类和 方法,该方法将返回 收集电影豆给你。 你什么都不用做,除了 调用它。自动生成数据库 密码很好
  • 我将添加一个JSP并将您正在构建的集合放入请求中。然后jsp可以在集合上迭代,并根据需要对其进行格式化。这将信息的表示移出servlet,servlet是动作的协调器,而不是MVC模型中的数据格式化程序
  • 如果您实现了上述建议,那么您的代码行数可能会减少50%或更多。学习Hibernate可能是一件头疼的事,所以第一次学习Hibernate不一定会更容易或更快。它减少了代码行(同时做了几乎相同的工作)的原因是生成的代码非常正确,编码人员不必担心

    我一直在servlet中使用以下模式。这是伪代码,不是真正的java

       Connection conn = null;
       try {
          conn.getConnection(...);
          // your implementation here
          conn.commit();
       } catch (Exception e) {
          conn.rollback();
       } finally {
          conn.close();
       }
    

    关键是数据库连接始终可以传递给工作人员,除非出现问题,否则工作始终是提交的。如果出现问题,肯定会出现回滚。在任何一种情况下,数据库连接都会在其全部结束时关闭。

    有很多错误(很多人已经指出了其中的大部分)。代码好像是90年代写的。我强烈建议您阅读有关、、模式的内容。然后你自己回答这个问题,我会投票支持你的答案;-)

    所以对于代码审查来说,这不是一个好的选择。似乎代码是在90年代编写的。阅读有关MVC、分层体系结构、关注点分离的文章。SSO可能不用于代码审查,但他做到了自己的一部分。我不介意帮助那些尝试的人。我投票以“不是一个真正的问题”作为结束,仅仅是因为在你可以从代码本身推断的范围之外,绝对没有给出任何上下文。由于上下文是由潜在的错误代码推断出来的(因此代码审查),这不是一个好问题,因为所有好的设计决策都依赖于对上下文的良好把握。高质量的答案让我重新考虑结束这个问题。我不同意-数据库操作不属于servlet。如果没有servlet引擎,就无法进行测试。有一个服务POJO接口和实现,您可以在没有servlet引擎的情况下进行测试;然后让servlet调用该服务。这只是一个小小的区别,但是如果没有web层,您的服务是可测试和有用的。您的意思是将上面的伪代码放入pojo,让servlet实例化pojo,并调用pojo的#doIt方法?那么我应该创建一个数据库类吗?@aLk关键部分
    SELECT id, title, year, rating FROM movie
    
    package persistence; 
    
    public interface MovieDao
    {
        List<Movie> find();
        Movie find(int id);
        List<Movie> find(String title);
        void save(Movie movie);
        void update(Movie movie);
        void delete(Movie movie);
    }
    
       Connection conn = null;
       try {
          conn.getConnection(...);
          // your implementation here
          conn.commit();
       } catch (Exception e) {
          conn.rollback();
       } finally {
          conn.close();
       }