Thiết kế phân cấp ngoại lệ


9

Trong công ty của tôi, chúng tôi đang xây dựng một ứng dụng web chứa các dịch vụ trung tâm máy chủ do chúng tôi tự thiết kế và sau đó chỉ định là giao diện. Tức là các giao diện là ứng dụng cụ thể và sau đó chúng được triển khai với các thư viện bên thứ ba mà chúng ta có thể thay đổi theo thời gian. Khi nói đến các ngoại lệ, tôi đã nhận ra rằng các ngoại lệ được ném bởi các dịch vụ của chúng tôi phải là các ngoại lệ dành riêng cho ứng dụng của chúng tôi, trái ngược với các ngoại lệ cụ thể thực hiện.

Bây giờ, tôi tự hỏi làm thế nào các ngoại lệ của chúng ta nên được cấu trúc và liên quan với nhau.

Đầu tiên, hãy xem xét một ngoại lệ chung MyAppException. Ngoại lệ này chỉ ra rằng một cái gì đó không được khám phá đã sai và điều tốt nhất chúng ta có thể làm là hiển thị một thông báo cho người dùng nói rằng có gì đó không ổn và chúng tôi đang xử lý nó. Lỗi có thể là cơ sở dữ liệu bị lỗi hoặc một cái gì đó similair. Ngoại lệ này sẽ bị ném ra khỏi tất cả các phương thức làm việc với cơ sở dữ liệu.

Thứ hai, xem xét một ngoại lệ MyAppDuplicateException. Ngoại lệ này sẽ chỉ ra rằng người dùng đã cố lưu một cái gì đó vào cơ sở dữ liệu đã có sẵn. Ở đây, chúng ta có thể hiển thị một thông báo lỗi cụ thể hơn nhiều và ngoại lệ này chỉ được đưa ra từ các phương thức chèn hoặc cập nhật các hàng cơ sở dữ liệu.

Ứng dụng này cũng có thể chứa các ngoại lệ khác tương tự như đối MyAppDuplicateExceptionvới các tình huống lỗi bị loại trừ khác. Vd MyAppNotFoundException...

Bây giờ cho câu hỏi của tôi:

  1. Các ngoại lệ khác có nên mở rộng MyAppException? Tôi thực sự thấy không có lý do cho điều này, tôi đã nhìn thấy nó ở rất nhiều nơi và tự hỏi nếu có một mục đích cho nó. Nhược điểm của điều này như tôi thấy đó là một tuyên bố thử / bắt không cần quan tâm đến ngoại lệ cụ thể trong trường hợp này. Nó chỉ có thể bắt ngoại lệ hàng đầu và vì điều này, nó không cần xử lý lỗi cụ thể mà gần như là có ngoại lệ cụ thể.
  2. Nếu các ngoại lệ khác không mở rộng MyAppException, nên MyAppExceptionlà một java.lang.RuntimeException? Điều này sẽ không yêu cầu thực thi mã để bắt nó, điều này đối với tôi nghe có vẻ tự nhiên vì quan điểm của ngoại lệ là nói rằng một cái gì đó chưa biết đã xảy ra và mã thực thi không bị loại trừ để có thể xử lý nó. Mã tại điểm vào của yêu cầu vẫn có thể có câu lệnh try / Catch bắt MyAppExceptionvà đảm bảo rằng thông báo được hiển thị cho người dùng.

chỉnh sửa Không có câu hỏi nếu các trường hợp ngoại lệ cụ thể như MyAppDuplicateExceptionnên được kiểm tra hay không, thì chắc chắn nên được kiểm tra.

Câu trả lời:


9
  1. Đôi khi bạn muốn bắt một loại ngoại lệ cụ thể (ví dụ MyAppDuplicateException) và đôi khi bạn muốn bắt toàn bộ danh mục ngoại lệ (ví dụ MyAppException). Bằng cách MyAppDuplicateExceptionmở rộng, MyAppExceptionbạn cung cấp cho mã cuộc gọi linh hoạt hơn một chút trong cách xử lý các ngoại lệ khác nhau.
  2. Lời khuyên tốt nhất mà tôi đã nghe về điều này là nói chung, bạn nên ném một ngoại lệ được kiểm tra nếu bất cứ điều gì được gọi là phương pháp của bạn tuân theo hợp đồng của nó. Đó là một cách để nói "đây là những điều có thể được dự kiến ​​sẽ thất bại". Tôi chắc chắn sẽ thực hiện MyAppDuplicateExceptionvà các trường hợp ngoại lệ được kiểm tra (ví dụ như không phải RuntimeException ).

