2010-03-15 55 views
8

Tôi đã viết một lớp tải các đối tượng cấu hình của ứng dụng và theo dõi chúng để tôi có thể dễ dàng ghi lại các thay đổi hoặc tải lại toàn bộ cấu hình cùng một lúc bằng một cuộc gọi phương thức duy nhất. Tuy nhiên, mỗi đối tượng cấu hình có thể có khả năng ném một ngoại lệ khi thực hiện IO, nhưng tôi không muốn những lỗi đó hủy bỏ toàn bộ quá trình để cung cấp cho các đối tượng khác vẫn có cơ hội tải lại/ghi. Vì vậy, tôi thu thập tất cả các ngoại lệ được ném trong khi lặp qua các đối tượng và lưu trữ chúng trong một siêu ngoại lệ, được ném sau vòng lặp, vì mỗi ngoại lệ vẫn phải được xử lý và ai đó phải được thông báo về những gì chính xác. Tuy nhiên, cách tiếp cận đó có vẻ hơi lạ với tôi. Có ai đó ở đó với một giải pháp sạch hơn?Xử lý nhiều ngoại lệ

Dưới đây là một số mã của lớp nêu:

public synchronized void store() throws MultipleCauseException 
    { 
    MultipleCauseException me = new MultipleCauseException("unable to store some resources"); 
    for(Resource resource : this.resources.values()) 
     { 
     try 
      { 
      resource.store(); 
      } 
     catch(StoreException e) 
      { 
      me.addCause(e); 
      } 
     } 
    if(me.hasCauses()) 
     throw me; 
    } 

Trả lời

4

Nếu bạn muốn giữ lại các kết quả của các hoạt động, mà có vẻ như bạn làm như bạn cố tình tiếp tục, sau đó ném một ngoại lệ là điều sai trái làm. Nói chung, bạn nên nhằm mục đích không làm phiền bất cứ điều gì nếu bạn ném một ngoại lệ.

Những gì tôi đề xuất là chuyển các ngoại lệ hoặc dữ liệu có nguồn gốc từ chúng sang lỗi xử lý gọi lại khi bạn thực hiện.

public interface StoreExceptionHandler { 
    void handle(StoreException exc); 
} 

public synchronized void store(StoreExceptionHandler excHandler) { 
    for (Resource resource : this.resources.values()) { 
     try { 
      resource.store(); 
     } catch (StoreException exc) { 
      excHandler.handle(exc); 
     } 
    } 
    /* ... return normally ... */ 
] 
+0

Cân nhắc tải lại, các đối tượng ném một ngoại lệ sau đó thể hiện trạng thái nhất quán có thể có mới nhất (tức là giữ bản sao cũ của cấu hình). –

3

Có nguyên tắc chỉ đạo trong việc thiết kế những gì và khi nào ngoại lệ nên được ném ra, và hai người có liên quan cho kịch bản này là:

  • Ném ngoại lệ phù hợp với trừu tượng (ví dụ mô hình ngoại lệ dịch)
  • ngoại lệ Ném sớm nếu có thể

cách bạn dịch StoreException-MultipleCauseException se ems hợp lý với tôi, mặc dù gộp các loại khác nhau của ngoại lệ thành một có thể không phải là ý tưởng tốt nhất. Thật không may Java không hỗ trợ chung Throwable s, vì vậy có lẽ thay thế duy nhất là tạo ra một phân lớp MultipleStoreException riêng biệt thay thế.

Liên quan đến việc ném ngoại lệ càng sớm càng tốt (bạn KHÔNG làm), tôi sẽ nói rằng bạn có thể bẻ cong quy tắc trong một số trường hợp nhất định. Tôi cảm thấy sự nguy hiểm của việc trì hoãn một cú ném là khi các tình huống đặc biệt gây ra phản ứng dây chuyền không cần thiết. Bất cứ khi nào có thể, bạn muốn tránh điều này và bản địa hóa ngoại lệ cho phạm vi nhỏ nhất có thể.

Trong trường hợp của bạn, nếu khái niệm về lưu trữ tài nguyên theo khái niệm là nhiều tác vụ độc lập thì có thể "xử lý hàng loạt" ngoại lệ theo cách bạn đã làm. Trong các tình huống khác, nơi mà các nhiệm vụ có mối quan hệ phụ thuộc lẫn nhau phức tạp hơn, tuy nhiên, gộp tất cả lại với nhau sẽ làm cho nhiệm vụ phân tích các ngoại lệ trở nên khó khăn hơn.

Trong một ý nghĩa trừu tượng hơn, trong các thuật ngữ lý thuyết đồ thị, tôi nghĩ rằng có thể hợp nhất một nút với nhiều trẻ em không có con vào một. Có thể không hợp nhất một cây con lớn, hoặc thậm chí tệ hơn, một biểu đồ tuần hoàn, thành một nút.

+0

Bạn không thể loại trừ các trường hợp ngoại lệ trong Java. –

+0

Wow, đó là một bất ngờ. Cảm ơn bạn đã chỉ ra điều đó. – polygenelubricants

+0

Đã thử nó và đã ngạc nhiên như nhau. Tuy nhiên, tôi không thấy bất kỳ lý do gì kể từ khi generics chỉ mở rộng vào một số phôi tiềm ẩn mà sẽ thực sự hữu ích ở đây.Có lẽ ai đó nghĩ rằng "chúng tôi có loại xóa và một cái gì đó như bắt (GenericException e) {} bắt (GenericException e) {} sẽ không hoạt động, vì vậy chúng tôi ngăn các lập trình viên thậm chí cố gắng" –