2013-05-16 24 views
6

Tôi có một giao diệnGiao diện thực hiện ra mắt trường hợp ngoại lệ khác nhau

public interface DataDAO { 
    public void doSomething() throws Exception; 
} 

Cho phép nói rằng có hai hiện thực, một trong đó sử dụng cơ sở dữ liệu để lấy dữ liệu và một số khác có sử dụng một Webservice.

public class DataDAOJdbc implements DataDAO { 
    public void doSomething() throws Exception { 
     //Implement 
    } 
} 

public class DataDAOWebService implements DataDAO { 
    public void doSomething() throws Exception { 
     //Implement 
    } 
} 

Như bạn có thể thấy, vấn đề là ngoại lệ siêu phổ biến được khởi chạy. Khi cả hai triển khai cần phải nâng cao cùng một loại ngoại lệ.

Việc triển khai Jdbc thực sự chỉ tăng cho phép nói SQLException trong khi triển khai Webservice chỉ tăng IOException.

Câu hỏi là, làm thế nào tôi có thể làm cho giao diện thanh lịch hơn, vì vậy tôi nắm bắt được một ngoại lệ thích hợp?

Điều đầu tiên mà tôi mặc dù đã tạo ra ngoại lệ của riêng tôi, và tuyên bố nó trên cấp độ giao diện

public interface DataDAO { 
    public void doSomething() throws MyCoolException; 
} 

Và sau đó, tất nhiên thực hiện accordinly.

Câu hỏi là, điều này có hợp lý không? Tôi chưa bao giờ tạo ra ngoại lệ của riêng mình, vì vậy tôi không thực sự chắc chắn nếu điều này có ý nghĩa hay không. Ngoài ra, tôi nên tính đến điều gì khi tạo MyCoolException?

+0

Cách lấy cảm hứng từ Spring và gói chúng trong RuntimeExceptions. –

+0

@AjayGeorge, tôi muốn những ngoại lệ đó được xử lý bởi cấp cao hơn, do đó làm cho chúng RuntimExceptions không hợp lệ đối với tôi, sửa tôi nếu tôi sai :) –

+0

Bạn cũng có thể phân lớp RuntimeExceptions và sau đó tạo [DataAccessException] (http : //static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/dao/DataAccessException.html) như vào mùa xuân. –

Trả lời

4

Điều đầu tiên tôi mặc dù đã tạo ngoại lệ của riêng mình và khai báo nó ở cấp độ giao diện (...) điều này có hợp lý không?

Vâng, điều đó có ý nghĩa và tôi nghĩ đó là cách tốt nhất để xử lý các tình huống này.

tôi sẽ cung cấp một ví dụ Kickoff cho điều này (dựa trên mã hiện tại của bạn):

public class MyCoolException extends Exception { 
    public MyCoolException() { 
    } 
    public MyCoolException(String message) { 
     this.message = message; 
    } 
} 

public interface DataDAO { 
    public void doSomething() throws MyCoolException; 
} 

public class DataDAOJdbc implements DataDAO { 
    public void doSomething() throws MyCoolException { 
     //Implement 
     try { 
     } catch (SQLException e) { 
      //handle the exception 
      logger.error("Error!", e); 
      //throw your custom exception 
      throw new MyCoolException(e.getMessage()); 
     } 
    } 
} 

public class DataDAOWebService implements DataDAO { 
    public void doSomething() throws MyCoolException { 
     //Implement 
     try { 
     } catch (IOException e) { 
      //handle the exception 
      logger.error("Error!", e); 
      //throw your custom exception 
      throw new MyCoolException(e.getMessage()); 
     } 
    } 
} 
+1

Hmm, đây là một nitpick, nhưng tôi khuyên bạn nên gói ngoại lệ nguyên nhân (thay vì chuỗi thông báo của nó) bằng 'MyCoolException' và đợi để đăng nhập toàn bộ câu chuyện khi' MyCoolException' được xử lý. –

+1

Tôi hoàn toàn đồng ý với Paul, và tôi thậm chí còn đi xa khi nói rằng đó là điều quan trọng nhất cần cân nhắc khi viết ngoại lệ của riêng bạn (* đặc biệt là * nếu nó có nghĩa là bọc một ngoại lệ khác): không có nguyên nhân gốc, bạn mất * nhiều thông tin có thể cực kỳ quan trọng khi gỡ lỗi mọi vấn đề. –

+0

@PaulBellora Tôi đồng ý với bạn mọi người, đó là lý do tại sao tôi đã nói đây là một ví dụ cơ bản và đăng nhập ngoại lệ trước khi trả lại ngoại lệ tùy chỉnh. –

2

Bạn có thể sử dụng một loại tổng quát để xác định giao diện ném:

public interface DataDAO<E extends Throwable> { 
    public void doSomething() throws E; 
} 

Sau đó, Triển khai của bạn sẽ trông như thế này:

public class DataDAOJdbc implements DataDAO<JDBCException> { 
    public void doSomething() throws JDBCException { 
     //Implement 
    } 
} 

public class DataDAOWebService implements DataDAO<WebServiceException> { 
    public void doSomething() throws WebServiceException { 
     //Implement 
    } 
} 

Tuy nhiên, điều này có nhược điểm mà bạn có thể không còn xử lý tất cả các ngoại lệ theo cùng một cách, trừ khi bạn chỉ bắt được Exception (điều này có thể phủ nhận toàn bộ điểm).

+2

Nhưng giả sử OP muốn mã để giao diện, không thực hiện, điều này sẽ không giúp gọi các trang web cả. –

+0

@PaulBellora điểm tốt, bạn có ý tưởng hay hơn không? –

+0

Cách tiếp cận này phá vỡ đa hình. Một ngoại lệ tùy chỉnh nên được sử dụng. – Mikhail

1

make này có ý nghĩa?

Vâng, đúng vậy. Bằng cách tuyên bố rằng doSomething ném một ngoại lệ được kiểm tra cụ thể, bạn đang báo hiệu cho người gọi của phương thức mà họ chỉ cần nắm bắt và đối phó với ngoại lệ cụ thể đó. Bằng cách khai báo đồng bằng throws Exception, người gọi sẽ được khuyến khích bắt và đối phó với tất cả Exception s, thậm chí bao gồm các ngoại lệ thời gian chạy như NullPointerException.

Tôi nên tính đến điều gì khi tạo MyCoolException?

Nó có thể đơn giản như sau:

public final class MyCoolException extends Exception { 

    public MyCoolException(Throwable cause) { 
     super(cause); 
    } 
} 

Vì vậy ngoại lệ tùy chỉnh của bạn sẽ chỉ đơn giản là hành động như một wrapper cho ngoại trừ nguyên nhân, bất cứ điều gì có thể được. Nếu có thể, bạn có thể thêm thông báo có thông tin bổ sung có thể hữu ích cho việc gỡ lỗi. Khi bắt gặp MyCoolException, bạn có thể bỏ qua nó bằng cách gọi getCause() hoặc chuyển nó vào cuộc gọi đến khung đăng nhập (ngăn xếp của nó sẽ bao gồm nguyên nhân ngoại lệ).

Các vấn đề liên quan