2009-06-24 26 views
6

Tôi đã API sau:Java API nghỉ

public interface MyApi { 

    /** 
    * Performs some stuff. 
    * @throws MyException if condition C1 
    */ 
    public void method() throws MyException; 
} 

Tôi bây giờ thực hiện việc sửa đổi sau đây trong việc thực hiện API của tôi

public class MyApiImpl { 

    public void method() throws MyException { 
    if (C1) { 
     throw new MyException("c1 message"); 
    } 
    ... 
    } 
} 

được thay thế bằng:

public class MyApiImpl { 

    public void method() throws MyException { 
    if (C1) { 
     throw new MyException("c1 message"); 
    } else if (c2) { 
     throw new MyException("c2 message"); 
    } 
    ... 
    } 
} 

Bạn xem xét điều này như là một breakage API?

Mã của khách hàng sẽ vẫn biên dịch nhưng hợp đồng phương thức được xác định bởi javadoc API không còn được tôn trọng vì MyExcepiton bị ném bởi điều kiện "mới".

Nếu chỉ tệp API API của tôi được cập nhật, ứng dụng khách sẽ vẫn hoạt động nhưng tùy thuộc vào cách khách hàng bắt ngoại lệ, hành vi ứng dụng có thể thay đổi rất nhiều.

Quan điểm của bạn về điều đó là gì?

Trả lời

7

Có, bạn đang phá vỡ hợp đồng giao diện bằng cách ném một ngoại lệ khi C1 không xảy ra.

Theo nguyên tắc, vaguer giao diện hợp đồng, dễ dàng hơn nó không phải là để phá vỡ :) Nếu giao diện không được định nghĩa trong điều kiện của một C1 rõ ràng, nhưng trong điều kiện chung chung hơn, cung cấp nhiều hơn Mềm dẻo.

6

Quan điểm của tôi là bạn không nên thay đổi hợp đồng được xác định bởi API trong tài liệu. Nếu bạn cần hành vi mới, bạn nên hoặc.) Tạo một phương thức mới có thể được gọi bởi máy khách phản ánh hành vi mới này hoặc b.) Thảo luận với khách hàng về nhu cầu thay đổi và làm cho họ biết về nó.

Điều này thực sự có thể đi cả hai cách, đó là giữa bạn và khách hàng của bạn như những gì phương pháp tiếp cận của bạn sẽ được.

1

Phần lớn phụ thuộc vào những gì c2. Là nó trong giới hạn hợp lý trên hợp đồng đã tồn tại từ trước? Nếu vậy, bạn thỏa mãn hợp đồng bằng cách ném một MyException. Nếu không thì có lẽ bạn cần phải ném một loại ngoại lệ mới.

Tôi nên chỉ ra rằng tôi không phải là một fan hâm mộ lớn của ngoại lệ đã kiểm tra. Cuối cùng, buộc ai đó phải đối phó với ngoại lệ không nhất thiết phải làm cho mã của họ tốt hơn hoặc an toàn hơn (thực tế nó có thể có tác dụng ngược lại vì họ có thể nuốt chửng các ngoại lệ giả).

1

Tôi muốn nói "không", không có ngắt API, trừ khi MyException là RuntimeException. Sau đó nó là.

Dù sao, tôi muốn phân lớp MyException cho tình trạng C2

Và cả hai điều kiện C1 và C2 nên "đặc biệt" IMHO, tôi sẽ không làm cho một thói quen ném ngoại lệ

1

Đó là một vỡ. Liệu API có được thi hành bởi các cấu trúc ngôn ngữ hay đơn giản là tài liệu không liên quan.

Liệu sự cố này có gây ra sự cố cho mã máy khách hay không là một câu hỏi khác. Nó có thể là bạn đang sửa chữa một lỗi và cần phải bao gồm trường hợp C2 theo cách này để sửa chữa nó. Từ đó các nhà phát triển mã khách hàng tôn trọng có thể hạnh phúc rằng bạn đã thực hiện thay đổi này (giả sử họ hiện không làm việc xung quanh lỗi này theo cách sẽ phá vỡ khi đối mặt với thay đổi này!)

1

Tôi nghĩ rằng vấn đề ở đây là bạn đã thực hiện một phần giao diện của bạn, điều kiện cụ thể triển khai. Nếu điều kiện "C1" chỉ là một phần của việc triển khai của bạn, thì bạn có thể đã tạo một triển khai mới đơn giản để ném ngoại lệ lên "C1" hoặc "C2" mà không phá vỡ giao diện.