Cấu trúc bean hỗ trợ JSF (các phương pháp hay nhất)


118

Tôi hy vọng rằng trong bài đăng này, tôi có thể lấy ý kiến ​​của mọi người về các phương pháp hay nhất cho giao diện giữa các trang JSF và các hạt sao lưu.

Một điều mà tôi không bao giờ có thể giải quyết được là cấu trúc của những hạt đậu nền của tôi. Hơn nữa, tôi chưa bao giờ tìm thấy một bài báo hay về chủ đề này.

Thuộc tính nào thuộc về đậu ủng hộ? Khi nào thì thích hợp để thêm nhiều thuộc tính hơn vào một bean nhất định thay vì tạo một bean mới và thêm các thuộc tính vào nó? Đối với các ứng dụng đơn giản, có hợp lý không khi chỉ có một hạt đậu hỗ trợ duy nhất cho toàn bộ trang, nếu xét đến sự phức tạp liên quan đến việc đưa một hạt đậu này vào một hạt đậu khác? Phần mềm hỗ trợ có nên chứa bất kỳ logic nghiệp vụ thực tế nào hay nó phải chứa dữ liệu nghiêm ngặt?

Vui lòng trả lời những câu hỏi này và bất kỳ câu hỏi nào khác có thể xuất hiện.


Đối với việc giảm sự ghép nối giữa trang JSF và đậu hỗ trợ, tôi không bao giờ cho phép trang JSF truy cập vào bất kỳ thuộc tính nào của thuộc tính đậu hỗ trợ. Ví dụ: tôi không bao giờ cho phép một cái gì đó như:

<h:outputText value="#{myBean.anObject.anObjectProperty}" />

Tôi luôn yêu cầu những thứ như:

<h:outputText value="#{myBean.theObjectProperty}" />

với giá trị đậu hỗ trợ là:

public String getTheObjectProperty()
{
    return anObject.getAnObjectProperty();
}

Ví dụ: khi tôi lặp qua một tập hợp, tôi sử dụng một lớp wrapper để tránh đi sâu vào một đối tượng trong bảng dữ liệu.

Nói chung, cách làm này cảm thấy "đúng" với tôi. Nó tránh bất kỳ khớp nối nào giữa chế độ xem và dữ liệu. Vui long sửa cho tôi nêu tôi sai.


Bạn có thể đưa ra một ví dụ cho: Ví dụ: Khi tôi lặp qua một tập hợp, tôi sử dụng một lớp wrapper để tránh đi sâu vào một đối tượng trong bảng dữ liệu.
Koray Tugay

2
Để biết thêm thông tin, hãy xem câu trả lời của
BalusC

Câu trả lời:


146

Bạn có thể muốn kiểm tra điều này: phân biệt giữa các loại bean được quản lý JSF khác nhau .

Dưới đây là mô tả về các loại đậu khác nhau, như được định nghĩa trong bài viết trên của Neil Griffin:

  • Model Managed-Bean : Phạm vi phiên thông thường. Loại hạt quản lý này tham gia vào mối quan tâm "Model" của mẫu thiết kế MVC. Khi bạn nhìn thấy từ "mô hình" - hãy nghĩ đến DỮ LIỆU. Một hạt mô hình JSF phải là một POJO tuân theo mẫu thiết kế JavaBean với các thuộc tính đóng gói getters / setters. Trường hợp sử dụng phổ biến nhất cho một bean mô hình là trở thành một thực thể cơ sở dữ liệu, hoặc đơn giản là đại diện cho một tập hợp các hàng từ tập kết quả của một truy vấn cơ sở dữ liệu.
  • Sao lưu Managed-Bean : Phạm vi yêu cầu thông thường. Loại hạt quản lý này tham gia vào mối quan tâm "Lượt xem" của mẫu thiết kế MVC. Mục đích của backing-bean là hỗ trợ logic giao diện người dùng và có mối quan hệ 1 :: 1 với dạng xem JSF hoặc dạng JSF trong thành phần Facelet. Mặc dù nó thường có các thuộc tính kiểu JavaBean với các getters / setters liên quan, nhưng đây là các thuộc tính của Chế độ xem - không phải của mô hình dữ liệu ứng dụng cơ bản. JSF backing-bean cũng có thể có các phương thức JSF actionListener và valueChangeListener.
  • Bộ điều khiển Managed-Bean : Phạm vi yêu cầu thông thường. Loại hạt quản lý này tham gia vào mối quan tâm "Bộ điều khiển" của mẫu thiết kế MVC. Mục đích của controller bean là thực thi một số loại logic nghiệp vụ và trả về kết quả điều hướng cho trình xử lý điều hướng JSF. Các hạt điều khiển JSF thường có các phương thức hành động JSF (và không phải phương thức actionListener).
  • Hỗ trợ Managed-Bean : Phiên thông thường hoặc phạm vi ứng dụng. Loại bean này "hỗ trợ" một hoặc nhiều lượt xem trong mối quan tâm "Lượt xem" của mẫu thiết kế MVC. Trường hợp sử dụng điển hình là cung cấp ArrayList cho JSF h: selectOneMenu danh sách thả xuống xuất hiện trong nhiều dạng xem JSF. Nếu dữ liệu trong danh sách thả xuống dành riêng cho người dùng, thì bean sẽ được giữ trong phạm vi phiên. Tuy nhiên, nếu dữ liệu áp dụng cho tất cả người dùng (chẳng hạn như danh sách thả xuống của các tỉnh), thì bean sẽ được giữ trong phạm vi ứng dụng, để nó có thể được lưu vào bộ nhớ cache cho tất cả người dùng.
  • Utility Managed-Bean : Phạm vi ứng dụng thông thường. Loại bean này cung cấp một số loại chức năng "tiện ích" cho một hoặc nhiều dạng xem JSF. Một ví dụ điển hình về điều này có thể là một bean FileUpload có thể được sử dụng lại trong nhiều ứng dụng web.

