Nội dung của chương này khảo sát, phân tích, đánh giá 3 mô hình hỗ trợphối hợp widget tiêu biểu trong các hướng tiếp cận hiện nay: OpenAjax widget[38],mô hình phối hợp của Jin Yu [14], IBM iWidget [26] . Qua đó, rút ra đặc điểm, thuận lợi cũng như hạn chế từ các phương pháp biểu diễn này và đề xuất một số biểu diễn bổ sung cần thiết, giúp cho cơ chế phối hợp linh động và dễ mở rộng hơn.
18 trang |
Chia sẻ: vietpd | Lượt xem: 1662 | Lượt tải: 0
Bạn đang xem nội dung tài liệu Khảo sát và phân tích các mô hình phối hợp widget, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
30
Chương 3
Khảo sát và phân tích các mô hình phối hợp widget
Tóm tắt
Nội dung của chương này khảo sát, phân tích, đánh giá 3 mô hình hỗ trợ
phối hợp widget tiêu biểu trong các hướng tiếp cận hiện nay: OpenAjax widget
[38],mô hình phối hợp của Jin Yu [14], IBM iWidget [26]. Qua đó, rút ra đặc điểm,
thuận lợi cũng như hạn chế từ các phương pháp biểu diễn này và đề xuất một số biểu
diễn bổ sung cần thiết, giúp cho cơ chế phối hợp linh động và dễ mở rộng hơn.
3.1 Khảo sát khả năng phối hợp của widget trong các widget
Platform
Tên Platform
Khả năng hỗ trợ Mashup
Secure
Mashup
Mashup
Editor
Hoạt động
độc lập
Phối hợp
dựa trên
lập trình
dựa trên
biểu diễn
OpenAjax x x x
Google Gadget x
IBM iWidget x x x x
Netvibes x
Kludgets x
ClearSpring x
MuseStorm x
Opera x
Microsoft Gadget x
YourMinis x
Springwidget x
Yahoo widget x
widgetBox x
W3C x
Bảng 3-1: Khả năng phối hợp widget trong các widget Platform
31
Bảng 3-1 tổng hợp thông tin về khả năng phối hợp widget trong các widget
platform. Kết quả khảo sát cho thấy chỉ có 2 Platform chính OpenAjax widget và
IBM iWidget cung cấp các widget có khả năng phối hợp hoạt động. Việc phối hợp
này có thể thực hiện theo 2 dạng sau:
Mã lập trình (Imperative)
Sự phối hợp thực hiện dựa trên việc lập trình do lập trình viên tự thực hiện và
không có biểu diễn trừu tượng. Việc phối hợp này chỉ phù hợp với nhà phát triển,
đồng thời khả năng và mức độ phối hợp phụ thuộc vào sự am hiểu công nghệ phát
triển widget. Việc thay thế widget với tính năng tương tự khó khăn, ngoài ra, Mashup
sau khi tổng hợp khó phát triển và mở rộng. Chuẩn widget tiêu biểu dạng này là
OpenAjax Widget [38].
Biểu diễn khai báo (Declarative)
Mối quan hệ phối hợp được biểu diễn dựa trên đặc tả trừu tượng dạng khai báo
XML. Đặc tả thường đi kèm với Engine có nhiệm vụ phân tích và vận hành sự phối
hợp.
Ưu điểm của hướng tiếp cận này là nếu đặc tả đầy đủ ngữ nghĩa kết hợp với
Engine đủ mạnh, cùng với các thư viện đã có sẵn, ta có thể phát sinh và triển khai
được ứng dụng chạy trên nhiều nền tảng (Web, Windows, Mobile…) và công nghệ
khác nhau (HTML – CSS – Javascript, Silverlight, Flash, JavaFX …).
Ngoài ra, do tính trừu tượng cao và đơn giản, đặc tả dạng này tương đối phù hợp
với nhiều đối tượng người dùng (lập trình viên sử dụng widget hay người dùng cuối).
Khả năng thay thế widget với chức năng tương tự thực hiện dễ dàng vì tất cả đều thực
hiện thông qua biểu diễn trừu tượng.
Một số đề xuất tiêu biểu về mô hình phối hợp dựa trên khai báo: Jin Yu [14], IBM
iWidget [26]. Phần tiếp theo sẽ trình bày về các phương pháp biểu diễn khả năng phối
hợp widget trong các chuẩn cũng như trong các đề xuất hiện nay.
32
3.2 OpenAjax widget
3.2.1 Giới thiệu
OpenAjax widget là một phần trong đặc tả OpenAjax Metadata do liên minh
OpenAjax (OpenAjax Alliance) phát triển. OpenAjax Alliance là một tổ chức với
thành viên bao gồm các công ty phần mềm (BEA, Borland, Google, IBM, Mozilla,
Novel, Oracle, Yahoo, Zend…), cộng đồng nguồn mở (Dojo, Eclipse, Red Hat…),
nhà phát triển Web nhằm thống nhất và thông qua các chuẩn công nghệ Web dựa trên
Ajax sao cho các công nghệ này mang tính mở và tương thích về mặt hoạt động
(interoperability).
Đặc tả OpenAjax Metadata phục vụ 2 mục tiêu chính: xây dựng môi trường phát
triển ứng dụng Ajax (Ajax-IDE), phát triển ứng dụng Mashup (tập trung vào Mashup
an toàn – secure Mashup). Liên quan đến khía cạnh tổng hợp Mashup, đặc tả chú
trọng giải quyết 2 thách thức lớn trong quá trình tích hợp Mashup bao gồm:
Secure Mashup
Đặc tả cung cấp các biểu diễn cho phép cô lập widget thành các Sandbox (sử
dụng iFrame với các sub-domain khác nhau), việc liên lạc giữa các widget lúc này sẽ
do Managed Message Bus quản lý.
Widget Interoperability
Đặc tả bao gồm OpenAjax widget cho phép mô tả:
User Interface widget (menu, tree, grid…) trong các thư viện Ajax, giúp các
widget thuộc về các thư viện Ajax khác nhau có thể tương tác được với nhau.
Mashable Component (Mashble widget): là các UI widget nhưng có thêm các
đặc tả bổ sung về tính năng phối hợp tạo ứng dụng Mashup.
33
3.2.2 Sự phối hợp widget
Có 2 cách phối hợp:
Share Property: lưu trữ thuộc tính chung có thể chia sẻ giữa nhiều widget.
Message Topic: Mashable widget có khả năng khai báo các sự kiện mà nó hỗ
trợ thông qua Message Topic (khai báo với thẻ ). Mỗi Message Topic
tương ứng với một sự kiện, các widget khác có thể đăng ký (Subscribe) hàm
xử lý sự kiện (event handler) tự động gọi thực hiện khi Message Topic phát ra
từ widget nguồn. Mashable widget sử dụng các API do OpenAjax Hub 2.0 (đã
được công nhận là chuẩn Ajax hỗ trợ tạo Mashup bảo mật) cung cấp để thực
hiện liên lạc.
OpenAjax Hub có 2 cơ chế liên lạc tương ứng với 2 loại Hub:
Unmanaged Hub:
Unmanaged Hub cho phép các widget trong cùng Frame liên lạc với nhau thông
qua các phương thức publish(), subscribe(), mà không cung cấp cơ chế cô lập widget
hoặc khả năng bảo mật khác. Ưu điểm của Unmanaged Hub là đạt được hiệu năng
(performance) tốt hơn so với dạng còn lại (Managed Hub).
Ví dụ: cách sử dụng Unmanaged Hub: Giả sử widget nguồn khai báo message
topic có tên là “org.example.location.set”, widget này sẽ phát ra sự kiện thông qua
phương thức OpenAjax.hub.publish kèm theo tham số sự kiện chứa trong biến
location_data như sau:
// Source widget:
var location_data = {lat: current_latitude,long:current_longitude};
OpenAjax.hub.publish(“org.example.location.set”, location_data);
Các widget khác sẽ đăng ký xử lý sự kiện cũng thông qua message topic cùng tên sử
dụng phương thức OpenAjax.hub.subscribe kèm theo hàm callback
onDataCallback. Khi sự kiện phát ra, hàm onDataCallback được kích hoạt và nhận
dữ liệu từ đối số data để thực hiện các xử lý tương ứng như sau:
//Destination widget:
function onDataCallback(topic, data) {
// Do something in response to the event and its data
}
OpenAjax.hub.subscribe(“org.example.location.set”,onDataCallback);
34
Managed Hub:
Managed Hub là tính năng nổi bật nhất của Hub 2.0, cho phép ứng dụng Mashup
cô lập widget không đáng tin cậy thành các sandbox. Managed Hub hỗ trợ các khả
năng sau:
Widget sau khi đã bị cô lập (sandbox) không thể truy cập mã kịch bản script
hoặc nội dung DOM bên trong Mashup hay widget khác. Widget chỉ có thể
liên lạc với Mashup hay widget khác thông qua các API publish, subscribe do
Hub cung cấp.
Mashup có thể định nghĩa các luật kiểm soát widget mà nó đang quản lý chỉ có
thể khai báo hoặc đăng ký trên các dạng Message Topic nào.
Ngăn chặn widget không đáng tin cậy tự thay đổi nội dung được nạp ban đầu
của nó nhằm chèn vào một số đoạn mã độc khai thác thông tin trên Mashup
hay widget khác.
Ngăn chặn widget giám sát các Message Topic mà nó không được phép truy
cập, hoặc giả mạo Message Topic (nhờ vào cơ chế định danh widget do Hub
cung cấp).
Managed Hub cũng sử dụng cơ chế Publish/Subscribe khi thực hiện liên lạc
nhưng thông qua đối tượng hubClient. Quá trình sử dụng cũng tương tự Unmanaged
Hub.
Ví dụ: Lấy ví dụ tương tự Unmanaged Hub, widget phát sự kiện và widget xử
lý sự kiện được cài đặt như sau:
// Source widget:đăng ký sự kiện
var location_data = { lat:current_latitude, long:current_longitude
};
hubClient.publish(“org.example.location.set”,location);
// Destination widget:xử lý sự kiện
function onCompleteCallback(item, success, errCode) {
// Xử lý khi nhận được thông báo kết quả đăng ký
}
function onDataCallback (topic, data) {
// Xử lý khi nhận được sự kiện và dữ liệu đi kèm
}
var subID = hubClient.subscribe(“org.example.location.set”,
onDataCallback, null, onCompleteCallback);
35
3.2.3 Nhận xét
OpenAjax cung cấp đặc tả khá toàn diện cho phép widget được phát triển từ các
thư viện Javascript khác nhau có thể phối hợp hoạt động với nhau. Giải quyết vấn đề
về khả năng tương tác (interoperability) trong các thư viện Ajax hiện nay.
Đặc tả đảm bảo sự an toàn trong liên lạc giữa các widget thông qua chuẩn Open
Ajax Hub 2.0, khả năng tạo Mashup bảo mật dễ dàng.
Tuy nhiên hạn chế hiện nay là chưa cung cấp đặc tả biểu diễn sự phối hợp mà chủ
yếu thực hiện khi lập trình trong giai đoạn xây dựng widget. Điều này dẫn đến việc
chưa thể xây dựng Engine thực hiện quá trình phối hợp tự động. Các widget sẽ bị kết
buộc khá chặt về dữ liệu truyền trong khi cài đặt. Việc chỉnh sửa, mở rộng ứng dụng
Mashup từ đó cũng bị hạn chế vì người phát triển phải chỉnh sửa trực tiếp trong mã
nguồn. Khả năng tích hợp widget từ nhiều thư viện khác nhau lúc này lại trở thành
rào cản vì đòi hỏi lập trình viên phải am hiểu rõ về cách sử dụng nhiều thư viện.
3.3 Mô hình tích hợp các thành phần thể hiện (Jin Yu[14])
3.3.1 Giới thiệu
Phương pháp biểu diễn được Jin Yu, Fabio Casati, Florian Daniel đề xuất vào
năm 2007 trong đó nhấn mạnh vào việc đặc tả các thành phần hỗ trợ khả năng phối
hợp hoạt động giữa các thành phần thể hiện (Presentation Component): sự kiện và
thao tác.
Sự kiện (Event): được gây ra bởi người dùng trên giao diện thể hiện hoặc các yêu
cầu từ các thành phần thể hiện khác.
Ví dụ: Component ParkListing sử dụng dịch vụ “Find a Part” trả về danh sách
công viên và địa chỉ tương ứng. Component này hỗ trợ sự kiện
ParkSelectionChanged, khi được phát ra sẽ truyền đi tham số có tên là parkName
cho Widget nhận. Biểu diễn sự kiện này được mô tả như sau:
36
Thao tác xử lý (Operation): cung cấp tập các xử lý cho phép truy cập thông tin
bên trong Component hoặc thay đổi trạng thái thể hiện của nó.
Ví dụ: Component bản đồ sẽ cung cấp thao tác showPointOfInterest hiển thị
bản đồ theo tham số vị trí được cung cấp hoặc thao tác setZoomLevel dùng để cập
nhật trạng thái phóng to, thu nhỏ (tỉ lệ zoom) của bản đồ. Với thao tác
showPointOfInterest khi được gọi thực hiện, ta phải cung cấp đối số đầu vào là
nps:POI. Biểu diễn của thao tác được mô tả như sau:
3.3.2 Biểu diễn sự phối hợp
Jin Yu cũng đề xuất đặc tả biểu diễn sự phối hợp với tính tổng quát, đơn giản và
trừu tượng cao.
Ví dụ: ta có thể kết hợp 2 Component DataViewer và EventExplorer như sau:
<listener id=“parkChangedMapListener”
xmlns=“”
publisher=“parkListing”
event=“ParkSelectionChanged”
subscriber=“map”
operation=“showPOI”/>
Biểu diễn này khai báo mối quan hệ về mặt phối hợp hoạt động. Cụ thể, khi sự
kiện ParkSelectionChanged tại widget parkListing phát ra, nó sẽ được truyền sang
widget map kích hoạt xử lý showPOI. Tham số sự kiện sẽ tự động ánh xạ với đối số
của thao tác xử lý.
37
Hình 3-1 mô tả kết quả phối hợp từ biểu diễn trên. Khi người dùng chọn một công
viên trong danh sách, vị trí tương ứng sẽ được thể hiện trực quan lên bản đồ Google.
Hình 3-1: Kết quả xử lý của biểu diễn phối hợp được
tạo ra dựa trên biểu diễn [14]
3.3.3 Nhận xét
Ưu điểm trong mô hình đề xuất là tính đơn giản và trừu tượng cao. Do đó hướng
tiếp cận này phù hợp với nhiều loại người dùng (nhà phát triển widget hoặc thậm chí
người dùng cuối) có thể mô tả sự phối hợp dễ dàng. Các tác giả cũng đã cài đặt thử
nghiệm Engine vận hành việc phối hợp.
Tuy nhiên, mô hình còn tồn tại một số hạn chế sau:
Trong các ví dụ về sự phối hợp, Jin Yu chỉ minh họa việc truyền các tham số
kiểu cơ sở. Các tham số kiểu cấu trúc không được đề cập một cách tường
minh.
Thao tác (operation) được dùng để minh họa chỉ có một đối số, trong trường
hợp thao tác có nhiều tham số, việc biểu diễn ánh xạ tham số sự kiện vào đối
số cũng chưa được đề cập.
Cơ chế lan truyền sự kiện (sự kiện xảy ra trên widget này sẽ kích hoạt sự kiện
của một widget khác) chưa được biểu diễn.
Vấn đề chuyển đổi kiểu dữ liệu truyền giữa các widget chỉ được nêu ý tưởng,
chưa cung cấp đề xuất biểu diễn hoặc cài đặt hỗ trợ thực tế.
38
3.4 IBM iWidget
3.4.1 Giới thiệu
IBM đưa ra mô hình đặc tả widget và hệ thống API phát triển widget vào năm
2008. Các widget sau khi cài đặt có thể chạy trên IBM Lotus Mashup, công cụ nằm
trong bộ IBM Mashup Center [15].
Kiến trúc Framework được tổ chức với các thành phần sau:
page: đại diện cho ứng dụng Mashup chứa các widget khác.
iWidget: thành phần giao diện hoạt động phía trình duyệt, cung cấp các xử lý
logic hoặc thể hiện thông tin đến người dùng.
iContext: hỗ trợ quản lý các iWidgets đang tích hợp trên page. Context quản
lý các thông tin sau: các widget đang tồn tại trong trang, sự tương tác giữa
iWidget với Framework và các dịch vụ bên dưới, sự phối hợp giữa các
iWidget.
Encapsulation Wrapper: đóng gói iWidget, cung cấp các hỗ trợ tương tác
giữa iContext và iWidget.
Hình 3-2: Kiến trúc IBM iWidget [54]
39
Hình 3-2 trình bày kiến trúc các thành phần được sử dụng khi Mashup. Một trang
web page sẽ chứa nhiều widget có khả năng tương tác với nhau và tất cả sự phối hợp
đều do đối tượng iContext quản lý.
Để nắm rõ hơn về cấu trúc widget, ta xét một ví dụ về widget Stock. Biểu diễn
của nó bao gồm 2 phần: thành phần giao diện (stock.xml) và lớp cài đặt các xử lý
nghiệp vụ (stock.js).
Thành phần thể hiện giao diện được khai báo trong tập tin xml (stock.xml) có nội
dung được trình bày trong Bảng 3-2. Thành phần này có chức năng đặc tả nguồn dữ
liệu (iw:itemSet), giao diện thể hiện (iw:content), khai báo lớp đóng gói liên quan
(encapsulation class – iw:resource).
<iw:iWidget id=“stock”
xmlns:iw=“”
iScope=“stock” supportedModes=“view” mode=“view” lang=“en”>
<iw:itemSet id=“attributes” private=“true”
onItemSetChanged=“changeItemSet”>
loading...
Stock Quote: loading...
Broker:
loading...
<input type=“button” style=“height=10px”
name=“send” value=“Send Data”
onclick=“iContext.iScope().sendData()”/>
<input type=“button” style=“height=10px”
name=“configure” value=“Edit Broker”
onclick=“iContext.iScope().editBroker()”/>
Bảng 3-2: Nội dung thành phần thể hiện của Widget Stock.
40
Trong biểu diễn này, thành phần lớp đóng gói (encapsulation class - stock.js) có vai
trò tương tự Code Behind trong Asp.net, định nghĩa các thuộc tính, phương thức, sự
kiện trong widget. Khi cần gọi thực hiện các xử lý trong lớp đóng gói, widget sử dụng
đối tượng iScope. Nội dung cài đặt bên trong stock.js được mô tả như sau:
dojo.declare(“stock”,null,null,{
onview: function () {
var element = this.iContext.getElementById(“stock”);
var attributesItemSet =
this.iContext.getiWidgetAttributes();
element.innerHTML =
attributesItemSet.getItemValue(“stock”);
var element2 =
this.iContext.getElementById(“company”);
element2.innerHTML =
attributesItemSet.getItemValue(“company”);
},
updateStock:function(iEvent) {
var element2 = this.iContext.getElementById(“company”);
element2.innerHTML = iEvent[“payload”];
}
});
Cài đặt của lớp đóng gói bao gồm 2 hàm callback onview, updateStock với ý
nghĩa như sau:
onview là hàm callback được gọi khi hiển thị widget.
updateStock là hàm xử lý sự kiện. Khi widget nhận được sự kiện thay đổi
company từ widget khác, nó sẽ nhận được thông tin này thông qua đối số
iEvent và kích hoạt updateStock xử lý.
Widget sau khi xây dựng xong có thể sử dụng trong các ứng dụng Mashup với biểu
diễn như sau:
<a class=“mm_Item” href=“#company”
style=“visibility: hidden”> Yahoo
41
<a class=“mm_Item” href=“#stock”
style=“visibility: hidden”> 27
<a class=“mm_Item” href=“#broker”
style=“visibility: hidden”> Ameritrade
<a class=“mm_SourceEvent” href=“#1”
style=“visibility: hidden”>sendStockData
<span class=“mm_TargetEvent”
style=“visibility: hidden”>onGetCompanyName
Widget khai báo tham chiếu đến file cấu hình qua thuộc tính href=“…/stock.xml” để
trình bày giao diện thể hiện.
3.4.2 Khai báo sự kiện
Widget khai báo khai báo sự kiện thông qua thuộc tính (attribute) với tên bắt đầu
bằng on, ví dụ: sự kiện onStockChange trong widget Stock được khai báo như sau:
<iw:iWidget name=“stock”
xmlns:iw=“”
iScope=“stock”
onStockChange=“updateStock”>
Trong đó, hàm xử lý sự kiện (event handler) bắt buộc phải khai báo trong lớp
đóng gói (stock.js) như sau:
dojo.declare(“stock”,null,null,{
onview: function () {
var element = this.iContext.getElementById(“stock”);
var attributesItemSet= this.iContext.getiWidgetAttributes();
element.innerHTML = attributesItemSet.getItemValue(“stock”);
var element2 = this.iContext.getElementById(“company”);
element2.innerHTML=attributesItemSet.getItemValue(“company”);
},
updateStock:function(iEvent) {
var element2 = this.iContext.getElementById(“company”);
element2.innerHTML = iEvent[“payload”];
}
});
42
IBM iWidget hỗ trợ 2 cơ chế phát ra sự kiện:
Sự kiện do widget tự phát ra thông qua phương thức fireEvent của đối tượng
iContext.iEvents.
iContext.iEvents.fireEvent(“onStockChange”,null, “data”)
Sự kiện được phát ra bởi các widget khác sử dụng đối tượng serviceManager.
serviceManager.getService(“eventService”).fireEvent(“widgetId”,
“onStockChange”,”DATA”)
Trong cả 2 cơ chế kích hoạt sự kiện, tham số dữ liệu truyền (DATA) có thể là nội
dung kiểu cơ sở hoặc kiểu cấu trúc với mô tả dựa trên JSON hoặc XML.
3.4.3 Sự phối hợp widget
Framework cung cấp 2 cách phối hợp:
Trạng thái chia sẻ (Shared State): là nội dung mà widget có thể chia sẻ với
các thành phần khác trên cùng Page (Mashup Canvas). Subscriber widget sẽ
được thông báo khi Shared State thay đổi bằng cách đăng ký xử lý với Shared
State.
Sự kiện: widget có thể khai báo 2 dạng sự kiện.
o Published Event là các sự kiện mà widget có thể truyền sang widget khác.
Sự kiện loại này được khai báo với thuộc tính published là true, kiểu dữ
liệu truyền được xác định với thuộc tính payloadType. Ta có thể tham
khảo cách thức khai báo sự kiện published theo ví dụ bên dưới.
<iw:event id=“cellDataSelected” published=“true”
eventDescName=“desc_cellDataSelected”/>
Trong ví dụ trên, sự kiện truyền cellDataSelected được phát ra khi người dùng chọn
một ô trong danh sách và truyền tham số với kiểu dữ liệu bất kỳ (payloadType có giá
trị là any).
o Handled Event là sự kiện mà widget có thể nhận. Handled Event được
khai báo với thuộc tính handled là true, kiểu dữ liệu mà sự kiện nhận
được xác định với thuộc tính payloadType. Ví dụ về cách khai báo sự
kiện handled được mô tả như sau:
43
<iw:event id=“displayEventData” handled=“true”
onEvent=“displayData” eventDescName=“desc_displayEventData”/>
Trong ví dụ trên, sự kiện mà widget có thể nhận có tên là cellDataSelected khi được
kích hoạt sẽ nhận tham số là kiểu dữ liệu bất kỳ (payloadType có giá trị là any).
Sự phối hợp chỉ diễn sau khi 2 widget đã được phối hợp và quá trình này có thể dễ
dàng thực hiện thông qua giao diện do công cụ cung cấp theo Hình 3-3.
Hình 3-3: Giao diện phối hợp widget do công cụ IBM Lotus Mashup cung cấp
Trong Hình 3-3, widget nguồn Data Viewer sẽ truyền nội dung url trong nội
dung của nó khi sự kiện cellDataSelected phát ra. Widget nhận Event Explorer sẽ
nhận tham số url và truyền vào đối số của sự kiện displayEventData của nó. Từ thao
tác phối hợp thực hiện trên giao diện, hệ thống sẽ phát sinh đặc tả phối hợp với biểu
diễn như sau:
<a class=“mm_SourceEvent” href=“#1”
style=“visibility:hidden”> cellDataSelected
displayEventData
44
Khi widget nguồn phát ra Published Event (cellDataSelected), Handled Event
(displayEventData) trong widget đích sẽ được kích hoạt và thực hiện xử lý tương
ứng (hàm displayData trong lớp đóng gói). Ngoài ra, tham số sự kiện cũng được
truyền cho widget nhận xử lý.
3.4.4 Nhận xét
Mô hình do IBM cung cấp đã hỗ trợ tương đối đầy đủ khả năng phối hợp widget,
đồng thời khắc phục được phần lớn các hạn chế trong mô hình của Jin Yu[