草庐IT

java - 简单的CRUD操作异常设计

coder 2024-03-07 原文

我正在开发一个非常小的测试来模拟一个 3 层系统,这样我就可以了解异常是如何工作的。同时我想提出一个合理的方法,以便我可以将此设计作为其他应用程序中类似操作的进一步引用。

我一直在阅读有关该主题的不同文章,似乎对使用已检查或未检查的异常存在巨大争议,这让我对我的最终设计产生了怀疑。

我不会详述用于批评或支持已检查/未检查异常的论点,因为它们可能都是众所周知的,但我会展示我的设计,寻找一些关于如何改进和制作它的建议(只要可能)类似于真实的应用程序。

系统负责使用 JDBC 在关系数据库(比方说 MySQL)中执行基本的 CRUD 操作。我有以下内容:表示层、服务层和持久层。

基于这个答案Handling Dao exceptions in service layer对我来说,不公开特定的层实现和解耦层是有意义的。所以我决定创建我的自定义异常并将它们包装到每层的基本异常中,这样我就可以将特定层异常(即 SQLException)转换为通用层异常(即 PersistentException、BusinessException)。如果稍后实现发生变化,我可以简单地将新的实现包装到更高层期望的基本异常中。所以我有以下异常(exception)情况:

com.user.persistent.exceptions
    |_ PersistentException
    |_ ExistingUserException
    |_ Some more..

com.user.business.exceptions
    |_ BusinessException
    |_ somemore....

摘自 Josh Bloch 的 Effective Java 一书:“使用 可合理预期调用者会出现的条件的已检查异常 恢复。” 我也不太确定,但我相信用户可以从 SQLExeption 中恢复(即用户错误地提供了一个现有 ID,他可以重新输入正确的 ID)所以我决定将之前的exceptions 检查异常。以下是这些类的概览:

持久层。

public interface UserDAO 
{
    public void create(User team) throws PersistentException;
}

//Implementation in DefaultUserDAO.java
@Override
    public void create(User team) throws PersistentException 
    {       
        try
        {
            System.out.println("Attempting to create an user - yikes the user already exists!");
            throw new SQLIntegrityConstraintViolationException();           
        }
        catch(SQLIntegrityConstraintViolationException e)
        {
            throw new ExistingUserException(e);
        }
        catch (SQLException e) 
        {
            throw new PersistentException(e);
        } 
        finally 
        {
            //close connection
        }
    }

服务层:

public interface UserService 
{
    void create(User user) throws BusinessException;
}

//Implementation of UserService
@Override
public void create(User user) throws BusinessException 
{
    System.out.println("Doing some business logic before persisting the user..");

    try 
    {
        userDao.create(user);
    } 
    catch (PersistentException e) 
    {
        throw new BusinessException(e);
    }

}

介绍

    try 
    {
        userService.create(user);
    } catch (BusinessException e) 
    {   
        e.printStackTrace();
    }

现在以下几点让我对这个设计感到不确定。

  1. 我喜欢让编译器验证 使用 checked 时方法捕获/抛出声明的异常 异常(exception)。然而,与此同时,我认为这种方法会导致 处理所有异常的困惑代码。不知道 这是因为我没有正确使用异常或者因为 检查异常确实会导致代码困惑。
  2. 我也喜欢通过包装特定层来解耦层的想法 异常(exception)到一般的。但是,我可以看到很多新类(class) 为每个可能的异常创建而不是仅仅抛出 现有的 Java 异常。
  3. 我还可以看到这个应用程序的很多现有代码是 专门用于处理异常,其中一小部分专门用于 系统的实际目标。

这些实际上是我的主要关注点,让我想知道这是否真的是一个好的设计。我想听听您对此的看法(也许还有一些示例代码的小片段)。你们能给我一些关于如何改进它的提示吗?在某种程度上,我可以实现层之间的解耦并避免泄漏层特定的问题。

最佳答案

我相信您的应用程序在开发完成后不应该处理 SQL 异常。所以,你不应该捕获像 SQLException 这样的异常。或者,如果您被迫捕获它们,则只需重新抛出 RuntimeException。根据我的荣誉经验,创建自己的异常只有在为其他人开发某种库时才有意义。即使在这种情况下,在许多情况下您也可以使用现有的异常。尝试在不创建异常的情况下进行开发。只有当你意识到你离不开它们时才创建它们。

关于java - 简单的CRUD操作异常设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14005083/

有关java - 简单的CRUD操作异常设计的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  3. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  4. ruby-on-rails - Rails - 乐观锁定总是触发 StaleObjectError 异常 - 2

    我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd

  5. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  6. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  7. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  8. ruby - 在 Ruby 中重新分配常量时抛出异常? - 2

    我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案

  9. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  10. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

随机推荐