2010-07-22 34 views
5

Tôi muốn triển khai mẫu MVC trong một tình huống khó khăn. Khó khăn là các Mô hình của tôi (các thực thể tạo ra các sự kiện) tồn tại lâu dài, trong khi các khung nhìn (người nhận các sự kiện) là ngắn ngủi. Vấn đề của tôi là thông qua kết nối giữa hai mô hình, các Mô hình tồn tại lâu dài giữ cho Chế độ xem sống ngắn của tôi tồn tại, tức là chúng không thể được thu gom rác.Cách triển khai mẫu MVC mà không giữ Chế độ xem còn sống

[MODEL] ------- <weak> -------> [VIEW] 
    | 
<strong> 
    | 
    v 
[CONTROLLER] 

Một cách để làm việc xung quanh này là để lưu trữ các kết nối trong mô hình trong một WeakHashMap < View, Controller >. Điều này về cơ bản cho phép xem được rác thu thập, và khi điều đó xảy ra, WeakHashMap sẽ ném điều khiển tương ứng ra, quá. Tức là, nếu Controller không giữ một tham chiếu (mạnh) vào View - nó thường làm. Trong trường hợp này, Chế độ xem được giữ nguyên thông qua các tham chiếu mạnh mẽ cho đến khi Mô hình nằm ngoài phạm vi.

[MODEL] ------- <weak> -------> [VIEW] 
    |        ^
<strong>       | 
    |        | 
    v        | 
[CONTROLLER] ----------- <strong> ---/ 

Có cách nào khác để đính kèm người nghe vào mô hình của tôi không giữ cho chế độ xem của tôi (và bộ điều khiển) còn sống không?

CẬP NHẬT: Để trả lời câu hỏi của mdma: Bộ điều khiển giữ tham chiếu đến Chế độ xem vì nó cần cập nhật Chế độ xem. Tham chiếu này có thể yếu, nhưng tôi muốn có các bộ điều khiển là các lớp bên trong vô danh của lớp View, trong trường hợp đó cá thể Controller có một tham chiếu mạnh tiềm ẩn đối với cá thể View.

+0

Tại sao bộ điều khiển có một tham chiếu mạnh để xem? – mdma

Trả lời

0

Here bạn đã có triển khai tuyệt vời mẫu MVC. Có lẽ có một giải pháp cho vấn đề của bạn.

+0

Có lẽ tôi đang thiếu một cái gì đó, nhưng điều này có vẻ giống như một * demo * về cách sử dụng MVC của Swing? Ngoài ra, việc thực hiện mô hình MVC của Swing không phải là một giải pháp cho vấn đề của tôi, vì nó giữ sự tham chiếu mạnh mẽ giữa các mô hình và người nghe. –

3

Có một số cách để thực hiện MVC.

  • Viết mô hình sau đó để chế độ xem của bạn lắng nghe những thay đổi đối với mô hình. Khung nhìn cho bộ điều khiển biết khi có điều gì xảy ra.
  • Viết chế độ xem sau đó để mô hình của bạn lắng nghe những thay đổi đối với chế độ xem. Khung nhìn cho bộ điều khiển biết khi có điều gì xảy ra.
  • Viết chế độ xem. Hãy để mô hình của bạn lắng nghe những thay đổi đối với chế độ xem. Hãy để bộ điều khiển của bạn lắng nghe chế độ xem, điều này sẽ nâng cao các sự kiện khác nhau nếu có điều gì xảy ra.

Cái cuối cùng cho khớp nối yếu nhất giữa các chế độ xem, bộ điều khiển và mô hình. Đó là một tên khốn để kiểm tra đơn vị bộ điều khiển vì bạn sẽ phải xử lý sự kiện. Bạn thậm chí không thể chế giễu chúng bằng cách sử dụng các khuôn khổ mocking, bởi vì bạn cần phải nâng cao sự kiện toàn bộ thời gian. Nó hoạt động, mặc dù.

Tôi thích MVCP:

  • Cho phép điều khiển của bạn để quấn Model trong một Presenter. Bộ điều khiển sẽ lắng nghe các Chế độ xem được đính kèm và đưa cho họ một Người trình bày mới mỗi lần. Trường đại biểu Presenter thay đổi thành Model, và cũng ủy nhiệm các lệnh tới Controller. Cả Bộ điều khiển lẫn Mô hình đều không được tham chiếu đến Người trình bày. Khi khung nhìn chết đi, người trình bày đi theo nó.

