2012-01-17 33 views
60

Tôi googled chủ đề, nhưng bên cạnh Wikipedia Tôi không tìm thấy bất kỳ tài liệu hoặc bài viết hữu ích nào khác.Một bất biến lớp trong java là gì?

Ai đó có thể giải thích cho tôi một cách đơn giản ý nghĩa của nó hoặc giới thiệu tôi với một số tài liệu dễ hiểu và dễ hiểu không?

+0

+1 cho câu hỏi vì trang Wikipedia có ví dụ thực sự tuyệt vời về điều tôi không biết bạn có thể làm - thậm chí còn có các ví dụ. Lời giải thích của họ tốt hơn tôi có thể làm cho bạn mặc dù; nó khá đơn giản. – iandisme

+0

https://www.stanford.edu/~pgbovine/programming-with-rep-invariants.htm –

+0

Nếu bạn quan tâm đến bất biến w.r.t. Java, có thể bạn sẽ quan tâm đến [hợp đồng cho Java] (http://google-opensource.blogspot.com/2011/02/contracts-for-java.html). –

Trả lời

64

Nó không có nghĩa là bất kỳ điều gì đặc biệt trong tham chiếu đến java.

Biến thể lớp đơn giản là thuộc tính chứa cho tất cả các phiên bản của một lớp, luôn luôn, bất kể mã nào khác.

Ví dụ,

class X { 
    final Y y = new Y(); 
} 

X có lớp bất biến rằng có một tài sản y và nó không bao giờ là null và nó có một giá trị kiểu Y.

class Counter { 
    private int x; 

    public int count() { return x++; } 
} 

thất bại trong việc duy trì hai bất biến quan trọng

  1. Đó count không bao giờ trả về một giá trị âm vì có thể underflow.
  2. Cuộc gọi đó đến count được tăng lên một cách đơn điệu.

Lớp được sửa đổi duy trì hai biến thể này.

class Counter { 
    private int x; 

    public synchronized int count() { 
    if (x == Integer.MAX_VALUE) { throw new IllegalStateException(); } 
    return x++; 
    } 
} 

nhưng thất bại trong việc bảo tồn bất biến mà các cuộc gọi đến count luôn thành công thường (vắng mặt TCB-vi phạm ) vì count có thể ném một ngoại lệ hoặc nó có thể ngăn chặn nếu một sợi bế tắc sở hữu màn hình của quầy.

Mỗi ngôn ngữ có các lớp giúp dễ dàng duy trì một số biến thể của lớp học nhưng không phải là các biến thể khác. Java cũng không phải là ngoại lệ:

  1. Các lớp Java luôn có hoặc không có các thuộc tính và phương pháp, vì vậy bất biến giao diện dễ bảo trì.
  2. Các lớp Java có thể bảo vệ các trường private của chúng, vì vậy các bất biến dựa vào dữ liệu cá nhân rất dễ bảo trì.
  3. Các lớp Java có thể là cuối cùng, do đó các bất biến dựa vào không có mã vi phạm một bất biến bằng cách tạo ra một lớp con độc hại có thể được duy trì.
  4. Java cho phép các giá trị null ẩn danh theo nhiều cách, do đó rất khó để duy trì các giá trị bất biến "có giá trị thực".
  5. Java có chủ đề có nghĩa là các lớp không đồng bộ hóa gặp khó khăn trong việc duy trì các bất biến dựa trên các hoạt động tuần tự trong một chuỗi diễn ra cùng nhau.
  6. Java có ngoại lệ giúp dễ dàng duy trì các biến thể như "trả về kết quả với thuộc tính p hoặc trả về không có kết quả" nhưng khó duy trì các bất biến như "luôn trả về kết quả".

† - Một ngoại hoặc TCB vi phạm là một sự kiện mà một nhà thiết kế hệ thống một cách lạc quan giả định sẽ không xảy ra.

Thông thường chúng ta chỉ tin tưởng rằng các phần cứng cơ bản hoạt động như quảng cáo khi nói về tính chất của ngôn ngữ cấp cao được xây dựng trên họ, và lập luận của chúng tôi mà bất biến giữ không đưa vào tài khoản các khả năng:

  • Một lập trình viên sử dụng các móc gỡ lỗi để thay đổi các biến cục bộ khi một chương trình chạy theo các cách mà mã không thể.
  • Các đồng nghiệp của bạn không sử dụng phản chiếu với setAccessible để sửa đổi private bảng tra cứu.
  • Vật lý thay đổi Loki khiến bộ xử lý của bạn so sánh sai hai số.

Đối với một số hệ thống TCB của chúng tôi có thể chỉ bao gồm các bộ phận của hệ thống, vì vậy chúng tôi có thể không thừa nhận rằng

  • Một quản trị viên hoặc daemon đặc quyền sẽ không giết quá trình JVM của chúng tôi,

nhưng chúng tôi có thể giả định rằng

  • Chúng tôi có thể kiểm tra tới hệ thống tệp giao dịch đáng tin cậy.

Hệ thống cấp cao hơn, TCB của bạn càng lớn, nhưng những thứ không đáng tin cậy hơn bạn có thể thoát khỏi TCB, khả năng giữ bất biến của bạn càng nhiều và hệ thống của bạn càng đáng tin cậy hơn về lâu dài.

+1

Là "số đó' không bao giờ trả về cùng một giá trị hai lần "thực sự được coi là một biến thể lớp ? – ruakh

+0

@ruakh, đó là một câu hỏi hay. Tôi không chắc lắm. Những thứ như hashCode ổn định (đối với mỗi cá thể i, i.hashCode() không thay đổi) thường được gọi là các biến thể lớp đòi hỏi phải có lý luận về các giá trị được trả về trước đó, vì vậy có vẻ hợp lý để nói rằng "cho mỗi cá thể i, i.count() không có trong (các kết quả trước đây của i.count()) "là một biến thể lớp. –

+0

@ruakh Chẳng phải đó là một định nghĩa thuần túy sao? Nếu tôi đề xuất một bất biến như vậy, tại sao không? Nó chắc chắn có thể là một đảm bảo thú vị và quan trọng (nói để tạo ID duy nhất). Cá nhân tôi cũng nghĩ một cái gì đó như "nếu chỉ có một chuỗi duy nhất truy cập lớp này, các thuộc tính sau đây sẽ giữ" là hữu ích, nhưng tôi không chắc chắn nếu nó có thể mở rộng định nghĩa theo cách mà nó chỉ phải giữ trong khi nhất định điều kiện là đúng. (Và xem xét sự phản chiếu về cơ bản thì không thể đảm bảo bất cứ điều gì thú vị nếu không!) – Voo

8

Đó là những sự kiện phải đúng về lớp thể hiện. Ví dụ nếu một lớp có một thuộc tính X và bất biến có thể là X phải lớn hơn thì 0. Theo kiến ​​thức của tôi, không có phương thức tích hợp để duy trì các bất biến, bạn phải tạo các thuộc tính riêng và đảm bảo các getters và setters của bạn thực thi thuộc tính bất biến.

Có sẵn các chú thích có thể kiểm tra các thuộc tính bằng cách sử dụng phản chiếu và kẻ chặn. http://docs.oracle.com/javaee/7/api/javax/validation/constraints/package-summary.html

7

Bất biến có nghĩa là cái gì đó phải tuân theo điều kiện của nó bất kể bất kỳ thay đổi nào hoặc bất kỳ ai sử dụng/biến đổi nó. Đó là để nói, một tài sản của một lớp luôn luôn đáp ứng hoặc đáp ứng một số điều kiện ngay cả sau khi trải qua biến đổi bằng cách sử dụng phương pháp công cộng. Vì vậy, khách hàng hoặc người dùng của lớp này được đảm bảo về lớp và thuộc tính của nó.

Ví dụ,

  1. điều kiện về tham số của hàm là, nó nên luôn luôn> 0 (lớn hơn zero) hoặc không nên null.
  2. Minimum_account_balance tài sản của một trạng thái tài khoản lớp học, nó không thể đi dưới 100. Vì vậy, tất cả các chức năng công cộng nên tôn trọng điều kiện này và đảm bảo bất biến lớp.
  3. phụ thuộc dựa trên quy tắc giữa các biến, nghĩa là, giá trị của một biến phụ thuộc vào biến khác, vì vậy nếu một biến thay đổi, sử dụng một số quy tắc sửa lỗi, quy tắc khác cũng phải thay đổi. Mối quan hệ này giữa 2 biến phải được bảo toàn. Nếu không, thì bất biến sẽ bị vi phạm.
Các vấn đề liên quan