8
Đây là một bài viết tuyệt vời. Tôi chưa bao giờ nhìn thấy nó trước đây và chắc chắn rất vui vì bạn đã đăng nó. Ai bỏ phiếu xuống cái này là điên rồi. Nó không dành riêng cho iceFaces.
Zack Marrapese 23/06/09

2
Liên kết đến bài viết thực tế dường như đã biến mất.
Bill Rosmus

Một bản sao có thể được tìm thấy ở đây
ChrLipp

10
Tuy nhiên, tôi không thể hiểu được rằng câu trả lời này hiện đang ở mức 71 lượt ủng hộ. Bất cứ ai đã triển khai ứng dụng JSF của họ theo các quy tắc đó chắc chắn sau đó phải nói rằng JSF là một khung công tác vô cùng mờ nhạt và các ứng dụng JSF của họ là một mớ mã hỗn độn và tất cả đều đổ lỗi cho chính JSF thay vì cách tiếp cận tồi tệ của họ dựa trên những bài học sai lầm và cái gọi là "các phương pháp hay nhất" đã học.
BalusC

có logic nào trong số các bean này được thực thi trong trình duyệt thay vì trong máy chủ không?
eskalera

14

Câu hỏi tuyệt vời. Tôi đã phải chịu đựng rất nhiều với cùng một tình huống khó xử khi chuyển đến JSF. Nó thực sự phụ thuộc vào ứng dụng của bạn. Tôi đến từ thế giới Java EE, vì vậy tôi khuyên bạn nên có càng ít logic nghiệp vụ trong các hoạt động hỗ trợ của bạn càng tốt. Nếu logic hoàn toàn liên quan đến việc trình bày trang của bạn, thì bạn có thể có nó trong phần hỗ trợ.

Tôi tin rằng một trong (nhiều) điểm mạnh của JSF thực sự là bạn có thể hiển thị các đối tượng miền trực tiếp trên các bean được quản lý. Do đó, tôi thực sự khuyên bạn nên <:outputText value="#{myBean.anObject.anObjectProperty}" />áp dụng phương pháp này, nếu không, bạn sẽ tự làm quá nhiều việc cho mình trong việc phơi bày từng thuộc tính theo cách thủ công. Hơn nữa, sẽ hơi lộn xộn khi chèn hoặc cập nhật dữ liệu nếu bạn đóng gói tất cả các thuộc tính. Có những tình huống trong đó một đối tượng miền đơn lẻ có thể không đủ. Trong những trường hợp đó, tôi chuẩn bị một ValueObject trước khi hiển thị nó trên bean.

CHỈNH SỬA: Trên thực tế, nếu bạn định đóng gói mọi thuộc tính đối tượng mà bạn muốn hiển thị, thay vào đó, tôi khuyên bạn nên liên kết các thành phần giao diện người dùng với đậu hỗ trợ và sau đó đưa nội dung trực tiếp vào giá trị của thành phần.

Về cấu trúc bean, bước ngoặt đối với tôi là khi tôi buộc phải bỏ qua tất cả những thứ tôi biết về việc xây dựng ứng dụng web và bắt đầu coi nó như một ứng dụng GUI. JSF bắt chước Swing rất nhiều và do đó các phương pháp hay nhất để phát triển ứng dụng Swing hầu hết cũng sẽ áp dụng cho việc xây dựng các ứng dụng JSF.


