2010-07-15 31 views
10

Giả sử tôi có loại được gọi là Superstar. Bây giờ tôi muốn có một phương thức thực hiện một số công việc và chỉnh sửa một số thuộc tính của đối tượng Superstar.Thực hành tốt để chỉnh sửa đối tượng "theo tham chiếu"?

Dưới đây là hai cách để tôi có thể triển khai điều này. Cách 1 sẽ là như sau:

private Superstar editSuperstar(Superstar superstar){ 
    .... 
    superstar.setEdited(true); 
    return superstar; 
} 
... 
superstar = editSuperstar(superstar); 

Và cách 2 sẽ là:

private void editSuperstar(Superstar superstar){ 
    .... 
    superstar.setEdited(true); 
} 
... 
editSuperstar(superstar); 

Mà một trong hai cách có thể được coi là "thực hành tốt nhất"? Người đầu tiên, hoặc giả thứ hai "bằng cách tham khảo" một?

Trả lời

6

Trong trường hợp của bạn, biểu mẫu thứ hai là thích hợp hơn, vì bạn trực tiếp thay đổi một trong các thuộc tính siêu sao (edited). Tuy nhiên, nếu bạn có một phương thức sử dụng đối tượng siêu sao và trả về phiên bản cập nhật của nó (không thay đổi phiên bản đầu tiên) thì biểu mẫu đầu tiên sẽ có lợi cho tôi.

Cuối cùng, vì cả hai ví dụ này chỉ sử dụng đối tượng Superstar, nên là các phương thức thành viên của lớp Superstar.

+0

điều này là muộn, nhưng phương pháp thứ hai không trực tiếp chỉnh sửa 'superstar' bên ngoài. Nó tạo ra một phiên bản địa hoá của 'superstar' và không bao giờ thay đổi bất kỳ thuộc tính nào của đối tượng bên ngoài. – Jon

+1

@Jon Tại sao bạn nói taht? Không có gì ở đây ủng hộ yêu cầu đó, phải không? – Riduidel

4

Sử dụng cách 2 trừ khi bạn đang tạo lớp "người xây dựng" nơi bạn định chuỗi invocations. Ví dụ:

MyClass c = (new MyClassBuilder()).setX(blah).setY(blah).build(); 
+0

Ví dụ của bạn là khá khác nhau, nó thay vì minh họa ý tưởng trả về "này" - thay vì "void" - từ một phương thức setter để cho phép chuỗi invalations setter ... – pgras

4

Biểu mẫu đầu tiên là lừa đảo. Nó cho ấn tượng rằng một đối tượng đang được truyền vào, được sao chép và bản sao sau đó được thay đổi và trả về.

"Thực tiễn tốt nhất" sẽ là sử dụng biểu mẫu đầu tiên, nhưng để thực sự làm những gì được ngụ ý (áp dụng thay đổi cho bản sao, sau đó được trả lại). Các đối tượng không thay đổi thường nên được ưu tiên hơn các đối tượng có thể thay đổi được trừ khi chúng là những thứ chunky lớn đắt tiền để sao chép, trong trường hợp này, bạn nên ưu tiên biểu mẫu thứ hai.

2

Vấn đề bạn có ở đây với phương pháp đầu tiên là nếu bạn sử dụng nó như thế:

Superstar edited = editSuperstar(originalSuperstar); 

này cũng sẽ sửa đổi originalSuperstar đó là, theo ý kiến ​​của tôi, phản trực giác ...

Như vậy thích điều thứ hai nếu bạn sửa đổi đối tượng được truyền hoặc đối tượng đầu tiên nếu bạn trả lại một bản sao mới của đối tượng.

Ví dụ đặc biệt này, bạn có thể chỉ cần thêm một phương pháp chỉnh sửa đến lớp Superstar ...

1

Các hình thức đầu tiên sẽ là đáng ngạc nhiên cho các khách hàng API nếu bạn quay lại cùng một ví dụ chỉ có thay đổi một số lĩnh vực. Người ta sẽ mong đợi để có được một bản sao sửa đổi trở lại mà không cần thay đổi bản gốc.

Vì vậy, hãy sử dụng biểu mẫu thứ hai nếu bạn không trả lại bản sao và sử dụng bản sao đầu tiên nếu bạn làm (và suy nghĩ về việc làm Superstar không thay đổi trong trường hợp đó).

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