Chương 1 – Lập trình hướng khía cạnh 1. Giới thiệu Hệ thống phần mềm có thể được xem 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. Trong việc thiết kế phần mềm, các nhà thiết kế phần mềm thường tập chung sự quan tâm vào các chức năng chính, cơ bản của hệ thống.
Trong ứng dụng của các doanh nghiệp, đó chính là các logic nhiệp vụ cơ bản. Ví dụ như trong ứng dụng quản lý nhgiệp vụ bảo hiểm, các mô-đun chức năng chính được thiết kế cho việc quản lý các giao dịch bảo hiểm do khách hàng hoặc nhân viên phòng nghiệp vụ thực hiện. Trong ứng dụng quản lý nhân sự, các mô-đun quản lý chính là quản lý hồ sơ nhân viên, tính toán lương và các chế độ cho nhân viên. Trong hai ứng dụng trên, các mô-đun xử lý nghiệp vụ chính có thể được thực hiện riêng rẽ nhưng có những mối quan tâm liên quan đến nhiều mô-đun như tính năng lưu vết, xác thực quyền hạn, truy cập cơ sở dữ liệu, bẫy lỗi, … Các tính năng đó là cần thiết đối với mỗi mô-đun chính của hệ thống và dàn trải trên nhiều môđun của hệ thống.
Các mối quan tâm dàn trải trên nhiều mô-đun của hệ thống đó được gọi là các mối quan tâm cắt ngang (cross-cutting concerns). Do vậy đối với mỗi mô-đun, lập trình viên ngoài việc quan tâm đến những vấn đề cơ bản còn phải tính đến những mối quan tâm cắt ngang và sự trộn lẫn nhiều đoạn mã để xử lý những yêu cầu khác nhau. Sự trộn lẫn nhiều đoạn mã như vậy gọi là vấn đề đan nhau. Do vấn đề đan nhau có ở nhiều mô-đun nên các đoạn 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 vấn đề thiết kế và phát triển phần mềm như hệ thống khó xây dựng, khó quản lý, phát triển và tái sử dụng kém. Lập trình hướng đối tượng (Object-Oriented Programming - OOP) [1, 2, 12] là phương pháp lập trình phổ biến nhất hiện nay được sử dụng để quản lý các mối quan tâm nghiệp vụ chính, tuy nhiên phương pháp này chưa đủ mạnh để xử lý hiệu quả rất nhiều các mối quan tâm cắt ngang hệ thống, đặc biệt là các ứng dụng phức tạp. Phương pháp lập trình hướng khía cạnh (Aspect-Oriented Programming - AOP) [10, 22, 3] là phương pháp lập trình mới 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 cung cấp một dạng mô-đun khác bằng cách kéo các mối quan tâm cắt ngang vào một khối, đó chính là aspect.
Với AOP, ta có thể cài đặt các mối quan tâm cắt ngang hệ thống trong các aspect thay vì dàn trải chúng trên các mô-đun nghiệp vụ chính liên quan. Quá trình bộ đan aspect (weaver) kết hợp các mô-đun nghiệp vụ chính với các aspect thành hệ thống cuối cùng LUAN VAN CHAT LUONG download : add luanvanchat@agmail.com 5 được gọi là quá trình đan (weaving). Như vậy, AOP đã mô-đun hóa các mối quan tâm cắt ngang một cách rõ ràng, tách biệt với các mô-đun nghiệp vụ chính giúp cho việc thiết kế, thực thi và bảo trì hệ thống dễ dàng hơn và tốn ít chi phí, công sức. 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.
Lập trình hướng khía cạnh là kỹ thuật lập trình mới cho phép đóng gói những hành vi liên quan đến nhiều đối tượng và rất có thể sẽ là bước phát triển kế tiếp trong phương pháp lập trình. Tuy nhiên AOP không thay thế OOP mà nó là 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. Trong các phần tiếp theo, chúng ta sẽ khảo sát những vấn đề mà lập trình hướng đối tượng làm tốt và những vấn đề phát sinh từ các đối tượng và làm thế nào AOP có thể lấp khoảng trống này. AspectJ [11, 13, 26], một cài đặt phổ biến của AOP trên ngôn ngữ Java cũng được giới thiệu trong chương này.
Các vấn đề tồn tại trong lập trình hướng đối tượng Phát triển phần mềm đã đi được một quãng đường khá dài. Khi sự hữu ích của phát triển phần mềm được phát hiện, sự cải tiến nó đã trở nên bắt buộc để tìm kiếm các kỹ thuật để mô hình hóa các bài toán của thế giới thực một cách hiệu quả hơn. Nhiều năm trước, phương pháp luận chung cho việc giải quyết một bài toán là chia nó thành các môđun chức năng nhỏ hơn và mỗi chức năng được cấu thành từ nhiều dòng lệnh. Phương pháp luận này đã làm việc tốt nhưng một trạng thái hệ thống được điều khiển bởi một số lượng lớn các biến toàn cục mà chúng có thể được thay đổi bởi bất kỳ dòng lệnh nào trong ứng dụng.
Sự xuất hiện của phương pháp luận hướng đối tượng kéo trạng thái của hệ thống vào các đối tượng riêng lẻ, chúng có thể trở nên riêng tư và được điều khiển thông qua các phương thức truy cập và logic. Kỹ thuật OOP rất xuất xắc trong việc đóng gói các hành vi vào chủ thể lớp (class), miễn là chúng riêng biệt. Tuy nhiên, trong các bài toán thực tế có những hành vi dàn trải trên nhiều lớp. Trong hầu hết các ngôn ngữ lập trình hướng đối tượng truyền thống như C++ [2] hay Java [1, 12] đều không hỗ trợ việc đóng gói các hành vi dàn trải trên nhiều môđun, 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ý.
Hiện tại, OOP được lựa chọn cho hầu hết các dự án phần mềm. Nó tập chung vào giải quyết các nghiệp vụ chính nhưng nó không phải là phương pháp tốt để quản lý các hành vi dàn trải trên nhiều mô-đun. Các mối quan tâm của hệ thống Sự chia tách các mối quan tâm là một nguyên lý cơ bản của kỹ nghệ phần mềm. Nguyên lý này giúp quản lý tính phức tạp của phát triển phần mềm bằng việc khai báo, đóng gói và khai thác các phần của phần mềm liên quan đến một mối quan tâm đặc thù.
Một mối quan tâm (concern) là một yêu cầu cụ thể hoặc một sự cân nhắc nào đó cần phải được đưa ra nhằm thỏa mãn mục đích chung của toàn hệ thống. Một hệ thống phần mềm là việc thực thi tập các mối quan tâm đó. Ví dụ trong một hệ thống quản lý LUAN VAN CHAT LUONG download : add luanvanchat@agmail.com 6 nghiệp vụ bảo hiểm bao gồm việc thực thi các mối quan tâm sau: quản lý khách hàng, quản lý hợp đồng bảo hiểm, tính lãi suất cho các hợp đồng bảo hiểm có yếu tố tiết kiệm, thực hiện chi trả bảo hiểm, tạo báo cáo, xác thực quyền hạn, lưu vết giao dịch, … Bên cạnh các mối quan tâm của hệ thống, một dự án phần mềm cần chỉ ra được các mối quan tâm khác liên quan đến toàn bộ các thuộc tính chất lượng của hệ thống như tính dễ hiểu, dễ quản lý, dễ bảo trì và phát triển. Các mối quan tâm được chia thành hai loại: mối quan tâm chính được cài đặt chức năng chính của một mô-đun và mối quan tâm cắt ngang là yêu cầu ngoài, mức hệ thống và dàn trải trên nhiều mô-đun.
Một ứng dụng của một doanh nghiệp không những quan tâm đến các mối quan tâm nghiệp vụ chính mà còn phải quan tâm đến các mối quan tâm cắt ngang hệ thống như xác thực quyền hạn, lưu vết giao dịch, bẫy lỗi, truy cập tài nguyên chung, đảm bảo tính toàn vẹn của giao dịch, … Tất cả các mối quan tâm này đều cắt ngang một số mô-đun. Ví dụ như mối quan tâm về việc lưu vết giao dịch liên quan đến tất cả các môđun giao dịch chính, mối quan tâm về truy cập dữ liệu liên quan đến các mô-đun có truy xuất cơ sở dữ liệu, mối quan tâm về xác thực quyền hạn liên quan đến các mô-đun có yêu cầu về quản lý quyền truy cập.1 minh họa việc thực thi các mô-đun trong một hệ thống chứa cả các mối quan tâm mức hệ thống và các mối quan tâm nghiệp vụ. Ở đây, một hệ thống được mô tả như một sự tổng hợp của nhiều mối quan tâm. Hệ thống trở nên chồng chéo lên nhau bởi các kỹ thuật cài đặt hiện tại, chính vì thế, sự độc lập giữa các mối quan tâm không được đảm bảo.
Các mối quan tâm trong một hệ thống. LUAN VAN CHAT LUONG download : add luanvanchat@agmail. Giải quyết các mối quan tâm cắt ngang bằng OOP Trong quá trình phát triển phần mềm các nhà phát triển thường xác định các mối quan tâm và sau đó chia tách chúng cho các nhóm phát triển khác nhau để mô-đun hóa chúng. Có những trở ngại lớn cho các nhóm phát triển khi mô-đun hóa các mối quan tâm là làm sao xử lý hiệu quả các mối quan tâm cắt ngang hệ thống.
Trong thực tế, phương pháp OOP thường được sử dụng để mô-đun hóa các mối quan tâm của một hệ thống phần mềm. Tuy nhiên, thực tế thì, mặc dù OOP giải quyết rất tốt trong việc mô- đun hóa các mối quan tâm nghiệp vụ chính nhưng lại gặp khó khăn trong việc mô-đun hóa các mối quan tâm cắt ngang hệ thống. Trong OOP, các mô-đun chính có thể được kết nối lỏng với nhau thông qua giao diện, nhưng không dễ gì làm việc này với các mối quan tâm cắt ngang hệ thống. Lý do chính là một mối quan tâm được thực thi thành hai phần: Phần phía server (phần phục vụ) và phần phía client (phần được phục vụ).
OOP mô-đun hóa phần client khá tốt bằng các lớp và các giao diện. Tuy nhiên, ở phía server, một mối quan tâm lại là một loại cắt ngang hệ thống, bao gồm các yêu cầu gửi đến server, dàn trải trên các client. Thực thi các mối quan tâm cắt ngang bằng OOP. Xét một ví dụ điển hình về việc thực thi một mối quan tâm cắt ngang hệ thống trong OOP: Một mô-đun lưu vết cung cấp các dịch vụ thông qua một giao diện trừu tượng.
Việc sử dụng giao diện nới lỏng kết nối giữa các client và việc thực thi các giao diện. Các client sử dụng các dịch vụ lưu vết thông qua giao diện dành cho hầu hết các phần không quan tâm đến chi tiết cài đặt mà họ đang sử dụng.