(Post 14/03/2006) OOP (Object-oriented Programming)
lập trình hướng đối tượng hiện là mô hình phát triển được lựa chọn cho
hầu hết các dự án phần mềm. OOP rất hữu hiệu trong việc lập mô hình hành
vi chung của các đối tượng tuy nhiên nó không giải quyết thỏa đáng những
hành vi liên quan đến nhiều đối tượng. AOP giải quyết được vấn đề này,
và rất có thể sẽ là bước phát triển lớn kế tiếp trong phương pháp lập
trình.
|
Vào những ngày đầu của ngành khoa học máy tính, các thảo
chương viên lập trình trực tiếp bằng mã máy. Những nhà phát triển phần
mềm thời đó đã phải tốn nhiều thời gian suy nghĩ về tập lệnh riêng của
từng phần cứng máy tính cụ thể hơn là tập trung để giải quyết các yêu
cầu của bài toán đặt ra. Dần dần, người ta chuyển sang các ngôn ngữ lập
trình cấp cao hơn, cho phép khái quát hoá ở mức độ nào đó mã máy chạy
bên dưới. Rồi kế đến là các ngôn ngữ lập trình có cấu trúc cho phép phân
tích bài toán thành các thủ tục thực hiện những tác vụ cần thiết. Tuy
nhiên, khi độ phức tạp của các bài toán tăng lên, chúng ta cần có những
kỹ thuật tốt hơn. OOP cho phép chúng ta xem hệ thống như là một tập các
đối tượng cộng tác. Lớp (class) cho phép chúng ta ẩn đi những chi tiết
thực hiện bên dưới các giao tiếp (interface). Cơ chế đa hình (polymorphism)
cung cấp giao tiếp và hành vi chung cho những khái niệm liên quan.
Hình 1a |
|
Kỹ thuật OOP rất xuất sắc trong việc đóng gói các hành
vi và chủ thể (lớp), miễn là chúng hoàn toàn riêng biệt. Tuy nhiên, các
bài toán thực tế thường có những hành vi đan nhau liên quan đến nhiều
lớp. Theo truyền thống, hầu hết ngôn ngữ lập trình hướng đối tượng như
C++ và Java đều không hỗ trợ đóng gói những hành vi đan nhau, dẫn đến
mã chương trình có thể nằm lẫn lộn, rải rác và khó quản lý.
AOP (Aspect-oriented Programming) là kỹ thuật lập trình
mới cho phép đóng gói những hành vi có liên quan đến nhiều lớp. Nhóm từ
AOP mới mẻ này có thể làm cho bạn cảm thấy bối rối. Bạn vẫn chưa kịp nắm
vững OOP giờ lại xuất hiện thêm ‘mốt’ lập trình mới? Bạn đừng lo, OOP
vẫn tồn tại. AOP có thể xem là một sự bổ sung cho OOP, cho phép chúng
ta giải quyết các bài toán phức tạp tốt hơn và hiệu quả hơn.
Vấn đề đan nhau
Hệ thống phần mềm có thể xem như là một thể hiện kết
hợp nhiều vấn đề. Một hệ thống tiêu biểu có thể gồm nhiều dạng vấn đề
như xử lý nghiệp vụ, hiệu suất, bảo toàn dữ liệu, bảo mật, bẫy lỗi… và
còn có những vấn đề của quá trình phát triển hệ thống như tính dễ quản
lý, dễ bảo trì và phát triển. Hình 1a và 1b minh họa hệ thống với tập
các vấn đề đan nhau.
Để hiểu rõ hơn về vấn đề đan nhau, chúng ta hãy xét một
ví dụ đơn giản nhưng khá phổ biến: cập nhật dữ liệu. Giả thiết mục tiêu
quan trọng của hệ thống là nó phải dễ phát triển, bảo trì và đảm bảo an
toàn dữ liệu. Mục tiêu đầu đặt ra từ yêu cầu hệ thống phải phát triển
nhanh và không có lỗi, mục tiêu thứ hai do tính chất quan trọng của dữ
liệu.
Mục tiêu đầu có thể đạt được khá dễ dàng. Có thể dùng
lập trình thủ tục theo kiểu cũ để thực hiện hệ thống mạch lạc, ngắn gọn
và đáp ứng tốt yêu cầu bài toán. Các tác vụ cơ bản của mô đun cập nhật
như sau:
- Nạp dữ liệu.
- Cập nhật dữ liệu.
- Lưu dữ liệu.
Tuy nhiên việc thực hiện đơn giản này không giải quyết
mục tiêu thứ hai. Để đáp ứng cho mục tiêu thứ hai, chúng ta phải thêm
các tác vụ xử lý vấn đề an toàn dữ liệu.
- Xác thực quyền cập nhật dữ liệu.
- Khóa dữ liệu để đảm bảo sự an toàn dữ liệu, đề phòng người khác
truy cập trong khi đang thực hiện cập nhật.
- Nạp dữ liệu.
- Cập nhật dữ liệu.
- Kiểm tra tính toàn vẹn dữ liệu cập nhật
- Ghi nhận lại các thao tác cập nhật.
- Lưu dữ liệu
- Mở khoá dữ liệu
So với ban đầu thì mô đun cập nhật giờ đây khá phức tạp
với nhiều vấn đề liên quan đến những lớp xử lý khác như xác thực, khoá/mở
khoá dữ liệu. Những mô đun xử lý khác như thêm mới hay xóa dữ liệu cũng
có những vấn đề tương tự.
Vấn đề đan nhau làm cho các mô đun phải xử lý đồng thời
nhiều yêu cầu; lập trình viên ngoài việc suy nghĩ về vấn đề xử lý cơ bản
còn phải tính đến vấn đề hiệu suất, bảo mật, an toàn dữ liệu… và sự trộn
lẫn nhiều đoạn mã xử lý những yêu cầu khác nhau. Một vấn đề nữa đó là
tình trạng rải rác mã, do vấn đề đan nhau có ở nhiều mô đun nên các đoạn
mã xử lý liên quan cũng xuất hiện ở nhiều mô đun. Những vấn đề này ảnh
hưởng đến việc thiết kế và phát triển phần mềm, như hệ thống khó xây dựng,
quản lý, phát triển và tính tái sử dụng kém…
Cơ bản về AOP
Hình 1b |
|
Vấn đề cốt lõi của AOP là cho phép chúng ta thực hiện
các vấn đề riêng biệt một cách linh hoạt và kết hợp chúng lại để tạo nên
hệ thống sau cùng. AOP bổ sung cho kỹ thuật lập trình hướng đối tượng
bằng việc hỗ trợ một dạng mô đun khác, cho phép kéo thể hiện chung của
vấn đề đan nhau vào một khối. Khối này được gọi là ‘aspect’ (tạm dịch
là ‘lát’ – hàm ý lát cắt đi qua nhiều lớp đối tượng), từ chữ ‘aspect’
này chúng ta có tên của phương pháp phát triển phần mềm mới: aspect-oriented
programming. Nhờ mã được tách riêng, vấn đề đan nhau trở nên dễ kiểm soát
hơn. Các aspect của hệ thống có thể thay đổi, thêm hoặc xóa lúc biên dịch
và có thể tái sử dụng. Một dạng biên dịch đặc biệt có tên là Aspect Weaver
thực hiện kết hợp các thành phần riêng lẻ lại thành hệ thống hợp nhất.
AOP gồm ba bước phát triển (hình 2a và 2b):
- Phân tích các yêu cầu để xác định vấn đề chung và vấn đề đan nhau.
- Xây dựng thể hiện từng vấn đề riêng biệt.
- Tổng hợp các thể hiện.
Giống như các phương pháp lập trình khác, việc thực hiện
AOP gồm hai phần: đặc tả ngôn ngữ mô tả cú pháp và cấu trúc ngôn ngữ;
biên dịch kiểm tra sự đúng đắn của mã lệnh theo đặc tả ngôn ngữ và chuyển
đổi sang dạng mã máy có thể thực thi.
* Đặc tả ngôn ngữ AOP: Xét ở mức cao, ngôn ngữ AOP gồm
2 thành phần.
- Thể hiện vấn đề: Ánh xạ yêu cầu riêng lẻ ở dạng
mã để trình dịch có thể chuyển đổi sang dạng thực thi. Thể hiện vấn
đề có dạng thủ tục cụ thể, bạn có thể dùng các ngôn ngữ truyền thống
như C, C++ hay Java.
- Đặc tả quy tắc đan kết: Xác định cách thức tổng
hợp các vấn đề riêng lẽ. Muốn vậy, thể hiện cần sử dụng hoặc tạo một
ngôn ngữ để xác định các quy tắc tổng hợp các thể hiện khác nhau.
Ngôn ngữ xác định quy tắc đan kết có thể là sự mở rộng của ngôn ngữ
thể hiện, hoặc một ngôn ngữ hoàn toàn khác.
* Biên dịch AOP: Trình biên dịch AOP thực hiện theo trình
tự hai bước sau:
- Kết hợp các hành vi riêng lẻ
- Chuyển đổi thông tin kết quả sang dạng mã thực thi
Hình 2a |
|
Việc biên dịch ứng dụng AOP có thể thực hiện theo nhiều
cách, trong đó có cách dịch mã sang mã. Theo cách này, mã nguồn được tiền
xử lý các aspect riêng lẻ để tạo ra mã đã được đan kết với nhau. Kế tiếp
trình biên dịch AOP đưa mã đã được chuyển đổi này sang trình biên dịch
ngôn ngữ cơ sở để tạo dạng mã thực thi cuối cùng. Ví dụ, theo cách thức
này, các aspect riêng lẻ của ứng dụng AOP dùng ngôn ngữ Java trước tiên
sẽ được đan kết ở dạng mã nguồn Java, kế tiếp trình biên dịch Java sẽ
chuyển mã nguồn này sang dạng mã thực thi (byte code). Tương tự, cũng
có thể thực hiện đan kết ở giai đoạn mã byte code, byte code vẫn là một
dạng mã nguồn, nếu như hệ thống thực thi chế độ nền – máy ảo java – hỗ
trợ aspect. Với cách này, đầu tiên máy ảo Java sẽ nạp các quy tắc đan
kết, rồi áp dụng các quy tắc này cho các lớp được nạp sau đó. Nói cách
khác, trình biên dịch thực hiện việc đan kết các aspect trong khi thực
thi.
Hình 2b |
|
AOP tổng hợp hệ thống đi từ các vấn đề đan nhau đến vấn
đề chính, còn OOP đi theo hướng ngược lại. Tuy nhiên, OOP và AOP không
phủ định nhau mà bổ sung cho nhau. AOP có thể dùng các kỹ thuật lập trình
khác làm cơ sở, và vẫn giữ được những ưu điểm của hệ thống cơ sở.
Lợi ích của AOP
AOP là một kỹ thuật mới đầy triển vọng, hứa hẹn đem lại
nhiều lợi ích cho việc phát triển phần mềm. Dưới đây là một số lợi ích
cụ thể:
- Mô đun hoá những vấn đề đan nhau: AOP xác định các vấn đề một cách
tách biệt hạn chế tối thiểu việc nhập nhằng mã, cho phép mô đun hoá
cả vấn đề liên quan đến nhiều lớp đối tượng.
- Dễ dàng phát triển hệ thống: Việc thêm chức năng mới có thể thực
hiện dễ dàng bằng cách tạo aspect mới mà không cần quan tâm đến vấn
đề đan nhau. Khi thêm các mô đun mới vào hệ thống, các aspect hiện
có sẽ đan kết với chúng và tạo nên sự phát triển chặt chẽ.
- Cho phép để lại quyết định thiết kế tương lai: Một thiết kế tốt
phải tính đến cả yêu cầu hiện tại và tương lai, việc xác định yêu
cầu tương lai là một công việc khó khăn. Nếu bỏ sót những yêu cầu
tương lai có thể bạn sẽ phải thay đổi hay thực hiện lại nhiều phần
hệ thống. Với AOP, người thiết kế hệ thống có thể để lại các quyết
định thiết kế cho những yêu cầu tương lai nhờ thực hiện theo các aspect
riêng biệt.
- Tái sử dụng mã tốt hơn: Các aspect là những mô đun riêng biệt, được
kết hợp linh động – đây chính là yếu tố quan trọng để tái sử dụng
mã. AOP cho phép tái sử dụng mã tốt hơn OOP.
Lời kết
AOP là một ý tưởng mới, vẫn còn cần thời gian để đánh
giá, tìm hiểu mối quan hệ các kỹ thuật hiện có và để phát triển, ứng dụng
rộng rãi.
Cần nhấn mạnh điều quan trọng là AOP xây dựng trên các
công nghệ hiện hữu. Nó chỉ làm việc với thiết kế tốt. Để có thiết kế tốt,
bạn cần phải áp dụng đúng kỹ thuật cho đúng vấn đề, có thể là AOP, OOP,
phân tích theo chức năng, lập trình cấu trúc…
Giờ thì bạn đã biết về sự tồn tại của AOP. Hãy tìm đọc,
nghiên cứu và áp dụng nó. Hiện có rất nhiều thông tin về AOP trên internet.
Bạn có thể bắt đầu với website Aspect Oriented Software Development (aosd.net).
Thanh Phong
(theo PC World VN)
|