Cảm ơn cho cái nhìn sâu sắc của bạn. Tôi chưa bao giờ thực sự làm được gì nhiều trong cách ứng dụng swing (ngoài các dự án học thuật cách đây rất lâu). Một số nguyên tắc tốt của ứng dụng swing là gì? Ngoài ra, tại sao nó lại lộn xộn khi chèn và cập nhật giá trị? có vẻ giống với tôi?
Zack Marrapese

5

Tôi nghĩ rằng điều quan trọng nhất với các đậu hậu của bạn là tách biệt logic của chúng. Nếu bạn có trang đầu cho hệ thống CMS, tôi sẽ thấy việc đặt mọi đoạn mã vào một bean là một cách thực hiện không tốt vì:

  1. Hạt đậu cuối cùng sẽ biến thành rất lớn
  2. Người khác sẽ dễ dàng tìm thấy những gì họ đang tìm nếu họ đang khắc phục sự cố trang đăng nhập, nếu sau đó họ có thể dễ dàng tìm kiếm tệp loginBean.java.
  3. Đôi khi bạn có các phần chức năng nhỏ khác biệt rõ ràng với phần còn lại của mã của bạn, bằng cách tách phần này ra, tôi sẽ tưởng tượng bạn sẽ tự mình phát triển lại / mở rộng mã này thành một thứ gì đó lớn hơn dễ dàng hơn, khi bạn đã có một hạt đậu đẹp với tốt kết cấu.
  4. Có 1 hạt đậu lớn, để làm tất cả, sẽ làm cho nó phụ thuộc nhiều bộ nhớ hơn nếu / khi bạn phải khai báo như thế này MyBigBean bigBean = new MyBigBean (); thay vì sử dụng chức năng mà bạn thực sự cần bằng cách thực hiện LoginBean loginBean = new LoginBean (); (Sửa cho tôi nếu tôi sai ở đây ???)
  5. Theo tôi, tách đậu của bạn cũng giống như tách các phương pháp của bạn. Bạn không muốn 1 phương thức lớn chạy hơn 100 dòng, mà nên tách nó ra với các phương thức mới xử lý tác vụ cụ thể của chúng.
  6. Hãy nhớ rằng, rất có thể ai đó không phải bạn cũng sẽ phải làm việc trên các dự án JSF của bạn.


Đối với việc ghép nối, tôi không thấy đó là một vấn đề rắc rối khi cho phép các trang JSF của bạn truy cập quá vào các thuộc tính trong các đối tượng trong backingbean của bạn. Đây là hỗ trợ được tích hợp trong JSF và thực sự chỉ giúp việc đọc và xây dựng imo dễ dàng hơn. Tất cả của bạn đã tách biệt logic MVC một cách nghiêm ngặt. Bằng cách làm này, bạn tiết kiệm cho mình hàng tấn đường với getters và setters trong backingbean của bạn. Ví dụ: tôi có một đối tượng thực sự rất lớn do các dịch vụ web cung cấp cho tôi, nơi tôi cần sử dụng một số thuộc tính trong bản trình bày của mình. Nếu tôi tạo getter / setter cho mỗi thuộc tính bean của tôi sẽ mở rộng với ít nhất 100 dòng biến và phương thức khác để nhận các propeties. Bằng cách sử dụng chức năng JSF tích hợp sẵn, thời gian và các dòng mã quý giá của tôi được tiết kiệm.

Chỉ 2 xu của tôi liên quan đến điều này ngay cả với câu hỏi đã được đánh dấu là đã trả lời.


1
tuy nhiên, nếu bạn có một đối tượng khổng lồ đang nằm trong bean của bạn và bạn có - giả sử - 15 hàm EL đào sâu vào đối tượng đó từ trang JSF, giờ đây bạn không chỉ bị ràng buộc với bean mà còn với đối tượng đó. Do đó sẽ rất khó để loại bỏ đối tượng đó mà không phá vỡ giao diện người dùng.
Zack Marrapese

1
Nhưng hạt đậu hỗ trợ của bạn sẽ không bị ràng buộc với đối tượng đó? Và giao diện người dùng của bạn gắn liền với đậu hỗ trợ? Khi bạn phải sửa đổi nó, bạn sẽ phải thay đổi tất cả các getters / setters của mình trong cả UI và bean.
Chris Dale

4

