Lời nói đầu: bài viết này nằm trong loạt 5 bài viết hướng dẫn các kỹ thuật nền tảng để xây dựng 1 ứng dụng J2EE hoàn chỉnh. Các bài viết này dành riêng cho khóa "J2EE nền tảng" củaJava Developer Training Center (JDTC). Sau đây là danh sách toàn bộ bài viết:
- Cốt lõi Java trong phần mềm quản lý J2EE - Kết nối thế giới hướng đối tượng và quan hệ - Giao diện người - máy thế hệ mới - Máy ảo javascript với jquery - MVC framework nào, đó là câu hỏi cần trả lời
Từ Struts 1 sang Struts2 là một quá trình. Quá trình này diễn ra với một khoảng thời gian im lặng đáng sợ của Struts 1. Nhiều người cho rằng Strust 1 đã chín muồi nên không cần phải phát triển thêm. Nhiều người tin rằng Struts 1 đã chết. Thế nhưng Struts đã hồi sinh kỳ diệu bằng việc nhập chung vào 1 hảo framework MVC mới nổi webwork, một framework đàn em nhưng thực sự là "anh hùng xuất thiếu niên" với hàng loạt các tính năng mới mẻ và mạnh mẽ. Trên thực tế Struts 2 là tên gọi mới của webwork - bình mới rượu mới hoàn toàn. Struts2 cho phép hàng loạt các tính năng mạnh mẽ như: - Tích hợp đảo ngược điều khiển của Spring
- Lập trình theo khía cạnh (aspect programming) thể hiện bằng việc hiện thực các Đánh chặn (interceptor)
- Cho phép lập trình viên lựa chọn các view khác nhau như: JSP, FreeMaker, Velocity.
- Cho phép tích hợp: form validation, error handling, internationalization (i18n)
Cấu trúc của Struts2:
Một project trên Struts2 sẽ bao gồm các thành phần sau:
- Action class: đây là file Java đóng vai trò Controller trong MVC pattern. File Java này hiện thực lớp Action của Struts2 trong đó chủ yếu là hiện thực method execute. Phương thức này nói nôm na là nhận kết quả từ người dùng sau đó xử lý và trả kết quả về.
- View layer: tùy theo hiện thực cụ thể có thể là các file jsp hoặc vm dùng để hiển thị giao diện người dùng
- Data model/service layers: tương ứng với phần Model trong MVC pattern. Các file trong phần này sẽ hỗ trợ xử lý kết quả cho action class.
- beans.xml: tương tự như trong Spring, file beans.xml này khai báo các bean sẽ được dùng trong project.
- struts.xml: file này thay thế cho xwork.xml trong webwork dùng để map giữa URL và action class đồng thời map giữa result code và file view.
-web.xml: được đặt ở webapp/WEB-INF/, web.xml cho phép map giữa URL pattern (trong trường hợp này là *.action) với ServletDispatcher của Struts.
Bài tập:
1. Viết 1 ứng dụng Struts cho phép xuất ra dòng chữ "Hello Struts - I love JDTC" khi người dùng nhấn nút Say Hello
2. Viết 1 ứng dụng cho phép người dùng chọn ngôn ngữ tiếng Nauy và tiếng Anh sau đó nhấn nút Say Hello để xuất ra dòng chữ tùy theo ngôn ngữ được chọn:
- Hei Struts - Jeg elsker JDTC
- Hello Struts - I love JDTC
3. Tính hợp với ví dụ Hibernate quản lý user ở phần trước, viết các chức năng Tạo, Đọc, Cập nhật, Xoá (CRUD) cho user.
4. Thử dùng tính năng Form Validation của Struts2 để validate form nhập user
5. Xây dựng ứng dụng đa ngôn ngữ bằng i18n cung cấp bởi Struts2 cho phép 2 ngôn ngữ Nauy và Anh.
Lời nói đầu: bài viết này nằm trong loạt 5 bài viết hướng dẫn các kỹ thuật nền tảng để xây dựng 1 ứng dụng J2EE hoàn chỉnh. Các bài viết này dành riêng cho khóa "J2EE nền tảng" củaJava Developer Training Center (JDTC). Sau đây là danh sách toàn bộ bài viết:
- Cốt lõi Java trong phần mềm quản lý J2EE - Kết nối thế giới hướng đối tượng và quan hệ - Giao diện người - máy thế hệ mới - Máy ảo javascript với jquery - MVC framework nào, đó là câu hỏi cần trả lời
Giới thiệu
Như đã trình bày ở bài trước, sự kết hợp của javascript với các trang web đã tạo nên một thế hệ ứng dụng chạy trên web mới: tiện dụng, đáp ứng nhanh, đẹp mắt. Các ứng dụng chủ yếu nhất của javascript có thể chỉ ra là: kiểm tra dữ liệu nhập bởi người dùng (validation), xử lý dhtml, và quan trọng nhất là Ajax.
javascript cung cấp các hàm cho phép lập trình viên thực hiện một các tất cả những tác vụ mong muốn. Tuy nhiên, hiện nay có một xu hướng sử dụng lại các thư viện javascript viết sẵn bởi vì nó giúp lập trình viên tiết kiệm rất nhiều công sức nếu phải xây dựng từ đầu (from scatch). Hợn thế nữa, nếu dùng js nguyên thủy lập trình viên phải viết rất nhiều dòng lệnh trong khi nếu dùng thư viện có sẵn lập trình viên chỉ cần viết vài dòng lệnh mà vẫn có hiệu quả tương đương.
Có rất nhiều bộ thư viện như vậy ví dụ: Yahoo GUI, Prototypes, Ext JS, và đặc biệt là jquery. Trong số này, jquery là bộ thư viện được ưu chuộng nhất và mạnh mẽ nhất với những đặc điểm sau:
- Đơn giản hóa cú pháp js
- Đảo ngược điều khiển
- Có một cộng đồng đông đảo ngày đêm viết thêm các bộ thư viện tiện ích cho jquery từ điều khiển giao diện, các hiệu ứng chuyển động.
1. Cú pháp của jquery:
Để tiết kiệm code, jquery sử dụng 1 bộ cú pháp rất khác thường. Điều này có thể gây khó khăn cho những người mới bắt đầu. Tuy nhiên "khẩu quyết" để viết jquery có thể tóm tắt như sau:
- Chọn 1 hoặc nhiều thành phần trên trang web
- Chọn biến cố (event) sẽ xảy ra trên thành phần được chọn
- Xử lý biến cố này
Xem ví dụ đơn giản sau. Trang web có 1 nút nhấn và 1 thẻ div. Khi nhấn vào nút nhấn này, thẻ div sẽ hiện ra dòng thông báo: "JDTC - My desire"
- Ta có thể thêm chút hiệu ứng để trang web sống động hơn:
$("#divMsg").html("JDTC is my desire").show("slow");
Nhận xét:
- Toán tử dấu dollar $ cho phép chọn đối tượng bằng cách truyền vào "#id_của_đối_tượng".
- Tiếp sau đó là biến cố có thể xảy ra trên đối tượng đó. Các biến cố này cũng tương tự như trong javascript tuy nhiên không có tiền tố "on" phía trước. Ví dụ: click, dblclick, hover, mouseover, keyup, keypress....
- Biến cố sẽ bọc bởi từ khóa function cho phép định nghĩa 1 hàm xử lý biến cố này. Function chỉ có từ khóa, không có tên để giúp lập trình viên tiết kiệm công sức đặt tên hàm.
- Cascading: chắc có lẽ dịch là "dính chùm". jquery tiết kiệm code bằng cách cho phép gán toán tử dính chùm nhau. Điều này giúp tiết kiệm thời gian khi lập trình viên phải viết các biến trung gian để lưu kết quả tạm.
2. Đảo ngược điều khiển
Tương tự như Spring, jquery cũng cho phép đảo ngược điều khiển. Theo ví dụ ở trên nếu không có jquery ta phải khai báo hàm bên trong đối tượng:
jquery UI hỗ trợ các điền khiển nâng cao như kéo thả, slider, accordance... Tận dụng sức mạnh của các thư viện này, trang web của bạn sẽ trở nên "pro" hơn bao giờ hết.
4. Cross browser:
Vấn đề đau đầu của lập trình viên đã được giải quyết triệt để trong jquery. Viết 1 lần chạy mọi nơi đã đúng cho Java giờ lại đúng cho jquery.
5. Hỗ trợ Ajax mượt mà
Ajax đòi hỏi sự kết nối với máy chủ để lấy dữ liệu về và thay đổi một phần nội dung của trang web. Quá trình này diễn ra nhanh hay chậm tùy thuộc vào đường truyền và khả năng xử lý của máy chủ. Để cho giao diện người dùng trở nên thân thiện hơn, ta cần phải có thanh trạng thái báo Ajax đang hoạt động. jquery hỗ trợ làm điều này bằng cách cung cấp 2 hàm ajaxStart và ajaxComplete.
Ví dụ sau cho phép hiển thị thanh "Loading...." khi Ajax đang hoạt động. Thanh trạng thái này thực chất là 1 hình ảnh gif động
$("#imgLoading").ajaxStart(function(){
$(this).show();
});
$("#imgLoading").ajaxComplete(function(){
$(this).hide();
});
Nhờ có cặp hàm này, tất cả các thao tác Ajax trên cùng trang web đều có cùng một "look and feel", mang lại cảm giác thống nhất, dễ dùng cho người dùng.
6. jquery - Máy ảo javascript:
Thực chất jquery có thể được coi như 1 trình biên dịch mini giúp biên dịch các mã lệnh viết bằng ngôn ngữ jquery thành javascript và thực thi được trên trình duyệt.
Xem bảng sau đây để thấy các đại gia như Google, Microsoft, Yahoo đều đã và đang sử dụng jquery cho các ứng dụng của họ.
1. Hiện thực bộ menu của ứng dụng jHMS dùng jquery theo kiểu drop-down menu có sử dụng các hiệu ứng fadeIn, fadeOut. Menu hiện ra dùng hiệu ứng slow.
2. Hiện thực chức năng tìm kiếm bệnh nhân dùng Ajax và jquery. Có thanh trạng thái Loading....
3. Hiện thực chức năng thêm mới 1 bệnh nhân xử dụng Ajax để load form nhập. Sau đó dùng Ajax để post dữ liệu và lưu. Nếu lưu thành công thì trả về thông báo lưu thành công và clear form để chuẩn bị nhập tiếp.
Chú ý trong quá trình chờ dùng thanh Loading..... Kết hợp các hiệu ứng fast, slow, fadeIn, fadeOut để làm trang web trở nên sống động.
Lời nói đầu: bài viết này nằm trong loạt 5 bài viết hướng dẫn các kỹ thuật nền tảng để xây dựng 1 ứng dụng J2EE hoàn chỉnh. Các bài viết này dành riêng cho khóa "J2EE nền tảng" củaJava Developer Training Center (JDTC). Sau đây là danh sách toàn bộ bài viết:
- Cốt lõi Java trong phần mềm quản lý J2EE - Kết nối thế giới hướng đối tượng và quan hệ - Giao diện người - máy thế hệ mới - Máy ảo javascript với jquery - MVC framework nào, đó là câu hỏi cần trả lời
Từ desktop application đến web application là cả 1 cuộc cách mạng. Web 2.0 là mỹ từ được dùng để diễn tả cuộc cách mạng này. Sự kết hợp giữa dhtml, css, và ajax đã làm bùng nổ sức mạnh của các ứng dụng web. Thậm chí đã có những thư viện javascript tuyên bố họ có thể xây dựng được cả 1 hệ điều hành trên web 2.0 (Ext JS).
1. Div của dhtml đã thay đổi thế giới: là viết tắt của Dynamic HTML. Như tên gọi dhtml là một mở rộng của html cung cấp các tiện ích cho phép lập trình viên tương tác với tất cả các thành phần của trang web thông qua javascript. html tĩnh truyền thống thường rất tẻ nhạt với các thẻ định dạng header (từ h1 đến h5), in nghiêng, đậm, các thẻ liên quan đến table, td, tr. Khi thao tác với form, html tĩnh cung cấp text field, select box, radio button, button, text area.
Điểm ấn tượng nhất của dhtml là nó cung cấp thẻ div và hàm javascript getElementById. Với sự bổ sung của 2 thành phần này trang web trở nên sống động hơn trước rất nhiều.
Ví dụ: trang web có 1 button và dùng 1 thẻ div để hiện thông báo. Khi người dùng nhấn vào nút này, thẻ div sẽ thông báo "Hello world".
2. CSS, trang điểm cho trang web đầy sắc màu: CSS là một ngôn ngữ giúp đặc tả màu sắc, font chữ, vị trí, đường viền của các đối tượng trên 1 trang web. CSS có khả năng tác động đến tất cả các thành phần của trang web. Các điểm ấn tượng nhất của CSS bao gồm: - Tạo border 1 cách đẹp mắt: CSS cho phép tạo border cho bất cứ đối tượng nào: text, paragraph, hoặc nội dung trong thẻ div (được dùng phổ biến nhất). Format border bao gồm: màu, style (đường liền hoặc đứt né), và độ dày (thick, thin, medium). http://www.html.net/tutorials/css/lesson11_ex1.asp
- Format chữ với các hiệu ứng khác nhau: CSS cho phép chuyển đổi (text-transform) kiểu chữ thành viết chữ in hay kiểu viết hoa, cho phép trang trí (decorate) chữ bằng gạch dưới hoặc gạch ngang, kéo giãn chữ. http://www.html.net/tutorials/css/lesson5_ex3.asp
- Tạo layer trên trang web: ngoài chiều ngang và chiều dọc, với layer trang web sẽ có thêm chiều sâu. Việc chồng lớp được sử dụng nhiều nhất để tạo message box bằng div cho hiệu quả tự nhiên hơn thay vì dùng popup hoặc javascript confirm box. Ví dụ sau cho thấy 5 quân bài được xếp chồng lên nhau (thực chất là 5 tấm hình và dùng z-index và position để xếp lớp): http://www.html.net/tutorials/css/lesson15_ex1.asp
3. Ajax (đọc là "ei jax"): là 1 công nghệ đình đám hiện nay đóng vai trò cột trụ cho web 2.0. Ajax cho phép load lại từng phần của trang web (chủ yếu là thay đổi nội dung của 1 thẻ div nào đó). Như vậy, ajax chỉ phát huy hiệu quả khi kết hợp với lấy việc lấy dữ liệu từ server. Nguyên tắc hoạt động của ajax có thể được tóm tắt như sau: từ trang web hiện hành thông qua javascript gọi 1 url với một hoặc nhiều thông số, url này có thể là 1 action (Struts2) hoặc là trang .php. Trang này có nhiệm vụ xử lý yêu cầu bằng cách tiến hành query vào cơ sở dữ liệu dựa trên các tham số nhận được, và trả kết quả trả lại dưới 2 dạng: html hoặc xml. Với định dạng html, trang hiện hành chỉ việc dùng javascript lấy id của div và điền vào nội dung bằng cách dùng innerHTML. Đối với dạng xml, trang hiện hành cần phải duyệt (traverse) các node của cây xml sau đó điền kết quả vào trang web.
Như vậy, trong trang hiện hành phải có 2 hàm js: hàm thứ 1 phát động gọi xử lý trên server, hàm thứ 2 xử lý kết quả nhận được.
Với sự hỗ trợ của jquery, ajax trở nên "nhuyễn và kỳ ảo hơn bao giờ hết".
Bài tập: 1. Thiết kế trang đăng nhập của facebook (https://login.facebook.com/login.php) sử dụng CSS, javascript
2. Xây dựng lại top menu của trang (http://tuoitre.vn/)
3. Hiện thực chức năng "Write a comment" trong facebook. Ban đầu hiện text field có dòng chữ Write a comment bên trong. Khi người dùng click vào, sẽ mất dòng chữ Write a comment và hiện ra 1 button Save. Khi người dùng thoát focus ra khỏi text field, nếu chưa nhập nội dung gì thì trả về trạng thái cũ, nếu không sẽ giữ nguyên.
4. Tạo 1 form giống như trang sau http://slave.vatgia.com/home/register.php. Lưu ý các validate dùng javascript và hiển thị nội dung ngay tại control cần validate.
Từ lâu ước mơ của lập trình viên là làm sao kết hợp được sức mạnh mô phỏng thế giới của hướng đối tượng và logic lưu trữ của hệ cơ sở dữ liệu quan hệ. Hibernate đã ra đời để thỏa mãn giấc mơ đó. Tuy Hibernate không phải là framework duy nhất có thể làm được công việc này nhưng Hibernate là framework phổ biến nhất và được dùng nhiều nhất. Rod Johnson khi viết Spring đã chừa không viết luôn framework mới cho ORM (Object Relational Mapping) vì ông cho rằng Hibernate đã quá đủ.
Hibernate là một framework rất đầy đủ tuy nhiên khá phức tạp để sử dụng nhất là đối với người mới bắt đầu. Thiết kế cơ sở dữ liệu là công việc khó. Thiết kế class cũng không dễ dàng. Thiết kế mapping giữa 2 thế giới này lại càng phức tạp hơn. Như vậy, làm thế nào để giải được bài toán có 3 biến số như trong trường hợp này?
Kinh nghiệm cho thấy đối với 1 yêu cầu đầu vào R, hầu như chỉ có 1 đáp án thiết kế cơ sở dữ liệu mang tính tối ưu. Nhưng sẽ có nhiều hơn 1 thiết kế class: đơn hướng và đa hướng. Và do đó, sẽ có nhiều hơn 1 cách mapping. Bài toán này giải được dễ dàng nếu ta nhìn nhận 1 thực tế là: về mặt bản chất, chỉ tồn tại 3 kiểu quan hệ: quan hệ 1-1, 1-n, và n-n. Và trong thiết kế hướng đối tượng, ta cố gắng đưa về 3 kiểu quan hệ trên.
1. Quan hệ 1-1 và 1-n: Thực chất quan hệ 1-1 và 1-n có cách xử lý gần như tương đương nhau đó là dùng khóa ngoại để tham khảo tới khóa chính của bảng quan hệ. Ví dụ, quan hệ giữa bệnh nhân và dân tộc sẽ là quan hệ n-1: một bệnh nhân sẽ thuộc về 1 dân tộc và 1 dân tộc sẽ có nhiều bệnh nhân. Cách xử lý: trong bảng bệnh nhân sẽ có 1 cột mã_dân_tộc và liên kết với khóa chính trong bảng dân_tộc.
Trong thế giới hướng đối tượng ta phải thiết kế class như sau: public class Patient { private int id; private String lastName; private String firstName; private Ethnic ethnic; }
với Ethnic được thiết kế như sau: (a) public class Ethnic { private int id; private String name; }
Như đã nói ở trên, thế giới hướng đối tượng cho phép nhiều hơn 1 đáp án cho thiết kế, ví dụ ta có thể thiết kế class Ethnic như sau: (b)
public class Ethnic { private int id; private String name; private Set patients; }
Trên thực tế, cách thiết kế này không phổ biến vì nhu cầu truy xuất danh sách các bệnh nhân từ 1 dân tộc không cao và hoàn toàn có thể thực hiện được thông qua 1 query. Do đó, việc thiết kế phụ thuộc rất nhiều vào bản mô tả yêu cầu.
Xây dựng mapping cho thiết kế trên: - Trong file Patient.hbm.xml ta thực hiện như sau: - Trong file Ethnic.hbm.xml ta thực hiện như sau: đối với thiết kế (a) và Đối với thiết kế (b)
2. Quan hệ n-n: Kiểu quan hệ này nghe có vẻ lãng mạn nhưng ít tồn tại trên thực tế. Một số ví dụ liên quan đến quan hệ này. Trong một dự án sẽ có nhiều nhân viên tham gia làm, một nhân viên sẽ tham gia cùng lúc nhiều dự án. Để có thể lưu trữ được yêu cầu này, ta cần thêm 1 bảng trung gian tạm gọi là duan_nhanvien và lấy 2 khóa chính từ 2 bảng nhanvien và duan lam khóa ngoại. Theo yêu cầu này ta có thiết kế class và hibernate mapping như sau: - Thiết kế class: public class Staff { private int id; private String name; private Date birthDate; private Set projects; }
public class Project { private int id; private String name; private Date startDate; private Set staffs; }
- Mapping:
Khi thực hiện thao tác trên project hoặc staff, Hibernate sẽ tự động tạo bảng trung gian staff_project và cập nhật dữ liệu trên bảng này. NHƯ VẬY, ta không cần phải tạo lớp trung gian để quản lý staff_project. Ví dụ để thêm mới 1 project với 2 nhân viên ta viết như sau:
Staff staffA = new Staff("David Beckham"); staffManager.save(staffA);
Staff staffB = new Staff("C Ronaldo"); staffManager.save(staffB);
Project project1 = new Project("World cup 2010"); project1.getStaffs().add(staffA); project1.getStaffs().add(staffB);
projectManager.save(project1); //////thao tác này sẽ vừa insert 1 dòng vô bảng project, đồng thời 2 dòng vào bảng trung gian staff_project./////
3. Thế giới nhị nguyên: lưỡng nghi sinh tứ tượng Con số 2 phát sinh ra thế giới, sự kết hợp giữa âm và dương làm cuộc sống sinh sôi. Sự kết hợp của 2 trạng thái 0 và 1 phát sinh ra kỉ nguyên thông tin. Trong hibernate mapping cũng vậy, điều gì xảy ra nếu trong ví dụ trên ta thêm vào yêu cầu: mỗi nhân viên làm việc cho 1 dự án sẽ có chức vụ khác nhau và số giờ làm việc hằng tuần khác nhau. Như vậy trong bảng trung gian staff_project ta cần phải thêm vào 2 thuộc tính: position và hours. Do đó, mapping n-n trong trường hợp trên sẽ phải được chuyển thành 2 liên kết n-1:
public class Staff { .... private Set staff_projects; }
public class Project { .... private Set staff_project; }
và 1 class trung gian:
public class Staff_Project { private Project project; private Staff staff; private int hours; private String position; }
Hibernate mapping cho trường hợp này sẽ trở lại thành trường hợp n-1 như đã nói ở trên.
4. Thao tác với hibernate: Hibernate cung cấp đầy đủ các API giúp cho lập trình viên thực hiện các thao tác tương tự như với jdbc. Lập trình viên chỉ cần gọi hàm save hoặc update, Hibernate sẽ "take care" việc lưu trữ xuống database. API của Hibernate cũng cực kỳ phức tạp nhưng có thể tóm tắt lại như sau: - Configuration: là lớp dùng để khai báo thông tin về database, các file mapping - SessionFactory: hibernate có 1 nhà máy sản xuất các session - Session: đây chính là lớp cung cấp các thao tác thêm, xóa, sửa, và truy vấn đối tượng.
Qui trình để thao tác với hibernate: (mã giả) Configuration conf = new Configuration(); SessionFactory sf = conf.createSessionFactory(); Session session = sf.openSession(); session.save(new Project("World cup"));
5. Spring và Hibernate: Rod Johnson khi viết Spring đã ưu ái hỗ trợ Hibernate rất đầy đủ mặc dù các phiên bản Hibernate có cách hiện thực khác nhau. Spring giúp tích hợp với Hibernate thông qua 2 lớp: org.springframework.jdbc.datasource.DriverManagerDataSource và org.springframework.orm.hibernate.LocalSessionFactoryBean.
6. Hibernate Query Language (HQL):
Là một ngôn ngữ tương tự như SQL nhưng dùng riêng cho hướng đối tượng. Đặc điểm:
- Góp phần tăng sức mạnh của Hibernate
- Lưu ý đặc biệt: trả về đối tượng chứ không trả về record set.
- Điều kiện của truy vấn: nối chuỗi bằng String chứ không nối với đối tượng do đó điều kiện truy vấn phải lấy thuộc tính của đối tượng để so sánh.
Ví dụ:
Cho mô hình lớp như sau:
public class Ethnic { private int id; private String name; private Set patients; }
public class Patient { private int id; private String lastName; private String firstName; private Ethnic ethnic; }
a. Lấy danh sách các bệnh nhân
query = "from Patient"
b. Lấy danh mục các dân tộc
query = "from Ethnic"
c. Lấy danh sách bệnh nhân người Hoa (phải thực hiện join trên đối tượng)
query = "from Patient as patient inner join patient.Ethnic as ethnic where ethnic.name='Hoa' "
d. Lấy danh sách bệnh nhân có năm sinh là 1985
query = "from Patient as patient where year(patient.birthdate)=1985
Bài tập: 1. Hiện thực mô hình class cho bệnh nhân và dân tộc ở ví dụ 1 như trên. - Viết hibernate mapping file - Viết interface PatientManager và hiện thực bằng Hibernate dưới sự hỗ trợ của Spring
2. Hiện thực mô hình class cho ví dụ nhân viên và dự án ở trên (cho cả 2 trường hợp a và b) - Viết hibernate mapping file - Viết interface StaffManager và ProjectManager và hiện thực bằng Hibernate dưới sự hỗ trợ của Spring
Lời nói đầu: bài viết này nằm trong loạt 5 bài viết hướng dẫn các kỹ thuật nền tảng để xây dựng 1 ứng dụng J2EE hoàn chỉnh. Các bài viết này dành riêng cho khóa "J2EE nền tảng" của Java Developer Training Center (JDTC). Sau đây là danh sách toàn bộ bài viết:
- Cốt lõi Java trong phần mềm quản lý J2EE - Kết nối thế giới hướng đối tượng và quan hệ - Giao diện người - máy thế hệ mới - Máy ảo javascript với jquery - MVC framework nào, đó là câu hỏi cần trả lời
Java là một ngôn ngữ lớn, đầy thách thức nhưng cũng đầy khả năng. Một trong những điểm mạnh của Java chính là cộng đồng rộng lớn với hàng chục ngàn framework khác nhau được xây dựng để hỗ trợ thực hiện các chức năng khác nhau. Có nhiều người dự đoán Java sẽ chết và Ruby sẽ thay thế. Thực sự, Java chỉ có thể chết khi cả cộng đồng to lớn đó chết. Điều này hoàn toàn không dễ xảy ra ít nhất trong thời gian 10 năm tới. Bởi vì, Java luôn thay đổi, luôn thích ứng. EJB cồng kềnh đã được thay thế bằng EJB 3.0. Đặc biệt với Spring, thế giới J2EE đã trở nên hợp nhất và mạnh mẽ hơn bao giờ hết. Nếu thế gian mất 16 năm để Java có thể tiến hóa như hiện tại thì sẽ phải mất từng đó năm để có thể một cái gì đó khác thay thế cho Java.
Java được sử dụng nhiều nhất trong các ứng quản lý trên nền web. Đó là sân chơi mà Java chiếm ưu thế. Và đó cũng là chủ đề của bài viết này.
1. Hướng đối tượng trong Java - Java gắn liền với hướng đối tượng. Có nhiều đánh giá cho rằng Java là ngôn ngữ hướng đối tượng trong sáng nhất. Nhưng hướng đối tượng của Java trong các ứng dụng quản lý khác nhiều so với quan niệm phổ biến là "đối tượng bao gồm các thuộc tính và hành vi". Trong các ứng dụng quản lý, các lớp đối tượng được tách riêng hoàn toàn thuộc tính và hành vi.
Ví dụ 1: - Mô tả yêu cầu: Xây dựng mô hình class để quản lý sinh viên. Mỗi sinh viên có các thuộc tính cơ bản: mã số, họ tên, ngày sinh, địa chỉ, giới tính. Mỗi khoa có thuộc tính: mã khoa, tên khoa. Mỗi sinh viên sẽ thuộc về một khoa, mỗi khoa sẽ có nhiều sinh viên. Ứng dụng cho phép CRUD (Create Read Update Delete) các sinh viên và khoa.
- Phân tích và thiết kế: Theo quan niệm truyền thống lớp (class) bao gồm thuộc tính và hành vi vậy lớp Sinh viên có thể được thiết kế như sau:
public class Student { private String id; private String name; private Date birthDate; private String address; private boolean gender;
//hàm get set cho các thuộc tính của sinh viên
//các method CRUD
public void addStudent(Student student); public void updateStudent(Student student); public void deleteStudent(Student student);
}
Tuy nhiên trên thực tế không ai làm như vậy mà phải tách ra thành 2 lớp riêng biệt: public class Student { private String id; private String name; private Date birthDate; private String address; private boolean gender;
//hàm get set cho các thuộc tính của sinh viên }
public class StudentManager { //các method CRUD
public void addStudent(Student student); public void updateStudent(Student student); public void deleteStudent(Student student);
}
2. Trừu tượng hóa bằng interface: Java có vô số thứ nổi tiếng, design pattern là một trong số đó. Design pattern nghe có vẻ "cao siêu" thực ra cũng rất đơn giản. Làm riết thành quen, design pattern không phải là lý thuyết mà thực chất là kinh nghiệm. Design pattern có hơn 250 mẫu, không ai nhớ được hết 250 mẫu, khoảng mười mấy cái được dùng chủ yếu nhất. Trong J2EE, ít nhất trong Spring, có 2 cái dùng thường xuyên đó là Factory Method và MVC. MVC ai cũng hiểu. Factory method thực chất cũng dễ hiểu.
Áp dụng Factory method cho ví dụ ở trên, ta được:
interface StudentManager { public void addStudent(Student student); public void updateStudent(Student student); public void deleteStudent(Student student); }
Có nhiều cách để hiện thực các methods ở trên. Nếu ta dùng Hibernate, ta sẽ được: public class HibernateStudentManager implements StudentManager { public void addStudent(Student student) { session.save(student); } }
còn nếu hiện thực bằng jdbc:
public class JDBCStudentManager implements StudentManager { public void addStudent(Student student) { con.execute("insert into student(id, name) values(student.getId, student.getName) "); } }
Như vậy, đối tượng trong J2EE tách rời hoàn toàn thuộc tính và phương thức.
3. Đảo ngược điều khiển (Inversion of Control): Đảo ngược điều khiển là 1 khái niệm rất nổi tiếng trong Spring. Nói nghe có vẻ phức tạp nhưng trên thực tế rất đơn giản. Đảo ngược điều khiển trao quyền tạo đối tượng cho bean factory và được cấu hình trên file beans.xml thay vì lập trình viên phải viết code.
Trong ví dụ ở trên, khi muốn tạo 1 đối tượng studentManager, người dùng chỉ việc khai báo:
private StudentManager studentManager:
Sau đó get hoặc set cho property này. Việc quyết định StudentManager là HibernateStudentManager hoặc là JDBCStudentManager hoàn toàn được khai báo trong file beans.xml.
4. Sức mạnh của hướng đối tượng Những điểm mạnh của hướng đối tượng thường được nhắc tới bao gồm: trừu tượng hóa, tính đa hình. Tuy vậy, có một điểm mạnh của hướng đối tượng thường được bỏ quên đó là: hướng đối tượng cho phép mô hình thế giới thực một cách đầy đủ nhất. Thật vậy, trong ví dụ ở trên, nếu sinh viên có thêm thuộc tính Khoa, lớp sinh viên sẽ được mô hình chính xác như sau:
public class Student { .... private Department department: } với Department là một lớp khai báo như sau:
public class Department { private String code; private String name: }
Khi trình bày 1 danh sách sinh viên, nếu muốn lấy tên khoa ta chỉ cần thao tác như sau: student.getDepartment().getName()
Bài tập 1. Phân tích và thiết kế class cho hệ thống có yêu cầu như sau: Hệ thống quản lý 1 danh sách nhân viên. Thông tin của nhân viên gồm có: mã số, họ tên, ngày sinh, giới tính, địa chỉ. Mỗi nhân viên thuộc về 1 phòng ban. Thông tin của phòng ban gồm có: mã phòng, tên phòng. Một phòng ban có nhiều nhân viên. - Viết 1 interface gồm các phương thức để quản lý danh sách nhân viên với các thao tác CRUD (Tạo mới, Đọc, Cập nhật, và Xóa) - Hiện thực interface trên bằng 2 cách: 1) dùng kiểu array chứa danh sách nhân viên 2) dùng jdbc để thao tác với cơ sở dữ liệu;
2. Phân tích và thiết kế class cho hệ thống như sau: Hệ thống quản lý kho dược quản lý danh mục các loại thuốc. Thông tin thuốc gồm có: tên thương mại (brand name), tên thuốc gốc (generic name), qui cách đóng gói, đơn vị tính nhỏ nhất (viên, gói, hộp, chai, lọ). - Viết 1 interface gồm các phương thức để quản lý danh mục thuốc với các thao tác CRUD (Tạo mới, Đọc, Cập nhật, và Xóa) - Hiện thực interface trên bằng 2 cách: 1) dùng kiểu array chứa danh sách nhân viên 2) dùng jdbc để thao tác với cơ sở dữ liệu;
3. Phân tích và thiết kế class cho hệ thống như sau: Hệ thống quản lý xuất nhập tồn kho dược. Hệ thống quản lý danh sách các loại thuốc: tên thuốc, đơn giá. Hằng ngày, nhân viên sẽ lập các phiếu nhập để nhập thuốc vào kho. Thông tin phiếu nhập gồm: số phiếu, ngày nhập, tên nhân viên nhập, tổng tiền trước thuế, % thuế, tiền thuế, và tổng cộng. Mỗi phiếu nhập sẽ bao gồm nhiều chi tiết. Mỗi chi tiết là 1 loại thuốc, số lượng nhập, và đơn giá. - Viết 1 interface gồm các phương thức để quản lý danh mục phiếu nhập với các thao tác CRUD (Tạo mới, Đọc, Cập nhật, và Xóa) - Hiện thực interface trên bằng 2 cách: 1) dùng kiểu array chứa danh sách nhân viên 2) dùng jdbc để thao tác với cơ sở dữ liệu;
Lời nói đầu: bài này nằm trong loạt bài gồm 5 bài, thảo luận các vấn đề khác nhau trong việc xây dựng ứng dụng quản lý trong Java. - Cốt lõi Java trong phần mềm quản lý J2EE - Kết nối thế giới hướng đối tượng và quan hệ - Giao diện người - máy thế hệ mới - Máy ảo javascript với jquery - MVC framework nào, đó là câu hỏi cần trả lời
Các bài viết này nhằm mục đích hệ thống hóa lại những nhận xét cũng như kinh nghiệm thực tế của tác giả sau một thời gian làm việc với J2EE với mong muốn góp chút sức mọn đào tạo nên những lập trình viên Java có trình độ làm chủ được công nghệ và giải quyết được những bài toán mà thực tiễn phát triển của đất nước đang đặt ra như: chính phủ địên tử, y tế điện tử, giáo dục... Các bài viết này được viết với phương châm ngắn gọn, thực tế, và thực hành. Một số lượng các đồ án được đặt ra sau mỗi bài viết sẽ giúp học viên thực sự hiểu được "what is going on here?".
Là người theo chủ nghĩa thực dụng, tôi có một nhận xét rất tiêu cực rằng, những bài giảngvề lập trình dù được dạy trực tiếp bởi Bill Gates hay Rod Johnson cũng vô nghĩa nếu học viên không trực tiếp "trải nghiệm" bằng những ví dụ và bài toán cụ thể. Cách đây khoảng 5 năm, tôi có viết vài bài trên Javavietnam.org trong đó có một câu đại ý "tất cả những lý thuyết đại ngôn sẽ trở nên vô nghĩa nếu bạn không tự mình làm thử qua một ví dụ". Áp dụng tinh thần đó, loạt bài này sẽ theo công thức 4+1 nghĩa là 4h làm thực tế và 1h thảo luận. Như vậy có thể thấy, loạt bài này không dành cho những người tự học. "Sorry for that", người Anh thường dùng câu này khi phải nói ra sự thật mà không đúng với mong đợi của người được nghe. Chúng ta ai cũng có khuynh hướng tự học nhưng "it doesn't work", ít nhất là trong khuân khổ giáo trình này.
What is beyond the scene? Ý nghĩa của những việc này là gì?
Tôi tin tưởng vào triết lý "empowering people" - con người đều có những khả năng tiềm ẩn để làm những việc lớn hơn những cái họ đang làm. Để làm được vậy, họ cần phải được đào tạo để khai phá những tiềm năng đó. Những người bán vé số, những người nhặt rác, họ không hề vô dụng, họ có tiềm năng lớn. Họ có thể được đào tạo để làm những công việc có giá trị gia tăng cao hơn, và mưu cầu một cuộc sống tốt hơn. Nếu tất cả những người có hoàn cảnh khó khăn đều được "powered", chắc chắn lúc đó đất nước sẽ giàu mạnh lên và người Việt Nam khi cầm hộ chiếu ra nước ngoài sẽ không còn mặc cảm.
Giáo trình này làm một phần trong kế họach lớn hơn: viết lại sách giáo khoa và thông qua đó cải tổ giáo dục sâu rộng. Chưa ai làm được việc này, và sẽ không ai làm được việc này bởi lẽ đơn giản: nó đòi nỗ lực của một đội ngũ, của một mạng lưới. Bản thân từ đội ngũ đã mang ý nghĩa trừu tượng, đội ngũ là 2 người hay 2000 người. Như vậy, đội ngũ phải được bắt đầu từ người thứ 1và thứ 2, người thứ 10, người thứ 100.... Như vậy bạn có muốn là người thứ 100?