Ví dụ đầu tiên thường được xem là cách tiếp cận tốt hơn.
Bạn cũng nên không xem xét các MyBusinessException
là gói các NumberFormatException
, mà là NumberFormatException
là nguyên nhân của MyBusinessException
.
Ngoại lệ phải phù hợp với giao diện đang được hiển thị. Người gọi giao diện của bạn không cần phải biết hoặc xử lý các chi tiết triển khai. Trừ khi NumberFormatException
thực sự có ý nghĩa như một loại lỗi khi gọi số exampleOneException
, nó phải được dịch sang một ngoại lệ phù hợp hơn.
Ví dụ cụ thể hơn thường bao gồm các triển khai khác nhau, nơi người dùng không cần giao diện để xử lý các chi tiết cụ thể (có thể không được biết lúc biên dịch).
interface MyRepository {
Object read(int id) throws ObjectNotFoundException;
}
// a sql backed repository
class JdbcRepository implements MyRepository {
public Object read(int id) throws ObjectNotFoundException {
try { ... }
catch (SQLException ex) {
throw new ObjectNotFoundException(ex);
}
}
}
// a file backed repository
class FileRepository implements MyRepository {
public Object read(int id) throws ObjectNotFoundException {
try { ... }
catch (FileNotFoundException ex) {
throw new ObjectNotFoundException(ex)
}
}
}
Vì giao diện khai báo các loại lỗi có thể trả về, khách hàng của giao diện đó có thể nhất quán và hợp lý. Thêm mã để xử lý FileNotFoundException
và SQLException
thì việc triển khai thực tế có thể là hoặc không, không phải là tuyệt vời.
Cân nhắc xem có nhiều địa điểm trong việc triển khai FileRepository
có thể ném FileNotFoundException
hay không. Điều đó có ngụ ý mỗi và mọi người trong số họ ngụ ý đối tượng không được tìm thấy?
Khi xem xét tùy chọn hai, exampleTwoException
, điều quan trọng là nhận ra rằng khối catch
của bạn cho biết hiệu quả của bất kỳ lỗi nào xảy ra đã được giảm nhẹ. Có là trường hợp ngoại lệ kiểm tra sẽ được bỏ qua một cách hợp lý, nhưng nó là nhiều khả năng rằng một đơn giản
try { ... }
catch (SomeException ex) {
log.error("caught some exception", ex);
}
thực sự là kết quả của một nhà phát triển không cân nhắc những hậu quả của ngoại lệ, hoặc mã nên tôi đã bao gồm một FIXME
.
Điều này thậm chí còn đúng hơn khi bạn thấy catch (Exception ex)
hoặc catch (Throwable ex)
không thể chấp nhận được. Và cuối cùng, bạn có muốn trở thành người đào sâu thông qua một ứng dụng tìm kiếm tất cả các địa điểm mà bạn cần thêm (chưa) một khối đánh bắt khác để xử lý triển khai mới không? Không. Có lẽ đó là một nguyên nhân của catch (Exception ex)
...
Luôn ngoại lệ ném phù hợp với trừu tượng
Phương thức gọi là 'exampleOneException' có thể bắt' MyBusinessException' và xử lý theo yêu cầu riêng của chúng. Các phương thức gọi 'exampleTwoException' không có cách nào để biết rằng mọi thứ đã sai. – khelwood
Đây là những điều cơ bản khác nhau. Cách tiếp cận bạn nên sử dụng tùy thuộc vào cách bạn muốn phản hồi các lỗi - ví dụ: chỉ cần đăng nhập chúng cục bộ, chuyển tiếp chúng hoặc logic kinh doanh chuyên dụng thay đổi hành vi khi xảy ra lỗi. –
Hai đoạn mã đó không hoạt động giống nhau. Trong một trong những bạn đang rethrowing ngoại lệ trong khác bạn chỉ cần đăng nhập nó. –