2009-06-10 31 views
5

Tôi muốn có ý kiến ​​thứ hai về cách xử lý Ngoại lệ trong "sự kiện" (nhập liệu, cập nhật màn hình, v.v.). Trong trường hợp này tôi có quyền kiểm soát người gửi sự kiện.Xử lý ngoại lệ Java trong "sự kiện"

Vì vậy, một mô-đun được thiết lập để xử lý một sự kiện (nó thực hiện một giao diện người nghe, và được đăng ký với một người gửi sự kiện):

public void DefaultSet (CardData oldDefault, CardData newDefault) 
{ 
} 

Người gửi sự kiện chỉ đơn giản là:

 for (Enumeration e = listeners.elements(); e.hasMoreElements();) 
     { 
      RetrieverListener thisListener = (RetrieverListener) e.nextElement(); 
      thisListener.DefaultSet(oldDefault, newDefault); 
     } 

Vì vậy, nếu/khi có sự cố xảy ra trong người nhận:

  • Tôi có nên cố gắng giải quyết ngoại lệ không lại, và không bao giờ ném bất cứ điều gì trở lại cho người gửi? Đôi khi người nghe không có "ngữ cảnh" để xử lý lỗi chính xác, đúng không?

  • Có phải bạn cau mày ném một ngoại lệ trở lại mô-đun gửi sự kiện, để được xử lý theo cách được tài liệu không? ví dụ. "Ném một IOException sẽ dẫn đến một thiết lập lại ..". Điều này có vẻ không chuẩn từ javadocs mà tôi đã đọc.

  • Tôi có nên chỉ cần đăng nhập và bỏ qua ngoại lệ khi có sự cố & không có gì có thể thực hiện được?

Trả lời

6

Quy ước Java là các phương thức người nghe không ném ngoại lệ. Rõ ràng, các lỗi lập trình có thể làm cho người nghe ném một RuntimeException, nhưng không có cách nào nguồn sự kiện có thể phục hồi từ đó bởi vì nó sẽ để lại các đối tượng của chương trình trong một số trạng thái không rõ ràng, có thể không nhất quán.

Do đó, người nghe có thể bắt được ngoại lệ đã kiểm tra và khôi phục ngoại lệ từ họ (ví dụ: quay lại giao dịch) hoặc báo cáo cho một số đối tượng khác. Tôi thường sử dụng giao diện ErrorHandler trông giống như sau:

public interface ErrorHandler { 
    public void errorOccurred(String whatIWasTryingToDo, Exception failure); 
} 

Trình nghe sự kiện cho ErrorHandler biết về lỗi xảy ra.

public class SomeClass implements SomeKindOfListener 
    private final ErrorHandler errorHandler; 
    ... other fields ... 

    public SomeClass(ErrorHandler errorHandler, ... other parameters ...) { 
     this.errorHandler = errorHandler; 
     ... 
    } 

    public void listenerCallback(SomeEvent e) { 
     try { 
      ... do something that might fail ... 
     } 
     catch (SomeKindOfException e) { 
      errorHandler.errorOccurred("trying to wiggle the widget", e); 
     } 
    }   
} 

Tôi lắng nghe sự kiện khởi tạo với việc thực hiện điều này xử lý sự cố theo bất kỳ cách nào có ý nghĩa tại thời điểm đó trong ứng dụng. Nó có thể bật lên một hộp thoại, hiển thị một biểu tượng lỗi nhấp nháy trên thanh trạng thái, đăng nhập một thông báo kiểm toán, hoặc hủy bỏ quá trình, ví dụ.

+0

Kiến trúc thú vị và câu trả lời hữu ích, cảm ơn! Tôi đoán vấn đề của tôi là người nghe không phải lúc nào cũng hướng đến hiển thị mọi thứ hoặc cung cấp phản hồi của người dùng, sử dụng các sự kiện thực sự làm lệch tương tự ngăn xếp từ trên xuống khiến cho Ngoại lệ mạnh mẽ (xử lý ngoại lệ tại điểm thích hợp trong ngăn xếp) , nơi mà một cái gì đó có thể được thực hiện). Dù sao thì tôi nghĩ người nghe sẽ phải đối phó với lỗi, bằng cách này hay cách khác. –

+0

Bạn phải thiết kế hệ thống để làm cho người nghe có thể xử lý lỗi. Một ngoại lệ sẽ giải phóng ngăn xếp lại cho người nghe. Trình lắng nghe đã được gọi bởi một cái gì đó mà không thể biết làm thế nào để phản ứng với ngoại lệ - một nút được gọi trên chuỗi gửi sự kiện Swing, hoặc chuỗi gửi tin nhắn của một nhà cung cấp JMS, chẳng hạn. Bạn phải khởi tạo trình lắng nghe tại một vị trí và thời gian khi bạn có thể cung cấp cho nó tất cả ngữ cảnh cần thiết để phản ứng với ngoại lệ theo một cách hợp lý. – Nat

1

Khi bạn không thể làm gì để đăng nhập và gửi tin nhắn cho người dùng. Nếu có sự cố nào đó có thể làm hỏng dữ liệu hoặc cho kết quả sai nếu bạn không thể phục hồi, bạn nên đóng ứng dụng.

0

Cách tiếp cận thông thường là bỏ qua vấn đề. Người nghe không nên bỏ các ngoại lệ không được kiểm soát.

Cách tiếp cận tốt hơn là bắt và ghi nhật ký RuntimeException s. Chúng thường chỉ ra lỗi lập trình. Nếu một widget trên màn hình ném một NPE, thì không có lý do tại sao phần còn lại của cửa sổ không nên hoàn thành bức tranh. Sau đó, người dùng có thể lưu dữ liệu của họ và khởi động lại hoặc làm việc khác xung quanh vấn đề. Trong trường hợp của Error s nó thường có nghĩa là có một tình huống nghiêm trọng, chẳng hạn như OutOfMemeory và đánh bắt sẽ chỉ dẫn đến đập. Không ai làm điều này.

+0

"không có lý do tại sao phần còn lại của cửa sổ không nên hoàn thành bức tranh" - chắc chắn có; tiện ích bị thiếu có thể rất quan trọng và phần còn lại của cửa sổ có thể vô ích. Trong thực tế, nó có thể là vô ích và dường như đang làm một cái gì đó, đó là một kinh nghiệm người dùng tồi tệ hơn chỉ đơn giản là đâm. Nếu lập trình viên không mong đợi một trạng thái cụ thể nào đó, bạn phải giả định rằng trạng thái chỉ bị phá vỡ. – cdhabecker