Tôi có thể không trả lời mọi câu hỏi của bạn, bởi vì ít có vẻ như khá phụ thuộc vào từng trường hợp.

  • Điều này là tốt để có một logic kinh doanh trong bean hỗ trợ của bạn. Nó phụ thuộc vào bạn đến từ đâu. Nếu bạn đang thực hành thiết kế theo hướng miền, bạn sẽ bị cám dỗ để đưa logic nghiệp vụ vào sao lưu bean hoặc cũng có thể là logic bền vững. Họ cho rằng tại sao vật thể lại câm như vậy. Đối tượng không chỉ mang trạng thái mà còn mang cả hành vi. Mặt khác, nếu bạn xem xét cách hoạt động của Java EE truyền thống, bạn có thể cảm thấy giống như có dữ liệu trong đậu hỗ trợ của bạn, nó cũng có thể là đậu thực thể của bạn và logic kinh doanh và bền bỉ khác trong một số session bean hoặc thứ gì đó. Điều đó cũng tốt.

  • Hoàn toàn tốt để có một hạt đậu hỗ trợ duy nhất cho toàn bộ trang. Tôi không thấy bất kỳ vấn đề với điều này một mình. Điều này có vẻ không ổn, nhưng điều đó tùy thuộc vào từng trường hợp.

  • Câu hỏi khác của bạn phụ thuộc nhiều hơn vào trường hợp bạn đang có trong tay. Tôi muốn truy cập miền được điều khiển ở đây, có thể thích hợp để thêm các thuộc tính vào hiện có hoặc tạo một bean mới cho điều đó. Cái nào phù hợp hơn. Tôi không nghĩ rằng có bất kỳ viên đạn bạc nào cho việc này.

  • Thuộc tính nào thuộc về đậu ủng hộ nào. Vâng, nó không phụ thuộc vào đối tượng miền? Hoặc có thể là câu hỏi không rõ ràng.

Hơn nữa, trong ví dụ mã đã cho của bạn, tôi không thấy bất kỳ lợi ích lớn nào.


nếu - ví dụ - chúng tôi thay đổi từ việc sử dụng POJO tự ủ được tạo bằng các truy vấn JDBC sang các thực thể Hibernate có tên trường hơi khác nhau, chúng tôi sẽ không chỉ thay đổi hạt sao lưu. Chúng tôi cũng sẽ phải thay đổi trang JSF. Không phải như vậy với ví dụ mã của tôi. Chỉ cần thay đổi hạt đậu.
Zack Marrapese

Trong trường hợp đó, bạn có thể tạo ra các thực thể hỗ trợ của mình. thì bạn chỉ cần thay đổi các trang JSF. Hoặc nó phụ thuộc vào lý do tại sao bạn sẽ thay đổi tên của các thuộc tính? điều đó sẽ chỉ có ý nghĩa khi bạn đổi tên trường để khớp với tên cột cơ sở dữ liệu của bạn. Nhưng đó hoàn toàn là một trường hợp khác.
Adeel Ansari

4

Tôi sẽ không cần thiết chỉ giữ một hạt đậu hỗ trợ trên mỗi trang. Nó phụ thuộc vào chức năng nhưng hầu hết thời gian tôi có một bean trên mỗi trang vì hầu hết một trang xử lý một chức năng. Ví dụ trên một trang tôi có liên kết đăng ký (tôi sẽ liên kết với RegisterBean) và liên kết giỏ hàng (ShoopingBasketBean).

Tôi sử dụng <: outputText value = "# {myBean.anObject.anObjectProperty}" /> vì tôi thường sao lưu bean dưới dạng action bean chứa đối tượng dữ liệu. Tôi không muốn viết một trình bao bọc trong bean sao lưu của mình để truy cập các thuộc tính của các đối tượng dữ liệu của tôi.


0

Tôi thích kiểm tra mã doanh nghiệp mà không có View, vì vậy tôi coi BackingBeans là giao diện từ View đến mã Model. Tôi không bao giờ đặt bất kỳ quy tắc hoặc quy trình nào trong BackingBean. Mã đó đi vào Dịch vụ hoặc Người trợ giúp, cho phép sử dụng lại.

Nếu bạn sử dụng trình xác thực, hãy đưa chúng ra khỏi BackingBean và tham chiếu chúng từ phương pháp xác thực của bạn.

Nếu bạn truy cập DAO để điền các Lựa chọn, Bộ đàm, Hộp kiểm, hãy thực hiện việc đó luôn không có Trình duyệt phụ.

Tin tôi đi!. Bạn có thể đưa một JavaBean vào một BackingBean, nhưng hãy thử đưa một BackingBean vào một cái khác. Bạn sẽ sớm nhận được mã bảo trì và hiểu mã.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.