Có một bài viết rất hay ở đây sẽ giúp bạn tránh được hầu hết những cạm bẫy phổ biến.


Tôi thấy quan điểm của bạn với nr 1. Tuy nhiên, điều tuyệt vời của tôi là chúng tôi không bao giờ gặp phải tình huống mà chúng tôi muốn nắm bắt tất cả các loại ngoại lệ từ các dịch vụ của mình. Nếu có gì đó không ổn, chúng tôi thực sự muốn biết rõ đó là gì. Điều tôi nghe được từ bạn điểm thứ hai là MyAppException phải là RuntimmeException. (những người khác nên được kiểm tra, không có câu hỏi nào về điều đó)
Ludwig Magnusson

@vaughandroid, liên kết bị hỏng. Đây là kho lưu trữ: Community.oracle.com/docs/DOC-983543
user167569

@ user167569 Cảm ơn những người đứng đầu. Đã sửa liên kết.
vaughandroid

@LudwigMagnusson # 1 cho thấy vấn đề khi bạn muốn bắt một nhánh ngoại lệ tại một thời điểm nhất định, có thể sau khi xử lý các trường hợp cụ thể hơn. Điều đó không giống như bắt tất cả các ngoại lệ. Vấn đề với # 2 là bối cảnh. Bạn có thể nói rằng một IOExceptionngoại lệ thời gian chạy cho Tệp không được tìm thấy nếu tệp là tài nguyên nên có. Tuy nhiên, đó là một ngoại lệ được kiểm tra trong trường hợp người dùng yêu cầu một tên tệp cụ thể có thể tồn tại hoặc không tồn tại. Điều này đặc biệt đúng khi tạo các thư viện mà bối cảnh không được biết trước.
Maarten Bodewes

1

Tôi đã nhận ra rằng các ngoại lệ được ném bởi các dịch vụ của chúng tôi phải là các ngoại lệ dành riêng cho ứng dụng của chúng tôi trái ngược với các ngoại lệ cụ thể thực hiện .

Bằng cách này, bạn có nghĩa là ngoại lệ được xác định bởi việc thực hiện bên thứ ba của bạn? Chính xác?

Đầu tiên, hãy xem xét một ngoại lệ chung MyAppException. Ngoại lệ này chỉ ra rằng> một cái gì đó không được khám phá đã sai và điều tốt nhất chúng ta có thể làm là> hiển thị một thông báo cho người dùng nói rằng có gì đó không ổn và chúng ta đang làm việc với nó. Lỗi có thể là cơ sở dữ liệu bị lỗi hoặc một cái gì đó> similair. Ngoại lệ này sẽ bị ném ra khỏi tất cả các phương thức làm việc với cơ sở dữ liệu.

Nếu loại ngoại lệ này biểu thị một lỗi trong chương trình của bạn không phải do đầu vào của người dùng xấu mà là do một số vấn đề với mã của bạn, thì trong Java, đó phải là một ngoại lệ thời gian chạy.

Thứ hai, hãy xem xét một ngoại lệ MyAppD repeatateException. Ngoại lệ này sẽ> chỉ ra rằng người dùng đã cố lưu một cái gì đó vào cơ sở dữ liệu đã> ở đó. Ở đây, chúng ta có thể hiển thị một thông báo lỗi cụ thể hơn nhiều và ngoại lệ> này chỉ được ném ra từ các phương thức chèn hoặc cập nhật cơ sở dữ liệu> hàng.

Đây là một ngoại lệ được kiểm tra trong Java.

Nếu các ngoại lệ khác không mở rộng MyAppException, MyAppException> có nên là java.lang.R nbException không?

Đúng.

Điều này sẽ không yêu cầu thực thi mã để bắt nó, điều này đối với tôi nghe có vẻ tự nhiên> vì quan điểm của ngoại lệ là nói rằng một cái gì đó chưa biết đã xảy ra và> mã thực thi không bị loại trừ để có thể xử lý nó. Mã tại> điểm nhập của yêu cầu vẫn có thể có câu lệnh try / Catch bắt> MyAppException và đảm bảo rằng thông báo được hiển thị cho người dùng.

Vâng đúng vậy.


Bạn hiểu tôi chính xác.
Ludwig Magnusson

Khi bạn nói rằng lỗi là do "một vấn đề với mã của tôi", tôi chỉ muốn chỉ ra rằng vấn đề cũng có thể xảy ra với kết nối cơ sở dữ liệu, v.v. Không chỉ lỗi trong lập trình.
Ludwig Magnusson
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.