2009-04-15 51 views
5

Tôi tham gia vào dự án này, nơi chúng tôi đang xây dựng trên một đoạn mã di sản tốt. Tôi có một tình huống cụ thể về một đối tượng đậu java lớn mà phải được chuyển qua dây. Vì vậy, suy nghĩ đầu tiên của tôi là để làm cho nó bất biến và serializable để làm các trick .at thời điểm này tôi đang phải đối mặt với một vài sự lựa chọn khó khăn: -Tạo các đối tượng bất biến từ javabean

  1. Lý tưởng nhất là tôi muốn có một số cách để tự động tạo ra một bất biến, serializable phiên bản của lớp này. Tôi không có phạm vi để cấu trúc lại hoặc thay đổi lớp này theo bất kỳ cách nào và tôi thực sự ghét phải dán sao chép lớp học với tên khác là ?

  2. Giả sử rằng tôi đã lên trên 1 tức là tôi thực sự đã chọn để sao chép mã của lớp JavaBean HUGE, tôi vẫn sẽ nằm trong tình trạng không lành mạnh vì phải viết một constructor với một số thông số 20-25 để làm cho lớp này không thay đổi được. cách nào tốt hơn để làm cho lớp học bất biến khác hơn là xây dựng tiêm?

Cảm ơn và Kính trọng,

+0

Đây là một câu hỏi rất hay. Trừ khi bạn có một lớp bất biến trùng lặp - có vẻ như không phải là một cách thực sự tốt để giải quyết vấn đề này. Tôi đã sử dụng phương pháp không thay đổi hiệu quả! – Fortyrunner

Trả lời

4

Để làm cho nó thực sự không thay đổi, bạn cần phải khởi tạo các thành viên vào thời điểm xây dựng.

Một cách (và tôi không nói 'đẹp quá!) Để làm điều này và tránh một danh sách tham số lớn trong hàm tạo là có loại có thể thay đổi có cùng thuộc tính. Đặt các thuộc tính trên một loại có thể thay đổi tại một thời điểm, thông qua "setters", sau đó vượt qua đối tượng có thể thay đổi được với hàm tạo của kiểu không thay đổi như là một đối số duy nhất. Đối tượng bất biến sau đó sao chép các thuộc tính từ nguồn có thể thay đổi thành thành viên riêng (final).

Bạn cũng có thể xem xét "bất biến hiệu quả". Đó là, mặc dù bất biến không được thi hành bởi hệ thống, bạn sử dụng các thực hành mã hóa tách biệt rõ ràng giai đoạn khởi tạo khỏi giai đoạn sử dụng. Sau khi tất cả, bất biến là không cần thiết cho serialization.

Bạn có thể tiến thêm một bước nữa, tạo trình bao bọc ẩn thực hiện cho giao diện không hiển thị các thuộc tính của việc triển khai. Trình bao bọc chỉ thực hiện các phương thức trong giao diện, bằng cách ủy thác cho việc thực hiện "thực". Các setters và getters từ việc thực hiện không có mặt trong trình bao bọc. Điều này sẽ ngăn chặn khách hàng chỉ đơn giản là down-casting từ giao diện đến lớp thực hiện và thao tác các thuộc tính.

+0

bạn có thể thêm một số ví dụ mã cho từng kịch bản của bạn, đang cố gắng hiểu và gặp khó khăn. – Rachel

1

20-25 thuộc tính không phải là rất lớn cho một lần tắt, đặc biệt nếu bạn đang sử dụng một trình soạn thảo một nửa phong nha.

Nếu bạn đã có một trường hợp có thể thay đổi khi xây dựng phiên bản bất biến, chỉ cần chuyển nó cho hàm tạo.

Nếu bạn muốn trở thành thực sự ác hacky, sử dụng java.beans để tạo ra một serialisable Map cho lớp có thể thay đổi hoặc lớp con thực hiện Externalizable. Hoặc bạn có thể sử dụng java.beans serialization XML (XML hơn là có thể được gửi qua serialization Java ...).

0

Bước 1: Tạo một lớp mới và cung cấp cho nó biến thể hiện cùng tên chính xác như biến thể hiện của 'đối tượng bean java lớn' của bạn. Lớp học mới đó không nên có người định cư (nhưng chỉ có getters) để làm cho nó không thay đổi được.

Bước 2: Sử dụng Apache Commons BeanUtils.copyProperties để sao chép tất cả các thuộc tính (ví dụ: biến chẳng hạn) từ 'đối tượng đậu java lớn' của bạn để đối tượng mới của mình.

0

Một vài ý tưởng:

setters bảo vệ và phương pháp nhà máy Bạn có thể xác đậu với các phương pháp setter được bảo vệ và trong cùng một gói, một lớp nhà máy mà sẽ đưa tất cả các thông số và gọi những setters. Đậu là không thay đổi bên ngoài gói đó. Để thực thi điều này, hãy chắc chắn đóng dấu bình của bạn để người dùng cuối không thể tạo các lớp mới trong cùng một gói.

Lưu ý: Bạn có thể sử dụng chú thích JavaDude Bean của tôi để làm cho việc tạo ra đơn giản hơn: http://code.google.com/p/javadude/wiki/Annotations

Ví dụ:

@Bean(writer=Access.PROTECTED, // all setXXX methods will be protected 
    properties={ 
     @Property(name="name"), 
     @Property(name="age", type=int.class) 
    }) 
public class Person extends PersonGen { 
} 

Tạo getter và một constructor trong eclipse

Eclipse có một số công cụ tốt đẹp để thực hiện việc này nhanh chóng:

  1. Tạo lớp bean
  2. Thêm các trường bạn muốn
  3. Kích chuột phải vào cửa sổ soạn thảo
  4. Chọn Nguồn-> Generate Getters and Setters
  5. Nhấn "Chọn getters" nút
  6. Press ok
  7. Nhấp chuột phải vào cửa sổ trình chỉnh sửa
  8. Chọn nguồn-> Tạo bộ tạo hình từ trường
  9. Pic k và đặt hàng các lĩnh vực mà bạn muốn trong constructor
  10. Nhấn ok

Bất Biến Decorator

ý tưởng khác là để xác định đậu của bạn với getter và setter (bạn có thể sử dụng các kỹ thuật nói trên nhưng bao gồm setters), sau đó bạn có thể tạo một lớp bao bọc cho nó chỉ có getters.

1

gì về một giao diện đơn giản chỉ đọc cotaining getters?

Nếu lớp bean là của riêng bạn, hãy để nó đơn giản triển khai giao diện và chỉ sử dụng giao diện sau khi tạo.

Nếu bạn không có quyền kiểm soát lớp bean, bạn cũng có thể tạo giao diện getter và thực hiện nó bằng cách tạo proxy cho giao diện getter với trình xử lý invokation ủy nhiệm tất cả các lời gọi phương thức tới bean.

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