Giải pháp thiết kế phần mềm hiệu quả: Kiến trúc hướng khía cạnh AOP

MỤC LỤC

Phương pháp luận của AOP

Ưu điểm của AOP

Khi sử dụng AOP để giải quyết các bài toán chúng ta cần suy nghĩ về thiết kế và thi công hệ thống theo một phương thức mới, với AOP ta sẽ có các ưu điểm sau. Mặc dù AOP có các ưu điểm trên khi thiết kế và thi công một hệ thống,nhưng trên thực tế AOP cũng có một vài đặc điểm gay trở ngại sau. AOP thực ra không giải quyết các vấn đề mới, không giải quyết được vấn đề vẫn chưa được giải quyết.

3 Giới thiệu AspectJ

Một số khái niệm

  • Static crosscutting

    Ví dụ một pointcut có thể chọn một join point là một lời gọi đến một phương thức và lấy thông tin ngữ cảnh của phương thức đó như đối tượng chứa phương thức, các đối số của phương thức đó. Introduction là khái niệm sinh ra để can thiệp vào các cấu trúc tĩnh, trong AOP nó được dùng để xử lý các quan hệ đan xen tĩnh (static crosscutting). Trong AOP chúng ta thường xuyên can thiệp vào các quan hệ đan xen động sử dụng advice, và cũng cần thiết các hành động can thiệp vào các cấu trúc tĩnh.

    Trong khi các concern đan xen động sẽ sửa đổi sự thực hiện các thủ tục của chương trình thì sự đan xen tĩnh sẽ sửa đổi các cấu trúc như class, interface, các aspect khác và các hành vi tại điểm dịch chương trình. Đoạn mã dưới đây mô tả cách giới thiệu 2 thành viên là thuộc tính minimumBalance và phương thức getAvailable() vào lớp Account.

    Một số ứng dựng cơ bản của AOP

    Ví dụ : Aspect khai báo tất cả các class và interface trong gói entities thực thi Identifiable interface.

    4 Giải quyết bài toán với AOP

      Chẳng hạn chúng ta có thể áp dụng AOP cho các module con, sau khi chứng minh được khả năng của AOP, chúng ta sẽ tiếp tục triển khai trên các module tiếp theo. Một quy tắc là xem xét các concern được mô tả với các tính tù hoặc trạng từ bắt đầu với từ “mọi”, ví dụ như mọi ngày, mọi nơi…Nhận biết các concern này ban đầu sẽ giúp chúng ta tránh khỏi việc module hoá các concern đan xen theo phương pháp truyền thống. Thực hiện kiểm tra hiệu năng hệ thống: Rất nhiều vấn đề chỉ được phát hiện ra vào thời điểm triển khai hệ thống.AspectJ cú thể bất chế độ theo dừi hiệu năng cỏc aspect, do đó chúng ta có thể xác định được kết quả gần với các hệ thống thực, và chúng ta có thể quyết định sử dụng aspect hay không trên hệ thống triển khai để tránh tràn bộ nhớ.

      Báo cáo lỗi: Trong quá trình kiểm tra, khi chúng ta phát hiện ra các lỗi thì có thể sử dụng aspect để chỉ ra các ngữ cảnh trong ứng dụng chứ không phải chỉ là ngăn xếp của ngoại lệ được ném ra. • Tạo một bức tường an toàn: Thêm các tính năng mới mà không làm đổ vỡ hệ thống, Các chế độ tăng cường của aspect bảo đảm rằng các tính năng mới không ảnh hưởng đến hệ thống cũng như tạo ra các lỗi mới.

      5 Triển khai một số pattern trên AspectJ

      Các mẫu thiết kế cho việc tạo đối tượng .1 Singleton pattern

      • Prototype pattern
        • Builder pattern

          // Pointcut bảo đảm bất kỳ lớp nào trong cây thừa kế được đánh dấu //là Non Singletons thì không được gộp trong logic của Singleton pointcut excludeNonSingletons( ) : !call((NonSingleton +).new (.));. Các vai trò này được thi công bởi interface nên các aspect trừu tượng có thể làm việc với singleton mà không cần lo lắng về cách thi công chi tiết. Aspect PrototypePattern định nghĩa Prototype interface mà nó có thể ứng dụng cho bất cứ lớp nào trong ứng dụng cụ thể mà nó được là một nguyên mẫu.

          Mẫu thiết kế này được sử dụng khi thao tác trên nhóm các lớp có quan hệ với nhau trong khi nó che giấu sự thực thi các lớp này đối với client. Tạo một factory sử dụng aspect không mang ý nghĩa lắm bởi vì factory chứa các phương thức cụ thể đến các đối tượng có thể được tạo. Ưu điểm duy nhất của AOP đối với pattern này là khả năng loại bỏ sự nương tựa vào một lớp abstract cơ sở cho các abstract factory và thay thế chúng với một interface đơn giản.

          Điều này có nghĩa là các factory cụ thể có thể thừa kế từ lớp thích hợp khác hơn là sử dụng một quan hệ thừa kế được phép để hỗ trợ mẫu thiết kế. Factory method pattern tương tự abstract factory khi nó cung cấp cơ chế mà sự thi công cụ thể của các đối tượng được tách riêng từ các client của factory. Tuy nhiên các kỹ thuật về static crosscutting cung cấp mềm dẻo hơn khi sử dụng pattern này bằng cách loại bỏ lớp trừu tượng cơ sở.

          Các bước này được thi công như những phương thức của lớp builder, sau khi hoàn tất mỗi bước builder có thể được gọi để tạo đối tượng. Phương thức getResult() cung cấp sự truy cập đến trường result mà nó đã được thêm vào interface và các lớp thực thi để cung cấp một nơi lưu giữ các kết quả của builder. Trường result có thể nên khai báo quyền truy xuất là protected để nó chỉ được sử dụng trong bản thân lớp chứa nó và các lớp con của nó.

          Hình 9:Một ứng dụng trước và sau khi được tác động bởi Singleton pattern
          Hình 9:Một ứng dụng trước và sau khi được tác động bởi Singleton pattern

          Các mẫu thiết kế cho cấu trúc của đối tượng

            Mẫu thiết kế này hỗ trợ giảm sự chi tiết của các đối tượng trong hệ thống bằng cách chia sẻ các đối tượng. Mẫu thiết kế này tách riêng một lớp từ các tính chất của một thi công cụ thể mà các lớp thực thi khác có thể áp dụng mà không cần tác động vào các lớp client. Mẫu thiết kế này thừa các hành vi của một lớp trong khi duy trì public interface mà không cần hiểu về lớp hoặc để tâm đến sự mở rộng.

            Mẫu thiết kế này giúp thay đối một thông điệp được gửi từ một đối tượng thành một thông điệp được chấp nhận bởi đối tượng đích. Proxy Pattern cho phép người phát triển cung cấp một đối tượng đại diện cho một đối tượng khác trong trường hợp đối tượng cần được đại diện hoặc được điều khiển. // Without a caller then reject does not really make sense // as there is no way of deciding to reject or not if (delegate(null, subject, thisJoinPoint)).

            Hình 16: Cấu trúc của CompositePattern aspect
            Hình 16: Cấu trúc của CompositePattern aspect

            Các mẫu thiết kế cho hành vi của đối tượng .1 Observer pattern

              Để sử dụng được mẫu thiết kế này đầu tiên chúng ta cần phải xác định được yêu cầu bài toán, cụ thể là cần trả lời những câu hỏi sau. Các đơn hoặc đa thao tác có thể được kết hợp trong một yêu cầu hoặc một giao tác phụ thuộc vào tuỳ từng mục đích của chúng. Khi đối tượng yêu cầu được đã được xây dựng, nó có thể được quản lý như các thực thể tách rời từ đối tượng ban đầu.

              Iterator pattern cung cấp một cơ chế thi công tách biệt nhau của tập hợp các đối tượng, mà qua đó chúng được truy cập một cách tuần tự. Biến lặp hay con trỏ được dịch chuyển theo tập hợp các đối tượng trong khi giấu sự sắp xếp và thi công chi tiết của người dùng với tập hợp đó. Cung cấp một cách thức đồng bộ, nhất quán để duyệt qua các thành phần của trong các danh sách đối tượng mà nó che giấu cách thực hiện thi công của từng danh sách đó.

              Mẫu thiết kế này giúp đơn giản quá trình trao đổi thông tin giữa các đối tượng trong hệ thống bằng các tạo một lớp quản lý các thông điệp phân tán giữa các đối tượng đó. Mẫu thiết kế này có ý nghĩa đúng như tên gọi của nó, được sử dụng để hỗ trợ chuỗi các hành động nối tiếp nhau trong hệ thống. Mẫu thiết kế này cung cấp một cơ chế để trạng thái ban đầu của một đối tượng có thể được phục hồi sau một thời gian mà không cần gắn với một cơ chế cụ thể trong đó trạng thái của đối tượng được thiết lập lại với đối tượng.

              Memento đóng gói tất cả thông tin cần thiết để phục hồi trạng thái nội tại trước của một đối tượng tại thời điểm muộn hơn. Visitor Pattern trong mô hình OOP được sử dụng để thể hiện các hành động được thực hiện trên các thành phần của cấu trúc đối tượng. Với mô hình AOP, điều này không thực sự có ý nghĩa lắm vì bản chất của AOP chính là sự can thiệp vào các cấu trúc và hành vi của đối tượng.

              Strategy pattern cung cấp một cơ chế để tách biệt các lớp client từ sự thi công chi tiết của một thuật toán cụ thể hoặc một chiến lược nào đó. Thường thì tất cả các lớp riêng rẽ mà thi công strategy đã thi công một interface riêng để cho phép client được tách biệt ra với các thi công khác.

              Hình 29:Cấu trúc lớp sau khi áp dụng ObserverPattern
              Hình 29:Cấu trúc lớp sau khi áp dụng ObserverPattern