|
Trong bài viết này, tôi sẽ giới thiệu tổng quan về Phương pháp thiết kế MVC, và
minh họa Cách sử dụng MVC trong Thiết kế hướng đối tượng bằng việc xây
dựng phần mềm Java Web Mail.
Phương pháp thiết kế MVC bắt đầu
từ việc phát triển giao diện với người sử dụng (user interface) trong ngôn ngữ
lập trình Smalltalk, và là một trong những phương pháp thiết kế thành công nhất
trong các Phương pháp thiết kế hướng đối tượng (Object Oriented Design Pattern).
Hiện nay, MVC được dùng một cách rộng rãi trong nhiều hệ thống phần mềm hướng
đối tượng (OO Application), bất kể được viết bằng ngôn ngữ hướng đối tượng (OO
Language) nào.
Trong bài viết này, tôi sẽ giới
thiệu tổng quan về Phương pháp thiết kế MVC, và minh họa Cách sử dụng MVC trong
Thiết kế hướng đối tượng bằng việc xây dựng phần mềm Java Web Mail. Để nhận rõ
được ý nghĩa của việc ứng dụng MVC trong Java Web Mail, bạn đọc phải quen thuộc
với ngôn ngữ lập trình Java, các khái niệm về JSP, Servlet, Java Mail API. Tuy
nhiên, bạn đọc cũng có thể tham khảo mã nguồn của chương trình, dịch, chạy thử
và tìm hiểu dần dần.
MVC là 3 chữ viết tắt của
Model-View-Controller. Phương pháp thiết kế MVC (MVC Design Pattern)[1] là một
phương pháp chia nhỏ Presentation tier của một ứng dụng nhiều lớp (multi-tier application) hoặc chia
nhỏ phần giao diện với người dùng (user interface)[2] của một ứng dụng bất kỳ thành ba
thành phần chính là Model, View và Controller.
Model (Tạm dịch là phần Mô hình
[3]) : Đúng như tên gọi của nó, Model là một đối tượng hoặc một tập hợp các đối
tượng biểu diễn cho phần dữ liệu của chương trình, ví dụ như các dữ liệu được
lưu trong database, dữ liệu từ một hệ thống các ứng dụng khác như legacy system,
file system, mail system …
View (Tạm dịch là phần Hiển thị)
: Đây là phần giao diện với người dùng, bao gồm việc hiện dữ liệu ra màn hình,
cung cấp các menu, nút bấm, hộp đối thoại, chọn lựa …, để người dùng có thể thêm,
xóa. sửa, tìm kiếm và làm các thao tác khác đối với dữ liệu trong hệ thống.
Controller (Tạm dịch là phần
Điều khiển) : Đây là phần điều khiển toàn bộ logic về hoạt động của giao diện,
tương tác với thao tác của người dùng (từ chuột, bàn phím và các thiết bị ngoại
vi khác) và cập nhật, thao tác trên dữ liệu theo input nhận được và điều khiển
việc chọn phần Hiển thị thích hợp để truyền dữ liệu tới người dùng.
Dưới đây là sơ đồ của Phương
pháp thiết kế MVC :
- Khi người sử dụng ra một
lệnh (gõ câu lệnh, bấm nút chuột, bấm phím, chọn menu …), lệnh này sẽ được gửi
tới phần Điều khiển.
- Phần Điều khiển sẽ khởi tạo
phần Mô hình (nếu cần thiết), gửi các yêu cầu tới phần Mô hình để thực hiện.
- Căn cứ trên các lệnh và
thông tin nhận được từ lệnh, phần Mô hình sẽ đảm nhận việc lấy thông tin và
cập nhật thông tin trong các hệ thống khác, ví dụ trong các Enterprise Server
như Aplication Server, Mail Server, Database Server, từ File System, Network
File System, Legacy System …
- Sau khi hoàn thành việc thu
thập, cập nhật thông tin, Mô hình sẽ truyền những thông tin cần thiết về phần
Điều khiển.
- Lúc này, phần Điều khiển sẽ
quyết định chọn thành phần nào trong phần Hiển thị để hiện dữ liệu ra cho
người dùng.
- Phần Hiển thị khi làm nhiệm
vụ hiện thông tin cho người dùng cũng có thể truy cập các thông tin hiển thị
từ Mô hình, hoặc gửi thông tin hiển thị tới Mô hình. Trường hợp này xảy ra khi
Mô hình chứa các thông tin có thể dùng để hiện trực tiếp, ví dụ một danh sách
khách hàng, hoặc một danh sách các e-mail trong mailbox. Khi phần Hiển thị
hiện thông tin, nó có thể báo cho phần Mô hình biết nó đang hiện phần nào của
thông tin, ví dụ như “Đang hiện thông tin khách hàng từ 20 đến 40”. Những
thông tin loại này không cần thiết phải gửi qua trung gian Điều khiển.
Với phương pháp thiết kế này,
các chức năng hiển thị, chức năng logic điều khiển và chức năng truy cập dữ liệu
của chương trình được chia làm các phần tách biệt. Khi cấu trúc hoặc cách cài
đặt của một phần được thay đổi, các phần kia hầu như không cần thay đổi, hoặc
thay đổi rất ít về API (Application Programming Interface). Khi phần Hiển thị
cần thay đổi hình thức trình bày, phần Điều khiển và phần Mô hình hoàn toàn có
thể giữ nguyên.
Java là một ngôn ngữ lập trình
hướng đối tượng thuần túy (pure OOP Language), nên việc áp dụng Phương pháp
thiết kế MVC vào các phần mềm viết bằng Java rất dễ dàng và hiển nhiên. MVC
không phải là phương pháp duy nhất dùng để thiết kế giao diện với người sử dụng
trong Java, nhưng cho đến nay, nó vẫn là phương pháp tốt nhất cho việc này, nhất
là trong các ứng dụng Web.
Kể từ khi ra đời công nghệ JSP
(Java Server Page) và Servlet, có hai hình mẫu (model) [4] chính của Phương pháp
thiết kế MVC trong Java là MVC model 1 và MVC model 2.
Dưới đây là sơ đồ của MVC model
1:
Trong MVC model 1, các trang JSP
đóng vai trò Hiển thị (View) và Điều khiển (Controller). Có thể có nhiều trang
JSP khác nhau đóng các vai trò khác nhau.
- Khi người sử dụng dùng các
nút bấm, menu hoặc link … trên trình duyệt Web (Web browser) để thực hiện một
thao tác, một lệnh (có thể kèm theo các tham số) được gửi tới một trang JSP
tương ứng.
- Trang JSP này sẽ khởi tạo
một hoặc nhiều Java Bean (nếu cần thiết), truyền các lệnh cần thi hành tới
Java Bean. Chú ý rằng đây là các Java Bean thông thường, chứ không phải
Enterprise Java Bean (EJB)
- Sau khi Java Bean thực hiện
xong việc truy xuất hoặc cập nhật dữ liệu, trang JSP ban đầu có thể hiển thị
dữ liệu lấy từ Bean (JSP ban đầu đóng luôn vai trò View), hoặc chọn một trang
JSP khác để hiện dữ liệu từ Bean (JSP ban đầu đóng luôn vai trò Controller).
Trong một thiết kế tốt, để bảo đảm việc tách rời phần trình bày và logic của
chương trình, trang JSP nhận request chỉ đóng vai trò Điều khiển (Controller).
MVC model 1 có một nhược điểm
là phần logic điều khiển được viết trong trang JSP, như vậy phần chương trình
Java phức tạp dùng để điều khiển sẽ bị lẫn vào trong mã HTML dùng để trình bày.
Độ phức tạp của chương trình càng cao, thì trang JSP càng khó bảo trì. Hơn nữa
trong các dự án phần mềm phức tạp, thì phẩn hiển thị của trang JSP thường được
làm bởi người thiết kế Web, giỏi về HTML và đồ họa, còn phần chương trình Java
được viết bởi lập trình viên chuyên về lập trình. Trong các dự án phức tạp, dùng
JSP làm phần điều khiển sẽ làm lẫn lộn việc phân chia ranh giới trách nhiệm giữa
nhóm thiết kế đồ họa và nhóm lập trình, đôi khi dẫn đến việc bảo trì và phát
triển trở nên rất khó khăn, gần như không thể làm được.
Để khắc phục nhược điểm này, MVC
model 2 ra đời. Dưới đây là sơ đồ của MVC model 2:
Trong MVC model 2, một hoặc
nhiều servlet (thường là một) đóng vai trò Điều khiển, các Java Bean đóng vai
trò Mô hình và các trang JSP đóng vai trò hiển thị.
Trong model 2, các logic phức
tạp của chương trình được viết hoàn toàn trong các servlet, là các chương trình
Java. Phần hiển thị chỉ gồm các trang JSP với một vài mã đơn giản để lấy dữ liệu
có sẵn, không có logic phức tạp, vì thế hoàn toàn có thể được tạo ra bằng những
người thiết kế Web.
Các yêu cầu của người dùng được
gửi từ trình duyệt Web tới servlet. Servlet sẽ khởi tạo Java Bean (nếu cần thiết),
ra lệnh thu thập, cập nhật thông tin. Khi Java Bean hoàn thành công việc,
servlet sẽ chọn trang JSP thích hợp để hiện thông tin trong Java Bean cho người
dùng.
Đây chính là một cách sử dụng
MVC rất hiệu quả trong Java. Tất nhiên là sử dụng MVC model 2 một cách hoàn
toàn cứng nhắc, phần Điều khiển chỉ dùng servlet, phần Hiển thị chỉ dùng JSP sẽ
dẫn đến một vài trường hợp kém hiệu quả, nhất là khi có các request từ trình
duyệt Web chỉ đòi hỏi việc hiển thị thông tin.
Ví dụ: một trang Web đang hiện
các mail trong mail box từ mail thứ 20 đến mail thứ 40. Danh sách các mail này
đã có sẵn phần Mô hình khi người dùng login và phần Điều khiển ra lệnh cho phần
Mô hình lấy danh sách các mail có trong mail box trong POP server. Từ trang Web
này, người dùng phát ra một yêu cầu “Next” để xem tiếp danh sách các mail từ
mail thứ 40 đến mail thứ 60. Đây đơn thuần chỉ là đòi hỏi thông tin hiển thị, do
đó, nếu gửi qua servlet Điều khiển , servlet sẽ không làm gì cả, mà chỉ gửi yêu
cầu hiển thị tới trang JSP hiển thị danh sách mail. Trong trường hợp này, gửi
thẳng yêu cầu hiển thị từ trình duyệt Web tới trang JSP sẽ hiệu quả hơn.
Sơ đồ cho cách áp dụng MVC nói
trên như sau:
Trong cách áp dụng MVC này, các
yêu cầu có liên quan đến logic chương trình hoặc truy cập dữ liệu sẽ được gửi
tới servlet controller, còn các yêu cầu chỉ liên quan tới hiển thị sẽ được gửi
tới JSP controller.
Đây chính là cách tôi chọn để
cài đặt chương trình Java Web Mail.
Chương trình Java Web Mail bao
gồm các thành phần sau :
- Một servlet controller
MailUtilServlet, dùng để nhận các yêu cầu: login, logout, gửi mail, hiện
attachment. Những yêu cầu này sẽ được xử lý về mặt logic rồi gửi tới Java Bean
để thực sự làm công việc truy cập mail server. Sau khi Java Bean thực hiện
việc truy cập dữi liệu xong, MailUtilServlet sẽ chọn trang JSP thích hợp để
hiện dữ liệu.
- Một Java Bean MailUserBean
dùng để truy cập mail server, lấy danh sách và mội dung mail trong mail box,
xóa mail trong server.
- Trang JSP index.jsp đóng vai
trò JSP controller, dùng để nhận các yêu cầu: hiện danh sách các mail trong
mail box, hiện nội dung của một mail được chọn trong danh sách, hiện trang
soạn thảo mail để người dùng soạn thảo và gửi mail. Những thông tin cần để
hiển thị đã có sẵn trong MailUserBean, vì MailUserBean đã lấy những thông tin
này khi nhận được yêu cầu login từ MailUtilServlet. Vì thế, những loại yêu cầu
này thuộc về loại yêu cầu hiển thị, không có logic phức tạp, nên không cần
phải gửi qua MailUtilServlet.
- Một tập hợp các trang JSP:
- menu.jsp dùng để hiện menu
lệnh bao gồm Log in, Inbox, Compose và Exit
- first.jsp là trang để
nhập username, password, mailserver cho việc login
- messageheaders.jsp là
trang để hiện danh sách các mail có trong mail box để người dùng chọn xem và
xóa mail trong mail box.
- messagecontent.jsp là
trang để hiện nội dung của một mail đã được chọn từ danh sách.
- compose.jsp là trang để
soạn thảo mail cần gửi.
- status.jsp là trang dùng
để báo về lỗi khi log in, log out không thành công, và thông báo về kết quả
gửi mail thành công hay không.
- errordetails.jsp là trang
dùng để cung cấp thông tin chi tiết mỗi khi có lỗi log in, log out, gửi mail
không thành công. Thông tin trong trang này bao gồm cả Stack Trace của
exception khi sinh ra lỗi, chủ yếu dành cho lập trình viên dùng để xem chi
tiết về vấn đề đã xảy ra.
- logout.jsp là trang hiện
ra khi người dùng login ra khỏi hệ thống mail.
Một vài trang JSP và text file khác dùng để trang trí.
- Một CSS (Cascade Style
Sheet) tên là styleSheet.txt, dùng để định dạng về font và màu sắc cho tất
cả các file JSP.
Trong hệ thống này, không có
database sever. MailUserBean lấy và cập nhật dữ liệu từ POP mail server, gửi
mail từ SMTP server, sử dụng Java Mail API.
Chương trình gồm có các chức
năng sau:
- Sử dụng
HTTP để đọc và gửi mail từ bất kỳ một mail server nào dùng POP3 Protocol trên
Internet hoặc trong Intranet.
- Có thể
truy cập mail qua bất kỳ một proxy server nào có chức năng HTTP proxy. Chức năng
này rất có ích khi người dùng kết nối vào Internet từ một mạng Intranet phía sau
một firewall, và firewall này ngăn chặn các máy tính trong Intranet truy cập POP
server bên ngoài, trong khi đó, người sử dụng muốn gửi và nhận mail từ một POP
server trên Internet.
- Sử dụng
khả năng xử lý các loại dữ liệu (content handling) của trình duyệt Web để hiện
Attachment.
Bạn đọc có thể liên hệ với tạp
chí PC World để nhận file Zip chứa toàn bộ các file Java, JSP … của bài viết,
hoặc download từ Internet.
Đây là một ứng dụng Web sử dụng
JSP/Servlet, nên phải được cài đặt như một Chương trình Web (Web application)
của một Web Server có hỗ trợ servlet engine (ví dụ như BEA WebLogic, IBM Web
Sphere, Sun One, JBoss, Tomcat, Alaire JRun …)hoặc một Web server kết nối với
servlet engine (ví dụ như IIS + Tomcat, Apache + Tomcat, IIS + JRun, Apache +
JRun …).
Có hai phương pháp triển khai
một Chương trình Web:
- Triển khai chương trình
trong thư mục chứa các ứng dụng Web của servlet engine, ví dụ trong <TOMCAT>/webapps
hoặc trong <BEA>/ user_projects/ domains/ mydomain/ <DOMAIN NAME> của BEA
WebLogic. Đây là cách làm dễ nhất.
- Triển khai chương trình
trong một thư mục bất kỳ trên đĩa cứng của server, rồi chỉnh lại server
descriptor để chỉ tới thư mục này.
Đây không phải là bài viết về
Ứng dụng Web và Cách triển khai ứng dụng Web, nên tôi không đi sâu vào chi tiết
của cách cài đặt Java Web Mail vào trong một servlet engine.
Để tiện cho các bạn chưa quen
với việc viết, dịch và triển khai ứng dụng Web, tôi xin trình bày một (trong số
vài cách) dễ nhất là triển khai Java Web Mail vào thư mục webapps/examples của
Tomcat. Bạn có thể download Tomcat từ
http://jakarta.apache.org và cài đặt lên máy tính của bạn.
Khi bung nén file
JavaWebMail.zip ra một thư mục nào đó trên đĩa cứng, ví dụ thư mục D:\java\webmail,
bạn sẽ có một cấu trúc thư mục như sau
- Thư mục D:\java\webmail\jspmail
chứa toàn bộ các trang JSP của chương trình, một CSS dùng để định dạng màu sắc
và font chữ cho tất cả các trang Web và một vài file TXT chứa thông tin về
header, gooter của trang Web.
- Thư mục D:\java\webmail\jspmail\images
chứa các ảnh dùng để trang trí giao diện Web chứa toàn bộ các trang JSP của
chương trình.
- Thư mục D:\java\webmail\src\com\hanoian\mail
chứa hai Java file là mã nguồn chương trình của MailUtilServlet và
MailUserBean. Hai lớp đối tượng này thuộc về gói (package) com.hanoian.mail,
nên chúng nằm trong thư mục com/hanoian/mail dước thư mục src (source).
Trong thư mục D:\java\webmail,
có file compile_sample.bat dùng để dịch thẳng Java Web Mail vào thư mục <TOMCAT>webapps/examples.
Các bạn chú ý các điểm sau trong
file compile_sample.bat :
- JAVA_HOME là thư mục mà bạn
đã cài J2SE (Java 2 Standard Edition), ví dụ C:\j2sdk1.4.1_02. Bạn có thể đặt
giá trị này trong biến môi trường (environment variable), để có giá trị trong
tất cả các lần chạy, hoặc đặt giá trị này bằng lệnh set trước khi chạy
compile_sample, hoặc thay luôn địa tên thư mục vào chỗ của %JAVA_HOME% trong
file compile_sample.bat.
- TOMCAT_HOME là thư mục bạn
đã cài Tomcat, ví dụ như C:\Tomcat4. Bạn có thể làm tương tự như đối với
JAVA_HOME ở trên để thiết lập giá trị cho TOMCAT_HOME
Các bước dịch và triển khai
chương trình như sau:
- Vào thư mục <TOMCAT>/webapps/examples
(ví dụ C:\Tomcat4\examples), tạo thư mục jspmail. Trong thư mục jspmail tạo
thư mục images.
- Mở một dấu nhắc DOS, chuyển
đến thư mục mà bạn đã giải nén file JavaWebMail.zip vào đó, ví dụ D:\java/webmail.
Chạy file compile_sample.bat trong đó, Chú ý phải thiết lập các giá trị
JAVA_HOME và TOMCAT_HOME trước khi chạy.
- Vào thư mục <TOMCAT>/webapps/examples/
WEB-INF (ví dụ C:\ Tomcat4\ examples\ WEB-INF), mở file web.xml ra. Có thể
dùng Notepad, Wordpad hay bất kỳ một chương trình soạn thảo text nào. Nếu có
XML Spy là tốt nhất.
- Trong file web.xml tìm phần
định nghĩa các servlet, là phần bao gồm rất nhiều các XML element có tag là <servlet>,
ví dụ:
<servlet>
<servlet-name>
CompressionFilterTestServlet
</servlet-name>
<servlet-class>
compressionFilters.CompressionFilterTestServlet
</servlet-class>
</servlet>
- viết thêm khai báo servlet
sau đây vào phần dưới của các định nghĩa <servlet> (tức là phần trống giữa các
XML element <servlet> và <servlet-mapping>) :
<servlet>
<servlet-name>MailUtilServlet</servlet-name>
<servlet-class>
com.hanoian.mail.MailUtilServlet
</servlet-class>
</servlet>
- Ghi lại file web.xml, sau đó
khởi động lại Tomcat. Như vậy là chương trình đã được triển khai xong.
Chạy chương trình bằng cách mở
một trình duyệt Web, gõ một trong các liên kết sau vào phần địa chỉ Web:
http://localhost:8080/examples/servlet/MailUtilServlet
hoặc
http://localhost:8080/examples/jspmail/index.jsp
Vì yêu cầu đầu tiên của chương
trình chỉ là hiện màn hình nhập username và password, không có logic, nên nó có
thể được gọi thông qua servlet controller hoặc JSP controller
-------------------------------------
Chú thích
[1] Trong phân tích/ thiết kế
hướng đối tượng (OOA/OOD), khi nói đến MVC, người ta thường dùng các thuật ngữ
MVC Design Pattern, MVC Framework, MVC Paradigm. Theo ý kiến của tôi, khi nói về
thiết kế chương trình, vẽ diagram về cấu trúc của chương trình, MVC là một
phương pháp thiết kế (Design Pattern). Khi có một bộ công cụ tiện ích lập trình
hỗ trợ cho lập trình viên viết chương trình theo phương pháp MVC (ví dụ như
Jakarta Struts ), thì bộ công cụ tiện ích lập trình đó gọi là MVC Framework
implementation. Còn từ Paradigm dùng cho MVC mang tính chất chỉ chung chung.
Hiện nay, tại Mỹ, các thuật ngữ trên thường được dùng lẫn, tùy theo tác giả và
hoàn cảnh.
[2] Trong ngành Khoa học về máy
tính (Computer Science), có rất nhiều khái niệm về giao diện (interface) khác
nhau.
Ví dụ:
- User
interface là giao diện giữa máy tính và người dùng, chủ yếu chia làm 2 loại
chính là Command line (Console) Interface, là giao diện theo dòng lệnh và
Graphical User Interface (GUI), là giao diện đồ họa với người sử dụng.
- API
(Application Programming Interface) là một tập hợp các hàm (funtion) hoặc phương
thức (method) được quy ước sẵn của các software component mà các software
component khác có thể gọi để thực hiện một số chức năng đã xác định trước. Một
ví dụ về API là Window API, gồm một tập các hàm API dùng để gọi thực hiện các
chức năng hệ thống trên Window. Các lập trình viên viết chương trình gọi các API
này để tương tác với Window và cung cấp các thao tác trong chương trình.
- Object
Interface : Trong một hệ thống hướng đối tượng, các đối tượng (object) thường
được thiết kế để cung cấp một tập hợp các phương thức (method) mà các đối tược
khác có thể sử dụng để làm một số nhiệm vụ nhất định. Tập các method chung của
một đối tượng thường được cài đặt thông qua một giao diện gọi là Object
Interface.
- Network
Interface : Đây là card mạng (network card ) của máy tính hoặc các thiết bị mạng.
Ngoài ra, còn nhiều loại
interface khác.
Vì thế, khi nói về giao diện
(interface), tôi sẽ dùng thêm bổ ngữ để chỉ rõ đó là loại interface nào.
[3] Thực ra từ Model trong
trường hợp này (Data Model) dịch ra tiếng Việt là Mô hình không được chính xác
lắm, vì nó không phản ánh hết chức năng của Model trong một hệ thống MVC. Dịch
ra là Mẫu hoặc Hình mẫu cũng không chính xác. Chúng ta chưa có từ tiếng Việt
tương đương, nên tôi tạm gọi là Mô hình.
[4] Từ “model” trong cụm từ MVC
model 1 và MVC model 2 là dùng đề chỉ các hình mẫu khác nhau của cách áp dụng
MVC vào thực tế, chứ không phải là Data Model của MVC.
|