2010-08-01 30 views
6

Một trong những lời khuyên được đưa ra bởi Joshua Bloch là, lớp học nên được thiết kế như là bất biến.Thiết kế lớp học không thể thay đổi

Tôi có lớp sau

public class Dividend { 
    public Dividend setDate(SimpleDate date) { 
     Dividend dividend = new Dividend(this.getStock(), this.getAmount(), date); 
     return dividend; 
    } 
.....// More to go. 

Đối setDate phương pháp, đối tượng này sẽ không được sửa đổi.

Thay vào đó, bản sao của này với trường ngày của nó đang được sửa đổi sẽ được trả về.

Tuy nhiên, bằng cách đánh giá tên phương thức, người dùng sẽ biết đối tượng này sẽ vẫn không thay đổi được như thế nào?

Có quy ước đặt tên tốt hơn bên cạnh setDate không?

+2

Lớp 'Divident' có phương thức 'setComment' để sửa đổi đối tượng không? Sau đó, nó không phải là bất biến. – Jesper

+0

Nếu phương thức của bạn là riêng tư thì chỉ có lớp này là không thay đổi. – Gopi

+5

Thay vì 'setDate', bạn có thể thử những thứ như' onDate'/'withDate' /' forDate', v.v. – polygenelubricants

Trả lời

10

Nếu bạn có người định cư, lớp học của bạn sẽ trông có thể thay đổi và người dùng có thể sẽ sử dụng sai cách. Họ có thể sẽ gọi nó như thế này:

dividend.setDate(myDate); 

Và sau đó ngạc nhiên vì sao ngày của dividend không thay đổi. Họ nên đã sử dụng nó như thế này:

newDividend = dividend.setDate(myDate); 

Để thực hiện các API trực quan hơn, nó sẽ là tốt hơn để đổi tên các phương pháp setDate một cái gì đó giống như copyWith:

newDividend = dividend.copyWith(myDate); 

Hoặc, nếu bạn có nhiều lĩnh vực và quá tải sẽ gây nhầm lẫn, bạn có thể gọi cho họ copyWithDatecopyWithComment.

Cũng có thể có các tên khác như được nêu trong các câu trả lời khác: derive (và deriveWithDate) hoặc đơn giản là withDate.

1

Bạn nên triển khai lớp của mình giống như lớp String, không có bộ định vị trên đó. Nó sẽ được hiểu rằng nó là bất biến nếu không ai có thể đặt bất cứ điều gì trên đó. (có thể bạn có thể muốn đặt người đặt ở chế độ riêng tư hoặc bạn chỉ muốn đặt các biến trực tiếp từ bên trong lớp Cổ tức của mình)

3

Font, ví dụ, (a) derive phương pháp tạo trường hợp phông chữ mới từ hiện tại.

+0

đồng ý - Tôi thấy việc đặt tên có nguồn gốc khá trực quan. – mikera

-1

Chức năng này chỉ là trình bao bọc cho hàm tạo. Quá tải hàm khởi tạo để chấp nhận một đối tượng cổ tức đầy đủ để sao chép. Nếu không, bạn có thể đổi tên chức năng này getDividend (nó chắc chắn không phải là một setter).

2

Nhiều thư viện Java tôi đã xem đang bắt đầu sử dụng with làm tiền tố cho 'bản sao của đối tượng này, với các thay đổi sau'.

Ví dụ:

public Dividend withDate() { 
    .... 

mà lends tự để

Dividend newDividend = oldDividend.withDate(...).withAmount(...).withComment(...); 

JSR-310, ví dụ, sau mô hình này (cũng như sử dụng plusXxx()minusXxx() cho 'điều chỉnh' đối tượng mà phải mất một đồng bằng thay vì giá trị tuyệt đối, chẳng hạn).

-1

Vì số Dividend đang được trả lại, người dùng có thể sẽ biết đó là một phiên bản Dividend mới. Thậm chí sau đó, bạn có thể xem xét lại tên.

+0

Tôi cho rằng đó là giao diện thông thạo và trả về 'điều này' nếu tôi không biết nó là bất biến. – ILMTitan

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