2011-07-25 24 views
10

Rất nhiều chức năng của tôi có một tải trọng toàn bộ mã xác nhận ngay dưới tờ khai:Có cách nào hay để khẳng định trước điều kiện trong các phương thức Java?

if (! (start < end)) { 
    throw new IllegalStateException("Start must be before end."); 
    } 

Tôi muốn precisly xác định phạm vi hiệu lực của một số nguyên liệu đầu vào - ví dụ như một A> B, C => 1 hoặc str_d.length()> 0.

Cho rằng một số chức năng của tôi có khá nhiều đối số phải được xác thực tôi có thể kết thúc bằng cách viết nhiều bản mẫu để xác thực các điều kiện trước. Tôi đang viết thư viện chủ yếu sẽ được các nhà phát triển phi kỹ thuật sử dụng, chúng tôi nhận thấy rằng việc xác thực tính năng nhập liệu là cách tốt nhất để giúp người dùng của chúng tôi vận hành API của chúng tôi một cách chính xác. Càng sớm chúng tôi đưa ra một lỗi thì càng ít công việc mà khách hàng của chúng tôi sẽ phải làm.

Có phương pháp thanh lịch hơn để chỉ định điều kiện trước, sau điều kiện (và có thể là điều kiện bất biến) trong phương pháp của tôi không.

Một đồng nghiệp nói với tôi về một tính năng của ngôn ngữ lập trình Eiffel cho phép điều kiện trước/sau/bất biến được mô tả theo cách rất tự nhiên mà không cần lặp lại nhiều mã soạn sẵn. Có một add-on cho ngôn ngữ Java mà sẽ cho phép tôi sử dụng một số phép thuật này?

Trả lời

5

Làm thế nào về assert start < end. Hãy xem qua số documentation.

+1

Có, tôi chủ yếu là một nhà phát triển pthon. Đây là cú pháp chúng ta sẽ sử dụng trong Python, tuy nhiên tôi lưu ý rằng kiểu xác nhận này thường bị vô hiệu hóa khi chạy. Đã kết thúc

+0

'khẳng định bắt đầu

-2

Gói JUnit có các cấu trúc như khẳng định sẽ hỗ trợ trong việc kiểm tra điều kiện như vậy.

+0

Tôi đã có loại điều này trong bài kiểm tra đơn vị của tôi. –

+0

bạn không chỉ đơn thuần phải sử dụng nó trong các bài kiểm tra đơn vị, bạn sẽ có thể sử dụng nó trong thời gian chạy. – Milhous

+1

libit libs không nên được sử dụng trong mã sản xuất – vvursT

5

Aspect oriented programming có thể được sử dụng cho vấn đề như vậy. Các cuộc gọi phương thức có thể bị chặn để kiểm tra sự bất biến. Các phím tắt và lời khuyên được cấu hình theo cách khai báo. SpringGuice sử dụng AOP đơn giản.

Đây là example in Guice.

+1

Điều này thật thú vị - bạn có thể chỉ cho tôi một ví dụ trong Guice không? –

+1

Tôi không nghĩ rằng Guice/AOP là một gợi ý tốt cho việc kiểm tra điều kiện tiên quyết chung. Thật tuyệt vời đối với các kiểm tra chéo lớn (đặc biệt là các kiểm tra mà bạn có thể muốn thử nghiệm) như "là người đã yêu cầu người dùng đăng nhập", nhưng các kiểm tra cụ thể hơn như "là A ColinD

4

Bạn có thể thực hiện việc này bằng chú thích và lập trình hướng khía cạnh.

Tôi sẽ sử dụng IllegalArgumentException nếu kết hợp đối số không hợp pháp. Tôi sẽ sử dụng IllegalStateException trong trạng thái ngăn phương thức hoạt động.

Bạn có thể tạo phương thức trợ giúp cho ngoại lệ.

public static void check(boolean test, String message) { 
    if(!test) throw new IllegalArgumentException(message); 
} 

check(start < end, "Start must be before end."); 
+1

Những bài thơ bất thường cho sự đơn giản! –

12

chỉ dành cho lớp này. Bạn thường sử dụng nó với hàng nhập khẩu tĩnh, vì vậy ví dụ của bạn sẽ trông như thế:

checkArgument(start < end, "Start must be before end"); 

Nó giúp bạn dễ dàng để thêm thông tin vào tin nhắn là tốt, mà không phải trả chi phí String nối nếu kiểm tra đi.

checkArgument(start < end, "Start (%s) must be before end (%s)", start, end); 

Không giống như các báo cáo assert, chúng không thể bị vô hiệu hóa.

6

Kiểm tra dự án Cofoja cung cấp hợp đồng cho Java thông qua chú thích. Nó cung cấp Pre-/Postconditions và Invariants. Ngoài ra trái ngược với các triển khai Java khác, nó xử lý đúng các hợp đồng được định nghĩa trong các lớp/giao diện cha mẹ. Đánh giá hợp đồng có thể được bật/tắt khi chạy.

Dưới đây là một đoạn mã từ tutorial của họ:

import com.google.java.contract.Invariant; 
import com.google.java.contract.Requires; 

@Invariant("size() >= 0") 
interface Stack<T> { 
    public int size(); 

    @Requires("size() >= 1") 
    public T pop(); 

    public void push(T obj); 
} 
1

Đối với xác nhận đầu vào, bạn cũng có thể sử dụng Apache Commons Validator.

Lưu ý rằng xác thực đầu vào phải luôn được bật. Do đó, khái niệm rất khác với việc kiểm tra xác nhận (như, ví dụ, ở Eiffel), có thể tùy chọn bật/tắt - xem câu trả lời cho câu hỏi tràn ngăn xếp liên quan này When should I use Apache Commons' Validate.isTrue, and when should I just use the 'assert' keyword?

1

Nếu tôi thấy mình lặp lại cùng một nồi hơi- mã kiểm tra điều kiện tiên quyết mã trong một lớp, tôi refactor mã của tôi để giảm sự trùng lặp và để tăng trừu tượng bằng cách extractung mã lặp đi lặp lại vào một phương pháp mới (static private). Tôi sử dụng phương pháp Java-7 Objects.requireNonNull để kiểm tra null.

+0

Đây phải là lựa chọn tốt nhất nếu bạn đang xây dựng một SDK mà những người khác sẽ sử dụng. Không cần phụ thuộc bổ sung. :) – Carnell

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