Điều tuyệt vời về diễn giả là bạn có thể đóng gói chỉ cần nội dung mà chế độ xem cần. Giao diện cho người trình bày gần như hoàn toàn được điều khiển bởi khung nhìn. Bạn thậm chí có thể thực hiện các công cụ như tạo trình diễn khác nhau cho các chế độ xem khác nhau và điền tất cả thông qua một phương thức giao diện như sau: Presenter.PopulateWith(model, controller).Điều này mang lại cho bạn một nơi tuyệt vời để làm tất cả các logic trình bày (ngày thành chuỗi, tên đăng nhập mà không có ., vv) mà không gây ô nhiễm Mô hình đáng yêu của bạn. Và bạn nhận được tài liệu tham khảo yếu của bạn miễn phí!

Điều này rất giống với mẫu MVVM hiện được sử dụng trong WPF thành ngữ. Hoạt động tốt trong Java, cũng với Web. Hy vọng những điều này cung cấp cho bạn một số ý tưởng, anyway.

0

Tôi nghĩ bạn đang đi đúng hướng. Tôi thấy hai giải pháp khả thi để nhận được quan điểm khai hoang đúng:

  1. Thiết kế nhìn đời vào hệ thống, do đó xem descruction được thực hiện một cách rõ ràng, và sau đó tất cả các bên quan tâm có thể phát hành tài liệu tham khảo của họ để xem.

  2. Xóa tham chiếu mạnh trong bộ điều khiển. Bộ điều khiển có thể sử dụng một WeakReference để giữ cho khung nhìn, mà phải được kiểm tra với mỗi lần truy cập, hoặc thay vào đó, vượt qua trình điều khiển một khung nhìn View thực hiện giao diện thực của bạn, giữ nó qua tham chiếu yếu. Nếu tham chiếu đã được khai hoang (là null), lời gọi phương thức là một no-op.

0

... nhưng tôi muốn có Controllers được ẩn danh nội các lớp học của lớp View, trong trường hợp các trường hợp điều khiển có một tài liệu tham khảo mạnh mẽ tiềm ẩn đến Xem ví dụ.

Điều đó sẽ không hoạt động ... dựa trên biểu đồ trong câu hỏi.

Tham chiếu thường xuyên trong Model tới Controller và một khác trong Controller vào Chế độ xem sẽ đủ để có nghĩa là có thể truy cập được View. Do đó, tham chiếu yếu trong số Controller đến View sẽ không bị hỏng ... cho đến khi bản thân số Model trở thành đủ điều kiện để thu thập rác.

Vì một lớp bên trong vô danh không bao giờ có thể tĩnh, bạn không có lựa chọn hợp lý (*) nhưng để đặt Controller thành lớp lồng nhau tĩnh hoặc lớp không lồng nhau.

Phương án thay thế khác là làm cho liên kết từ Model đến Controller trở thành tham chiếu yếu.

(* Thực tế có một thủ thuật có thể có thể hoạt động ... mặc dù nó gần như quá khủng khiếp để đề cập đến. Bạn có thể tìm ra tên của thuộc tính ẩn chứa liên kết đối tượng Controller đối tượng cha của nó, và có thể dùng phản ánh để tìm ra Field và sau đó sử dụng để thiết lập các thuộc tính để null.)


EDIT

Đây là những gì J LS nói về các lớp ẩn danh - JLS 15.9.1

Lớp ẩn danh không bao giờ trừu tượng (§8.1.1.1). Một lớp vô danh luôn luôn là một lớp bên trong (§8.1.3); không bao giờ là tĩnh (§8.1.1, §8.5.2). Một lớp vô danh luôn luôn là hoàn toàn cuối cùng (§8.1.1.2).

Tôi đang gặp khó khăn trong hòa này với bình luận của OP ...

+0

Thực ra, bạn có thể có một lớp bên trong ẩn danh tĩnh nếu bạn định nghĩa nó trong một ngữ cảnh tĩnh (tức là trong một phương thức tĩnh hoặc là một trường tĩnh của một lớp). Đây là giải pháp mà chúng tôi đang sử dụng ngay bây giờ để đảm bảo rằng người nghe không tham chiếu chế độ xem - nhưng nó dẫn đến mã khủng khiếp và rất dễ xảy ra lỗi. Đó là lý do tại sao tôi đang tìm kiếm một giải pháp tốt hơn. –

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