1 Giới thiệu..........................................................................................................................5 1.1 Mục đích và cấu trúc của tài liệu...............................................................................5 1.

2 Các thuật ngữ.............................................................................................................5 1.3 Hạn chế của các phương pháp lập trình hiện tại........................................................6 2 Các đặc điểm của AOP.....................................................................................................7 2.1 Quản lý các concern hệ thống....................................................................................8 2.2 Phương pháp luận của AOP.....................................................................................11 2.2.1 Ưu điểm của AOP.............................................................................................12 2.2.2 Những nhược điểm...........................................................................................12 2.3 Một số công cụ hỗ trợ làm việc với AOP................................................................12 3 Giới thiệu AspectJ...........................................................................................................13 3.1 Giới thiệu.................................................................................................................13 3.2 Một số khái niệm.....................................................................................................13 3.2.1 Join point...........................................................................................................13 3.2.2 Pointcut.............................................................................................................14 3.2.3 Advice...............................................................................................................15 3.2.4 Introduction.......................................................................................................16 3.2.5 Aspect...............................................................................................................16 3.2.6 Static crosscutting.............................................................................................18 3.3 Một số ứng dựng cơ bản của AOP...........................................................................19 4 Giải quyết bài toán với AOP...........................................................................................19 4.1 Sử dụng AOP trong bước thiết kế............................................................................20 4.2 Sử dụng AOP trong bước thi công...........................................................................20 4.3 Sử dụng AOP trong bước kiếm tra..........................................................................21 4.4 Sử dụng AOP trong giai đoạn bảo trì.......................................................................21 5 Triển khai một số pattern trên AspectJ...........................................................................22 5.1 Các mẫu thiết kế cho việc tạo đối tượng..................................................................22 5.1.1 Singleton pattern...............................................................................................22 5.1.2 Prototype pattern...............................................................................................25 5.1.3 Abstract Factory pattern....................................................................................27 5.1.4 Factory Method pattern.....................................................................................29 5.1.5 Builder pattern..................................................................................................30 5.2 Các mẫu thiết kế cho cấu trúc của đối tượng...........................................................31 5.2.1 Composite pattern.............................................................................................31 5.2.2 Flyweight pattern..............................................................................................35 5.2.3 Bridge Pattern...................................................................................................36

5.2.4 Decorator pattern..............................................................................................37 5.2.5 Adapter pattern..................................................................................................39 5.2.6 Proxy Pattern.....................................................................................................39 5.3 Các mẫu thiết kế cho hành vi của đối tượng............................................................42 5.3.1 Observer pattern................................................................................................42 5.3.2 Command Pattern..............................................................................................45 5.3.3 Iterator pattern...................................................................................................49 5.3.4 Mediator pattern................................................................................................50 5.3.5 Chain of Responsibility Pattern........................................................................52 5.3.6 Memento Pattern...............................................................................................56 5.3.7 Visitor Pattern...................................................................................................58 5.3.8 Strategy pattern ................................................................................................60 5.3.9 State Pattern......................................................................................................62 6 Kết luận...........................................................................................................................64 7 Tài liệu tham khảo..........................................................................................................65

Mục lục hình ảnh Hình 1: Mô hình các concern mức hệ thống........................................................................8 Hình 2: Mô hình ánh xạ yêu cầu người dùng sử dụng AOP................................................9 Hình 3: Mô hình đa chiều về sự phụ thuộc giữa các module với nhau................................9 Hình 4: Mô hình ánh xạ từ các concern hệ thống sang các phương pháp lập trình truyền thống..................................................................................................................................10 Hình 5: Các module yêu cầu logging đều phải nhúng các đoạn mã để gọi logging API. .10 Hình 6: Giải quyết các concern hệ thống bằng phương pháp AOP...................................11 Hình 7: Các giai đoạn phát triển sử dụng phương pháp AOP...........................................12 Hình 8: Cấu trúc của aspect trừu tượng với interface và các hàm được định nghĩa để hỗ trợ Singleton pattern...........................................................................................................23 Hình 9:Một ứng dụng trước và sau khi được tác động bởi Singleton pattern...................24 Hình 10: Các bước thực hiện của mẫu thiết kế Singleton trong ứng dụng........................24 Hình 11: Cấu trúc của PrototypePattern aspect.................................................................25 Hình 12:Một ứng dụng trước và sau khi được tác động bởi Prototype pattern.................26 Hình 13: Sử dụng Prototype pattern trong ứng dụng.........................................................27 Hình 14: Lược đồ UML của AbstractFactory Pattern.......................................................28 Hình 15: Lược đồ UML của factory method pattern.........................................................29 Hình 16: Cấu trúc của CompositePattern aspect................................................................32 Hình 17: Mô hình các đối tượng trước khi áp dụng Composite pattern............................34 Hình 18: Mô hình các đối tượng sau khi áp dụng Composite pattern...............................34 Hình 19: Hoạt động của composite pattern trong ứng dụng..............................................34 Hình 20: Cấu trúc của FlyweightPattern aspect.................................................................35 Hình 21:Cấu trúc của XWindowBridge aspect..................................................................37 Hình 22: Sử dụng các hành vi của lớp Window trong ứng dụng.......................................37 Hình 23: Cấu trúc của DecoratorPattern aspect.................................................................38 Hình 24:Lớp TextDisplay trước và sau khi áp dụng DecoratorPattern ............................38 Hình 25: Áp dụng Adapter pattern.....................................................................................39 Hình 26: Cấu trúc của ProxyPattern aspect.......................................................................39 Hình 27: Cấu trúc của ObserverPattern aspect..................................................................42 Hình 28: Cấu trúc lớp trước khi áp dụng ObserverPattern ...............................................44 Hình 29:Cấu trúc lớp sau khi áp dụng ObserverPattern ...................................................44 Hình 30:Sử dụng ObserverPattern trong ứng dụng...........................................................45 Hình 31: Cấu trúc của CommandPattern và các hàm hỗ trợ pattern..................................45 Hình 32: Trước khi áp dụng CommandPattern .................................................................47

..57 Hình 43: Sử dụng MementoPattern trong ứng dụng..................................56 Hình 42: Cấu trúc của MementoPattern aspect..............54 Hình 41:Sử dụng ChainOfResponsibilityPattern trong ứng dụng...............................................................................................................58 Hình 45: Cấu trúc của Computeur.............................................................................................63 .........................59 Hình 46: Cấu trúc Computeur sau khi áp dụng Visitor pattern..51 Hình 38: Trước và sau khi áp dụng Mediator pattern.................49 Hình 36: Mô tả sự tương tác của EmployeeIteration với ứng dụng..................................................................................................................Hình 33:Trước khi áp dụng CommandPattern ................60 Hình 48:Cấu trúc của StrategyPattern aspect............................................................................................................................................52 Hình 39: Cấu trúc của ChainOfResponsibilityPattern aspect........................50 Hình 37: Cấu trúc của MediatorPattern aspect...............................61 Hình 49: Cấu trúc các lớp sắp xếp khi chưa áp dụng StrategyPattern ........................62 Hình 52: Sử dụng state pattern trong ứng dụng.............................................................62 Hình 50: Cấu trúc các lớp sắp xếp sau khi áp dụng StrategyPattern ......60 Hình 47:Sử dụng VisitorPattern trong ứng dụng...............................................................48 Hình 34: Sử dụng CommandPattern trong ứng dụng...57 Hình 44: Cấu trúc của Visitor pattern aspect.....................................................62 Hình 51: Sử dụng Strategy Pattern trong ứng dụng...................................52 Hình 40: Sau khi áp dụng ChainOfResponsibilityPattern ............................................................................................49 Hình 35: IteratorPatternAspect và interface định nghĩa vài trò của pattern..........................................................................................................

hướng thành phần. các bài báo. Tài liệu nhằm mục đích tìm hiểu mô hình AOP và đi sâu trình bày một trong những kỹ thuật quan trọng của ngành công nghệ phần mềm hiện nay là design pattern trên mô hình AOP Trước khi đọc tài liệu này bạn cần có kiến thức cơ bản về kỹ thuật lập trình hướng đối tượng. mặc dù hiện nay đã có rất nhiều phương pháp tiếp cận như lập trình hướng đối tượng.Chúng cũng đã giải quyết được một số vấn đề nhưng vẫn chưa có một phương pháp nào thoả mãn việc giải quyết các yêu cầu đan xen ở mức hệ thống. AOP không phát minh và điều gì mới mà chỉ giải quyết các vấn đề đã tồn tại theo cách tốt hơn. cú pháp và các khái niệm của AspectJ. cụ thể là triển khai trên cú pháp của AspectJ. . 1. các kiến trúc của phần mềm.1 Mục đích và cấu trúc của tài liệu Tài liệu này được tổng hợp từ nhiều nguồn khác nhau (xem phần tài liệu tham khảo). các mẫu thiết kế. giới thiệu một phiên bản thi công của nó là AspectJ. từ mục 1 đến 5: Trình bày các vấn đề cơ bản về AOP.2 Các thuật ngữ Trước khi đi vào tìm hiểu về AOP (một phương pháp lập trình mới) chúng ta cần hiểu một số thuật ngữ trong ngành công nghệ phần mềm hiện nay. Tài liệu được chia thành 2 phần chính sau Phần thứ nhất. Các nhà nghiên cứu lý thuyết đã đưa ra mô hình AOP để giải quyết các vấn đề mà các mô hình lập trình hiện tại chưa đáp ứng được hoặc đáp ứng được nhưng việc thực hiện nó quá phức tạp. Ngoài ra trong phần này. bao gồm các cuốn sách. Phần thứ 2. tài liệu cũng đề cập đến các ứng dụng thích hợp cho việc áp dụng AOP. các luận văn …về vấn đề nghiên cứu và ứng dụng AOP trong ngành công nghệ phần mềm.1 Giới thiệu Việc chuyển đổi các yêu cầu của người dùng vào trong một hệ thống phần mềm bao giờ cũng rất khó khăn.. các yêu cầu này được mô tả bằng khái niệm crosscutting concern. … trong ngành công nghệ phần mềm hiện nay.. các design pattern . (How to do the bad things in better way) 1. Đồng thời cũng cần kinh nghiệm thực tế về những khó khăn mà các phương pháp lập trình hiện tại đang gặp. từ mục 6 đến hết: Trình bày cách triển khai các mẫu thiết kế (design pattern) đã được sử dụng trong mô hình OOP sang mô hình AOP.

Là lớp trung gian trong các hệ thống phần mềm . Net Framework của Microsoft Mô hình lập trình hướng tương quan Là giải pháp thực hiện khi thiết kế các ứng dụng nhằm đảm bảo chất lượng. Có lẽ các câu hỏi thường gặp nhất trong ngành công nghệ phần mềm hiện nay là:Thiết kế một phần mềm như thế nào được gọi là đủ? Các hệ thống tốt cần xem xét đến những yêu cầu hiện tại và cả những yêu cầu tiềm tàng trong tương lai. Singleton. Proxy. hệ thống phình ra không mong muốn. tính trong sáng của mã chương trình. Sự lơ là các yêu cầu trong tương lai có thể dẫn đến thay đổi nhiều phần của hệ thống hoặc có thể phải xây dựng lại.crosscutting concerns refactoring middleware AOP design pattern Chỉ các quan hệ giữa các module trong một hệ thống phần mềm.3 Hạn chế của các phương pháp lập trình hiện tại Có lẽ khái niệm về AOP hiện nay đã được nhiều người biết đến. tăng tính mềm dẻo. Một số pattern hay được sử dụng như IOC (Inversion of Control). khó hiểu. Hay nói một cách khác. vì vậy ở đây ta chỉ trình bày lại ngắn gọn các khái niệm cơ bản và các đặc điểm chính của AOP Để trả lời được câu hỏi AOP là gì? Tại sao phải có AOP? Chúng ta cần bắt đầu tìm hiểu sự hạn chế của của các phương pháp lập trình hiện tại trong việc đáp ứng các yêu cầu ngày càng phức tạp của các hệ thống phần mềm. các thiết kế có khả năng đáp ứng nhu cầu cho tương lai kém có thể dẫn đến hiện tượng “tràn thiết kế”. Một số middleware tiêu biểu như EJB của Sun. mở rộng chức năng của chương trình đồng thời mã chương trình dễ hiểu hơn cho người đọc. Abstract Factory Class 1. Refactoring là một kỹ thuật trong công nghệ phần mềm mà mã nguồn chương trình được cấu trúc lại nhằm đảm bảo tính mềm dẻo. . Từ đó hình thành một yêu cầu có một thiết kế có thể đáp ứng được các yêu cầu trong tương lai mà không ảnh hưởng đến chất lượng.

Các đối tượng trong OOP hoạt động theo qui trình: Sinh-Hoạt động-Tử. Với AOP. cài đặt. bạn phải thay đổi tất cả các yêu cầu nghiệp vụ liên quan. Ở đây. Lấy ví dụ: Bạn cần xử lý nghiệp vụ truy xuất dữ liệu. Lưu vết. các quan hệ cơ bản sử dụng các phương pháp cơ bản. Tuy nhiên. phát triển. thay đổi yêu cầu của bài toán phần mềm. hoặc bỏ qua các yêu cầu phát triển tương lai  hệ thống thiếu tính khả mở. bạn phải cân nhắc giữa dự đoán trước các yêu cầu phát triển  Phát triển phần mềm nặng nề. nhược điểm thứ hai là: Một hệ thống thực tế là sự đan xen nhau giữa các yêu cầu. Kết quả là việc thực thi của từng concern tiến triển một cách độc lập. thường thì cần bổ sung vào các yêu cầu: Chứng thực. phân tích. Trong bản thiết kế. Chúng sẽ qui định cách các module khác nhau gắn kết với nhau để định hình lên hệ thống cuối cùng. giải quyết được nó tức bạn đã giải quyết được tính tiến hoá. khó bảo trì. 2 Các đặc điểm của AOP AOP được xây dựng trên các phương pháp lập trình hiện tại như OOP và lập trình có cấu trúc. tính tiến hoá cũng bị ảnh hưởng.. bạn có thể phân công trách nhiệm này cho một object cụ thể nào đó và vấn đề này rất bình thường. kiểm thử đến các hệ quản trị cơ sở dữ liệu . Nhưng sự mô phỏng này chỉ dừng ở mức tĩnh. Theo OOP. ảnh hưởng đến tất cả các pha từ xác định yêu cầu. Bảo mật. bạn phải bổ sung code cho các yêu cầu nêu trên. . Vì khi cần bổ sung thêm một nghiệp vụ nào khác. bổ sung các khái niệm và cấu trúc để module hoá các quan hệ đan xen. thường thì một object có một chu kỳ sống: Sinh-Hoạt động-Phát triển-Tử. Như vậy trong method TruyXuatDuLieu() của một đối tượng được chỉ định nào đó. Nhưng cùng với yêu cầu nghiệp vụ trên.Việc thực thi của từng quan hệ của AOP bỏ qua các hành vi được tích hợp vào nó. thiết kế. người ta nhận thấy OOP modul hoá yêu cầu theo kiểu mô phỏng một đối tượng (object) trong thế giới thực.. bussiness module sẽ không quan tâm nó cần được log hoặc xác thực như thế nào.. nhưng ở thế giới thực.. Các aspect trong hệ thống đóng gói các quan hệ đan xen lại với nhau.. Phân quyền. Ví dụ.Phương pháp lập trình OOP hiện tại đã tạo ra một cuộc cách mạng lớn trong công nghệ phần mềm. Tình trạng này. nếu sử dụng OOP sẽ thực thi các quan hệ cơ bản dưới hình thức lớp. tiến hoá. Nhược điểm trên của OOP là thấy rõ nhất. 'Phát triển' là điều quan trọng. Nền tảng cơ bản AOP khác với OOP là cách quản lý các quan hệ đan xen. Nó làm nên một hệ thống lộn xộn. người ta gọi là sự chồng chéo giữa các yêu cầu..

storage management. authencication tác động tới module có yêu cầu kiểm soát truy cập Hình 1: Mô hình các concern mức hệ thống Việc xác định được các concern trong hệ thống.1 Quản lý các concern hệ thống Concern là các yêu cầu cụ thể hay mối quan tâm đặc trưng được xác định để thoả mãn mục tiêu chung của hệ thống. logging tác động tới tất cả module trong hệ thống. logging. Ví dụ. error checking… Các concern được phục vụ cho một vài module. dễ bảo hành và duy trì. . multithread safety. xác nhận truy cập các dịch vụ. transaction integrity. Hệ thống phần mềm là sự gắn kết của tập các concern. chăm sóc khách hàng. Concern được chia làm hai loại 1. Concern đan xen: Thể hiện các quan hệ ràng buộc giữa các module trong hệ thống Một ứng dụng doanh nghiệp điển hình có thể bao gồm các concern đan xen sau: authentication. 2. chúng ta sẽ tập trung vào các concern một cách độc lập và sẽ giảm độ phức tạp của hệ thống. Ví dụ. data persistence. performance. Concern thành phần: Thể hiện các chức năng nội tại của một module. security. các giao dịch nội ngân hàng. …Ngoài ra một phần mềm còn phải đảm bảo khả năng dễ hiểu. resource pooling. các giao dịch ATM. lưu giữ các thực thể trong hệ thống. hệ thống ngân hàng bao gồm các concern sau đây: quản lý khách hàng và quản lý tài khoản. dễ phát triển.2.

Hình 2: Mô hình ánh xạ yêu cầu người dùng sử dụng AOP Hình 3: Mô hình đa chiều về sự phụ thuộc giữa các module với nhau Các concern đan xen nhau giữa các module. Hình sau minh hoạ sự thực hiện này: Với mô hình biểu diễn nhiều chiều của các concern được ánh xạ trên các ngôn ngữ một chiều như sau. . các kỹ thuật thi công hiện tại sẽ trộn chúng vào một module.

Ngay cả khi bạn có một bản thiết kế tốt của logging module như: cung cấp các API trừu tượng (Abstract API). Hình 5: Các module yêu cầu logging đều phải nhúng các đoạn mã để gọi logging API Đây chính là vấn đề sẽ được giải quyết bằng AOP. nhưng khi gặp concern mức hệ thống thì OOP không đáp ứng được yêu cầu. sử dụng AOP các module khác không cần chứa đoạn mã gọi logging API. giấu cách định dạng log message…Các module còn lại vẫn cần phải nhúng các đoạn mã để gọi các logging API. Hình 7 chỉ ra cách thực hiện module logging .Hình 4: Mô hình ánh xạ từ các concern hệ thống sang các phương pháp lập trình truyền thống Trong thiết kế phần mềm cách tốt nhất để đơn giản các hệ thống phức tạp là xác định các concern rồi module hoá chúng. OOP được thiết kế để phục vụ việc module hoá các concern cơ bản. Hình sau minh hoạ một ví dụ thiết kế dùng phương pháp truyền thống.

kết hợp lại để thành hệ thống cuối cùng. Tuy nhiên cộng đồng nghiên cứu AOP đề xuất ba bước thực hiện sau: 1. thực hiện chúng. sử dụng các thông tin trong aspect để cấu thành hệ thống đích . cách thực hiện log bây giờ chỉ tồn tại trong logging module và logging aspect. Quá trình này còn được gọi là quá trình dệt mã. Với phương pháp module hoá này bất cứ sự thay đổi yêu cầu nào về logging chỉ ảnh hưởng duy nhất đến logging aspect.2 Phương pháp luận của AOP Việc phát triển các hệ thống sử dụng AOP tương tự như phát triển các hệ thống sử dụng các phương thức khác: xác đinh concern. Như vậy các yêu cầu đan xen giữa logging module và các module khác được thực hiện duy nhất trong một module hay logging aspect. Concern Implementation: Thực thi các concern một cách độc lập 3. như đã được chỉ ra trên hình vẽ. Các concern lõi được tách ra khỏi các concern đan xen. 2. Aspectual decomposition: Trong bước này chúng ta phân tách các yêu cầu nhằm xác định các concern lõi và concern đan xen. Aspectual Recomposotion: Trong bước này chúng ta chỉ ra các quy lật kết hợp bằng cách tạp ra các aspect.dùng AOP có cùng chức năng với cách sử dụng OOP. Các modulek khác không chứa bất kỳ đoạn mã nào gọi đến logging API. Hình 6: Giải quyết các concern hệ thống bằng phương pháp AOP 2.

AOP thực ra không giải quyết các vấn đề mới. C.2 Những nhược điểm 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. Tăng khả năng sử dụng lại mã 6. AOP giải quyết các bài toán theo cách tốt hơn 2. không giải quyết được vấn đề vẫn chưa được giải quyết.org Aspectwerkz. Giảm thời gian thi công hệ thống 7. Giảm giá thành của sản phẩm 2.nhưng trên thực tế AOP cũng có một vài đặc điểm gay trở ngại sau 1.. AspectWerkz 3. AspectJ 2. Python. Tách biệt chức năng hơn của các module độc lập 2. Phát triển hệ thống dễ dàng hơn 4.3 Một số công cụ hỗ trợ làm việc với AOP AOP hiện nay đã được nghiên cứu và áp dụng vào hầu hết các ngôn ngữ như Java.Hình 7: Các giai đoạn phát triển sử dụng phương pháp AOP 2.org .2. Tên dự án 1. AOP phá vỡ tính đóng gói (encapsulation) 2.codehaus. PHP .2. với AOP ta sẽ có các ưu điểm sau 1. Tính module hoá cao hơn 3. Jboss AOP Địa chỉ Aspectj.org Jboss. AOP không là cứu cánh cho các thiết kế cẩu thả 3. Kết nối muộn thiết kế 5.1 Ư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. C#.

6. AspectJ định nghĩa 2 loại concern: 1. aspect). Trong AspectJ mọi thứ đều xoay quanh join point. 5... Phần đặc tả ngôn ngữ sẽ chỉ ra cách viết code. 2. các concern hệ thống được thực hiện bởi AspectJ. AspectJ đã được plugin vào công cụ phát triển Eclipse (eclipse. với AspectJ các concern cơ bản được viết bằng Java. interface.1 Join point Join point là một khái niệm cở bản của AspectJ.net Aspectc. hầu hết các concern đan xen trong AspectJ là concern đan xen động.2 Một số khái niệm Như đã biết mục đích của AOP là module hoá các concern đan xen nhau. 3. public class Account { .objectweb. với sự mở rộng này mã chương trình viết bằng Java sẽ tương thích với chương trình viết bằng AspectJ.org Jac.org Aspectsharp. Nghĩa là khi chúng ta thực hiện một thay đổi đến các cấu trúc dữ liệu tĩnh để đáp ứng các yêu cầu của bài toán. concern đan xen động (dynamic crosscutting): là sự gắn kết các hành vi mới vào chương trình.1 Giới thiệu AspectJ là sự mở rộng theo mô hình AOP của ngôn ngữ Java. AspectJ sử dụng dự mở rộng của Java để chỉ ra các luật gắn kết cho concern tĩnh và concern động. 7. Có thể là lời gọi đến một phương thức hoặc một lệnh gán cho một biến của đối tượng.2.sourceforge. Sping AOP Aspect# AspectC++ JAC www. void credit(float amount) { . concern đan xen tĩnh (static crosscutting): Là sự gắn kết thay đổi trong một cấu trúc tĩnh (class.org 3 Giới thiệu AspectJ 3.org) và được đánh giá là sản phẩm tốt nhất hiện nay về AOP 3.4. Join point có thể là bất kỳ điểm nào có thể xác định được khi thực hiện chương trình. AspectJ bao gồm hai phần: đặc tả ngôn ngữ và phần thực thi.spring framework.

} } 3. OverdraftManager.out...balance + = amount.).debit(amount)..2 Pointcut Pointcut là một cấu trúc chương trình mà nó chọn các join point và ngữ cảnh tại các joint point đó. } • join point tại các advice: public aspect MannersAspect { before() : deliverMessage() { System. } } Join point được phân loại như sau • • • • join point tại các phương thức join point tại hàm dựng (contructor) join point tại điểm truy cập các thuộc tính join point tại điểm điều khiển ngoại lệ: Được biểu diễn trong khối điều khiển ngoại lệ try { account. 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.print("Hello! "). _logger.applyOverdraftProtection(account..log(.2. Cú pháp của pointcut được khai báo như sau: [access specifier] pointcut pointcut-name([args]) : pointcut-definition .. amount). . } catch (InsufficientBalanceException ex) { postMessage(ex). } } public aspect LoggingAspect { after() : loggedOperations() { .. các đối số của phương thức đó.

thực hiện tiếp của mã nguồn ban đầu hoặc thực hiện thay đổi ngữ cảnh (tham số của hàm.println("Performing operation on " + connection).Ví dụ: execution(void Account.) throws SQLException)&& target(connection).2. Pointcut và advice sẽ hình thành nên các luật đan kết các quan hệ đan xen. before: Được thực hiện trước join point 2. advice này có thể thực hiện vòng.creadit(float)) Bảng ánh xạ giữa các join point được chọn cho các point cut Thực hiện phương thức Gọi phương thức Thực hiện hàm dựng Gọi hàm dựng Khởi tạo class Đọc thuộc tính Ghi thuộc tính Thực hiện điều khiển ngoại lệ Khởi tạo đối tượng Tiền khởi tạo đối tượng Thực hiện advice execution(MethodSignature) call(MethodSignature) execution(ConstructorSignature) call(ConstructorSignature) staticinitialization(TypeSignature) get(FieldSignature) set(FieldSignature) execution handler(TypeSignature) initialization(ConstructorSignature) preinitialization(ConstructorSignature) adviceexecution() 3.*(.3 Advice Là mã được thực hiện tại một join point mà đã được chọn bởi pointcut. Advice tương tự cấu trúc của hàm cung cấp các thức các hành động đan xen tại các join point mà nó được chọn bởi point cut. around: Bao quanh sự thực hiện join point.. after: Được thực hiện sau join point 3. } Object around(Connection connection) throws SQLException . …) Giả sử ta có pointcut được khai báo như sau pointcut connectionOperation(Connection connection) : call(* Connection. Advice được chia thành 3 loại sau 1. Ta có thể xây dựng các advice như sau: before(Connection connection):connectionOperation (connection) { System.out.

advice.out.: connectionOperation (connection) { System. interface.2. Ví dụ có thể thêm một phương thức hoặc một trường vào lớp nào đó hoặc sửa đổi cấu trúc thừa kế của một đối tượng. Nó tạo ra sự thay đổi tĩnh đến các module mà không trực tiếp ảnh hưởng đến các hành vi của module đó.out. trong AOP nó được dùng để xử lý các quan hệ đan xen tĩnh (static crosscutting). Aspect chứa mã thể hiện các luật đan kết cho concern. Ví dụ khai báo sau sẽ sửa đổi cấu trúc thừa kế của đối tượng Account. System..println("Operation " + thisJoinPoint + " on " + connection+ " started System. giống như class trong Java.2. declare parents: Account implements BankingEntity. Introduction là khái niệm sinh ra để can thiệp vào các cấu trúc tĩnh.5 Aspect Aspect là phần tử tập trung của AspectJ. 3.println("Operation " + thisJoinPoint + " on " + connection + " completed at " + System. 3. pointcut.currentTimeMillis()). proceed(connection).currentTimeMillis()). } at " + Nếu trong around advice muốn thực hiện thao tác tại join point. introduction được kết hợp trong aspect. phải sử dụng từ khoá proceed(). Join point. Chúng ta sẽ đề cập đến vấn đề này trong phần static crosscutting.4 Introduction Introduction là một lệnh chỉ ra sự thay đổi đến một class.. aspect body } . Aspect được khai báo theo mẫu sau [access specification] aspect <AspectName> [extends class-or-aspect-name] [implements interface-list] [<association-specifier>(Pointcut)] { . aspect.

save(Object)) : "Consider using Persistence. protected . aspect cũng có một số đặc điểm khác so với class như sau: • • • Aspect không thể khởi tạo trực tiếp Aspect không thể thừa kế từ một aspect khác (không phải trừu tượng) Aspect có thể được đánh dấu như quyền .Ví dụ sau khai báo một aspect: public aspect ExampleAspect { before() : execution(void Account.getLogger("banking"). "Before: " + thisJoinPoint).. before() : logPoints() { getLogger(). public Logger getLogger() { return Logger. } } • Aspect có thể nhúng trong class và interface như một aspect nằm trong Ngoài các tính chất tương tự class như trên.out.)). } Một số tính chất của khái niệm aspect tương tự khái niệm class • • • Aspect có thể chứa các thuộc tính và phương thức Aspect chứa các thuộc tính truy cập: private.credit(float)) { System. public abstract Logger getLogger().*(. abstract aspect và thi công các interface public aspect BankLogging extends AbstractLogging { public pointcut logPoints() : call(* banking. Aspect có thể khai báo như một aspect trừu tượng: public abstract aspect AbstractLogging { public abstract pointcut logPoints()..log(Level.. declare warning : call(void Persistence.INFO.println("About to perform credit operation").saveOptimized()". } } • Aspect có thể thừa kế class. public. } declare parents: Account implements BankingEntity.

1 Giới thiệu thành viên Aspect thường xuyên giới thiệu các thành viên hoặc các phương thức vào trong một lớp aspect .6. Đ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. interface. AspectJ có thể sửa đổi cây thừa kế của ..3. Ví dụ từ khoá private chỉ ra thành viên chỉ được truy cập từ aspect giới thiệu nó. 3._minimumBalance. 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. } after(Account account) : execution(SavingsAccount.debit())&& this(account) && args(amount) { if (account. Các thành viên được giới thiệu vào một lớp cũng có thể được chỉ ra quyền truy nhập như khai báo các thành viên của một lớp. public aspect MinimumBalanceRuleAspect { private float Account.6 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. } before(Account account.2.6. các aspect khác và các hành vi tại điểm dịch chương trình. float amount)throws InsufficientBalanceException : execution(* Account.getAvailableBalance() { return getBalance() . public float Account._minimumBalance = 25.getAvailableBalance() < amount) { throw new InsufficientBalanceException( "Insufficient available balance").new(.2.2._minimumBalance. 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.2 Sửa đổi cấu trúc thừa kế Khi thực thi các quan hệ đan xen thường xuyên cần tác động đến tập các class hoặc interface mà chúng có chung một kiểu cơ sở. } } 3.)) && this(account) { account. AspectJ cung cấp một có chế được gọi là introduction để giới thiệu các thành viên vào trong các class hoặc interface.

. Tối ưu hóa (resource pooling và caching): Khái niệm resource pooling và caching chúng ta thường xuyên phải sử dụng trong các tình huống muốn tối ưu hóa ứng dụng.. Vì các chức năng này xuyên suốt qua các module của ứng dụng nên khi triển khai các kỹ thuật này với AOP là một cách tiếp cận tốt nhất có thể 2. 4 Giải quyết bài toán với AOP Trong phần này chúng ta sẽ xem xét một số bài toán và một số giải pháp thực tiễn để giúp một ứng dụng triển khai được trên AOP.một lớp đã tồn tại để khai báo các lớp cha hoặc các interface của lớp đó miễn là không ảnh hưởng đến qui luật thừa kế của Java.. tracing. Việc áp dụng một công nghệ mới để giải . Các kỹ thuật điều khiển. tracking advices } 3. giám sát (monitor): Các kỹ thuật điều khiển. thời gian giao dịch. Ví dụ trong hệ thống nhà băng người quản trị muốn theo dõi thông tin mỗi giao dịch trong hệ thống như tên tài khoản. profiling là những kỹ thuật chung để hiểu được các hành vi xảy ra trong hệ thống..3 Một số ứng dựng cơ bản của AOP Dưới đây là một số ứng dụng điển hình sử dụng các ưu điểm của AOP trong việc thiết kế và triển khai 1. Ví dụ : Aspect khai báo tất cả các class và interface trong gói entities thực thi Identifiable interface. tuân theo một số luật cụ thể. giám sát như logging. Tăng cường chính sách (policy enforcement): Là một cơ chế bảo đảm các thành phần trong hệ thống phải theo các quy tắc lập trình thực tế. aspect AccountTrackingAspect { declare parents : banking. Mẫu khai báo như sau: declare parents : [ChildTypePattern] implements [InterfaceList]. Ví dụ bạn không thể gọi đến thư viên xử lý giao diện AWT trong mã của EJB được.* implements Identifiable.entities. 3. declare parents : [ChildTypePattern] extends [Class or InterfaceList].

test và bảo trì đều nhấn mạnh tới một số hành động. ví dụ như mọi ngày. Thực thi các concern lõi . thi công. 4. 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. chúng ta sẽ tiếp tục triển khai trên các module tiếp theo. Nhận biết các concern đan xen: Bước này là một phần trong việc ánh xạ các yêu cầu người dùng tới các module. Cần phải xem xét khả năng tối thiểu các rủi ro của hệ thống.1 Sử dụng AOP trong bước thiết kế Nếu sử dụng AOP trong bước thiết kế chúng ta sẽ có được nhiều sự thuận lợi mà AOP đem lại. Chẳng hạn chúng ta có thể áp dụng AOP cho các module con. Từ quan điểm về kiến trúc. Thiết kế các concern lõi trước: Áp dụng các quy tắc và phương pháp truyền thống để thiết kế các concern lõi. đặc biệt khi bạn còn chưa nhìn thấy một hệ thống nào triển khai thành công với công nghệ mới này. sự thuận lợi chính là giúp chúng ta vượt qua sự bế tắc của các kiến trúc hiện tại. sau khi chứng minh được khả năng của AOP. dễ thấy. Cũng như cần theo một số chỉ dẫn để việc thi công các concern lõi và concern đan xen dẽ nhất có thể. Sau đây là một số bước điển hình sử dụng AOP trong pha thiết kế 1. 2. Chúng ta sẽ tìm hiểu cách sử dụng mô hình hướng aspect như thế nào để giải quyết bài toán và các giải pháp về thiết kế. 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”.2 Sử dụng AOP trong bước thi công Khi sử dụng AOP trong bước thi công bạn nên nhấn mạnh vào trên một vài thực tiễn có tính chất chung. Mỗi pha trong quá trình phát triển phần mềm: thiết kế. Thiết kế các concern đan xen: Xác định các concern đan xen cần thiết. Công việc này càng làm tốt thì việc áp dụng các concern đan xen sau này càng dễ. ta cần xác định tính thích hợp cho mỗi vấn đề khác nhau.quyết bài toán không bao giờ dễ dàng. Lên một bộ khung cho các concern bạn cần và cũng có thể cả các concern bạn chưa cần ngay lập tức. 4. Một khi thực sự chắc chắn muốn sử dụng AOP trong hệ thống phần mềm nào đó. Cũng có một số phương pháp refactoring theo mô hình AOP bạn có thể sử dụng 1. 3.

3. d. Xác định các join point: Bước này cần xác định các vị trí trong mã chương trình cần cho các quan hệ đan xen. b. do đó chúng ta có thể xác định được kết quả gần với các hệ thống thực. 2. Xem xét bất kỳ sự rải rác và chồng chéo mã chương trình 2. Viết các concern lõi theo mô hình refactoring tốt nhất. c. Tạo các test case: Do AspectJ có khả năng sửa đổi các hành vi mà không cần sự thay đổi thực sự nên AspectJ có thể trợ giúp để viết các chương trình kiểm tra.3 Sử dụng AOP trong bước kiếm tra AspectJ có thể trợ giúp nhiều nhiệm vụ trong bước kiếm tra. Thiết kế các aspect 3. 4. 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 AspectJ có thể điều khiển 2 bước sau trong giai đoạn bảo trì . Sử dụng cách đặt tên nhất quán xuyên suốt ứng dụng Tách biệt các concern đan xen từ các module trong bước đầu tiên. 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. Lựa chọn các kỹ thuật sử dụng ở lớp dưới c.AspectJ có thể bất chế độ theo dõi hiệu năng các aspect. Báo cáo lỗi: Trong quá trình kiểm tra. Thực hiện refactoring các aspect 4. Thực thi các concern đan xen a. Sau đây là một kịch bản điển hình mà chúng ta có thể bắt đầu thực hiện với AspectJ 1. 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. 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ớ.4 Sử dụng AOP trong giai đoạn bảo trì Giai đoạn bảo trì hệ thống bao gồm hai thao tác chính sau • • • Thêm mới tính năng cho các yêu cầu mới Sửa các lỗi được tìm thấy 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.a. Tiếp theo cần quyết định cách tốt nhất để thể hiện các pointcut mà chúng sẽ chọn các join point b.

1. 5.1 Giới thiệu Singleton pattern là một mẫu thiết kế để đảm bảo trong một phiên làm việc của ứng dụng chỉ có duy nhất một thể hiện ( instance) của đối tượng vào lúc chạy. Ralph Johnson. Với mô hình lập trình hướng aspect. “Design Patterns: Elements of Reusable Object-Oriented Software” được biên soạn bởi Erich Gamma. bao gồm: các mẫu thiết kế về cấu trúc đối tượng.1 Các mẫu thiết kế cho việc tạo đối tượng 5. public interface Singleton { } public interface NonSingleton { } . tăng hiệu năng chương trình.1. Các mẫu thiết kế trong quyển sách này được chia thành 3 loại. tái sử dụng mã. các mẫu thiết kế được xây dựng với một số đặc điểm mới nhằm tận dụng được những ưu điểm của phương pháp mới này.• Thực thi các tính năng mới: AspectJ có thể thêm các quan hệ đan xen mới mà không thay đổi trực tiếp trên mã nguồn gốc 5 Triển khai một số pattern trên AspectJ Mẫu thiết kế (design pattern) được sử dụng rất nhiều khi phát triển một phần mềm. Đối tượng không được khởi tạo trực tiếp trong chương trình (các hàm khởi tạo của đối tượng được khai báo với từ khoá private) mà sẽ truy xuất qua một hàm static để trả về thể hiện duy nhất của đối tượng.1. và tạo lập đối tượng. và John Vlissides là một cuốn sách về design pattern đã được công nhận chính thức như một tài liệu thực tiễn cho mô hình lập trình hướng đối tượng (OOP).1 Singleton pattern 5. nó giúp người phát triển giải quyết các vấn đề như điều khiển đối tượng. hành vi đối tượng. public abstract aspect SingletonPattern issingleton( ) { private Hashtable singletons = new Hashtable( ). Mẫu thiết kế này thường được sử dụng để quản lý thông tin của một phiên làm việc của một ứng dụng. Các mẫu thiết kế được thực thi dựa trên cơ chế của các ngôn ngữ lập trình hướng đối tượng đang có. Richard Helm.

get(singleton) == null) { singletons..// Pointcut định nghĩa các đối lớp cto define specify an interest in all creations // of all Classes that extend Singleton pointcut selectSingletons( ) : call((Singleton +). Hình 8: Cấu trúc của aspect trừu tượng với interface và các hàm được định nghĩa để hỗ trợ Singleton pattern . proceed( )).put(singleton.new (. } } return (Object) singletons. Object around() : selectSingletons() && excludeNonSingletons( ) { Class singleton = thisJoinPoint.get(singleton).getDeclaringType( ). } } Aspect trừu tượng Singleton định nghĩa 2 vai trò: Singleton và NonSingleton.))..new (. // 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 +). synchronized(singletons) { if (singletons. 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.)).getSignature().

declare parents: SpecializedPrinter implements NonSingleton. lần đầu khi instance của Printer chưa có. nó sẽ được khởi tạo lần đầu. Lần tiếp theo khi instance đã tồn tại.5.2 Sử dụng Sau đây là ví dụ chỉ ra aspect SingletonPattern được sử dụng trong ứng dụng: Hình 9:Một ứng dụng trước và sau khi được tác động bởi Singleton pattern public aspect PrinterSingleton extends SingletonPattern { declare parents: Printer implements Singleton. } Hình sau minh hoạ hoạt động của ứng dụng khi gọi hàm in 2 lần.1. hàm in sẽ lấy tham chiếu đến instance đã được khởi tạo ở bước đầu tiên. Hình 10: Các bước thực hiện của mẫu thiết kế Singleton trong ứng dụng .1.

} } protected Object createCloneFor(Prototype object) { return null.clone( ).2 Prototype pattern 5.1.1. Những lớp này sẽ thừa kế với hàm clone() để hỗ trợ việc sao chép đối tượng.1 Giới thiệu Prototype pattern được sử dụng hỗ trợ sao chép một đối tượng dựa trên đối tượng gốc. public abstract aspect PrototypePattern { protected interface Prototype { } public Object Prototype. } public Object cloneObject(Prototype object) { try { return object. Hình 11: Cấu trúc của PrototypePattern aspect . } } 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.clone( ).clone() throws CloneNotSupportedException { return super.2.5. } catch (CloneNotSupportedException ex) { return createCloneFor(object).

} else if (object instanceof Staff) { return new Staff(((Staff) object). ((Staff) object).getX().getY( )).2. } else { return null.getX( ). protected Object createCloneFor(Prototype object) { if (object instanceof MusicalNote) { return new MusicalNote(((MusicalNote) object).1.getY( )).5. declare parents : MusicalNote implements Prototype. declare parents : Staff implements Prototype.2 Sử dụng public aspect GraphicPrototypes extends PrototypePattern { declare parents : Graphic implements Prototype. ((MusicalNote) object). } } } Hình 12:Một ứng dụng trước và sau khi được tác động bởi Prototype pattern .

3.3 Abstract Factory pattern 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. Theo mô hình lập trình OOP thì factory pattern cung cấp các lợi ích sau: 1.1. . 2.Hình 13: Sử dụng Prototype pattern trong ứng dụng 5. Client không cần phải quan tâm đến việc chọn một concrete class để tạo object mà mình muốn. Client không cần phải biết quá trình tạo object như thế nào Mô hình của pattern được mô tả trong hình sau. Client không cần phải liên hệ trực tiếp với lớp thực thi cụ thể (concrete class) mà thông qua interface hoặc abstract class.

public interface ComputerFactory { public Computer createPentiumProcessorComputer( ). Ư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. } public aspect DefaultComputerFactoryImplementation { . Đ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ế. Đoạn mã AspectJ sau đây chỉ ra cách thực hiện pattern này.Hình 14: Lược đồ UML của AbstractFactory Pattern 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. public Computer createComputerWithHardDisk(HardDisk hardDisk).

hardDisk. Computer computer = new Computer("12345". processor). Computer computer = new Computer("56789". Một phương thức trừu tượng (Factory method ) cung cấp một phương thức để khởi tạo các instance khác nhau của một interface.4 Factory Method pattern 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. motherboard. return computer. Motherboard motherboard = new Motherboard("434244". } public Computer ComputerFactory. HardDisk hardDisk = new HardDisk("738947"). processor). } } 5. floppyDisk). return computer.public Computer ComputerFactory. FloppyDisk floppyDisk = new FloppyDisk("93746"). Hình 15: Lược đồ UML của factory method pattern Đoạn mã AspectJ sau mô tả cách thực hiện pattern này: public interface ComputerCreator { .createPentiumProcessorComputer( ) { Processor processor = new Processor("Pentium 4 : 9089085043"). floppyDisk). motherboard. hardDisk. Motherboard motherboard = new Motherboard("019283".createComputerWithHardDisk(HardDisk hardDisk) { Processor processor = new Processor("Pentium Standard : 123478").1. FloppyDisk floppyDisk = new FloppyDisk("432434").

out.out. sau khi hoàn tất mỗi bước builder có thể được gọi để tạo đối tượng. 2.println("Inventory of computerparts:"). } public aspect TextPhraseBuilderDefaultImplementation { .toString( )). cần tạo một aspect mà nó thêm vào lớp cao nhất của lớp builder. public void buildBody(String content).public Computer createComputer(String serial).5 Builder pattern 5.1. Tách quá trình tạo một object ra bên ngoài bản thân class của object đó.createComputerAndPrintInventory(String serial) { System.1 Giới thiệu Builder pattern được sử dụng để tạo một đối tượng cần đến một tập các bước thực hiện phức tạp. Builder pattern có các lợi ích sau: 1. public String getResult( ).println(this. } public aspect DefaultComputerCreatorImplementation { public ComputerCreator. Ví dụ: public interface TextPhraseBuilder { public void buildHeader(String title). } } void Thường thì ComputerCreator trong pattern này là một lớp trừu tượng (abstract class).1. public void buildFooter(String closingContent). 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.5. 5. Tạo khả năng mềm dẻo trong việc đưa ra các implementation khác nhau cho qúa trình tạo object Để thực hiện Builder pattern trong AspectJ.createComputer(serial). System.

*/ declare error : ( set(public StringBuffer TextPhraseBuilder +. public String TextPhraseBuilder.getResult( ) { return result. 5. 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ó.public StringBuffer TextPhraseBuilder.result)) && !(within(TextPhraseBuilder +) || within(TextPhraseBuilderDefaultImplementation)) : "variable result is aspect protected. Aspect sử dụng Visitor pattern để duyệt đệ quy và làm việc với các thành phần của composite.2 Các mẫu thiết kế cho cấu trúc của đối tượng 5..2. } /** * Declares a compiler error that gets reported if other classes * (except Builders or this aspect) try to access the result variable. 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. .1 Composite pattern Composite pattern cung cấp khả năng nhóm các đối tượng cùng nhau trong một tập hợp và tương tác với nhóm tương tự như cách thao tác với một đối tượng thành viên độc lập của nhóm.toString( ). } Aspect TextPhraseBuilderDefaultImplementation cung cấp một phương thức thi công mặc định cho phương thức (). Composite pattern aspect định nghĩa giao diện Composite và Leaf để áp dụng vào các ứng dụng cần sử dụng vai trò của 2 giao diện này. use getResult( ) to access it".result = new StringBuffer( ). Sự tiện lợi này .result) || get(public StringBuffer TextPhraseBuilder +.

children). } return children.add(component). Component component) { getChildren(composite).get(s). private Vector getChildren(Component s) { Vector children = (Vector) perComponentChildren. perComponentChildren.remove(component). if (children == null) { children = new Vector( ).Hình 16: Cấu trúc của CompositePattern aspect public abstract aspect CompositePattern { public interface Component { } protected interface Composite extends Component { } protected interface Leaf extends Component { } private WeakHashMap perComponentChildren = new WeakHashMap( ). } public void removeChild(Composite composite. Component component) { getChildren(composite). } public Enumeration getAllChildren(Component c) { .put(s. } public void addChild(Composite composite.

elements( ). public void Component.nextElement( ). FunctionVisitor fv) { Vector results = new Vector( ). for (Enumeration enum = getAllChildren(c).doFunction(child)). } } public interface FunctionVisitor { public Object doFunction(Component c). } return results. declare parents : Rectangle implements Leaf. GraphicsComposite.hasMoreElements( ). } ) . } public void Composite.println("Drawing: " + this). } } Ví dụ sử dụng: public aspect GraphicsComposite extends CompositePattern { declare parents : Window implements Composite. } public interface Visitor { public void doOperation(Component c).draw(PrintStream s) { s. enum. declare parents : Line implements Leaf. enum. v. new Visitor( { public void doOperation(Component c) { c.draw(final PrintStream s) { s.draw(s).) { Component child = (Component) enum.doOperation(child). results.recurseOperation(this.add(fv. Visitor v) { for (Enumeration enum = getAllChildren(c).return getChildren(c).println("Composite: " + this).nextElement( ).) { Component child = (Component) enum.elements( ). } public void recurseOperation(Component c.aspectOf( ).hasMoreElements( ). } public Enumeration recurseFunction(Component c.

} Hình 17: Mô hình các đối tượng trước khi áp dụng Composite pattern Hình 18: Mô hình các đối tượng sau khi áp dụng Composite pattern Hình 19: Hoạt động của composite pattern trong ứng dụng .draw(PrintStream s) { s.println("Drawing Leaf: " + this). } public void Leaf.} }).

oopatterns. return flyweight. flyweight).put(key.5. public interface Flyweight { }.2. flyweightPool. protected abstract pointcut flyweightCreation(Object key). Object around(Object key) : flyweightCreation(key) && !within(com. } Ví dụ sử dụng: public aspect PrintableCharacterFlyweight extends FlyweightPattern .get(key).checkFlyweight(key).oreilly. } public synchronized Flyweight checkFlyweight(Object key) { if (flyweightPool.containsKey(key)) { return (Flyweight) flyweightPool.2 Flyweight pattern 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.aspectjcookbook.FlyweightPattern+) { return this. } else { Flyweight flyweight = createNewFlyweight(key). Hình 20: Cấu trúc của FlyweightPattern aspect public abstract aspect FlyweightPattern { private Hashtable flyweightPool = new Hashtable( ). } } protected abstract Flyweight createNewFlyweight(Object key).

drawRect( )).PrintableCharacter. public class Window { public void drawText(String text) { } public void drawRect( ) { } } public aspect XWindowBridge perthis(captureAllBridgedCalls( )) { private XWindow imp = new XWindow( ).drawLine( ). } void around( ) : captureDrawRect( ) { imp.drawLine( ).2. public pointcut captureAllBridgedCalls( ) : captureDrawText(String) || captureDrawRect( ). imp. protected pointcut flyweightCreation(Object key) : call(public com.3 Bridge Pattern 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. protected Flyweight createNewFlyweight(Object key) { return new PrintableCharacter((Character) key). public pointcut captureDrawText(String text) : execution(public void Window.drawLine( ).oreilly. . public pointcut captureDrawRect( ) : execution(public void Window. } } 5.drawText(String)) && args(text). new(Character)) && args(key).{ declare parents : PrintableCharacter implements Flyweight. imp. void around(String text) : captureDrawText(text) { imp.aspectjcookbook.drawText(text).

public abstract aspect DecoratorPattern { public interface DecoratedComponent { }. public void DecoratedComponent.decorated = decorated. private boolean DecoratedComponent. Hình 21:Cấu trúc của XWindowBridge aspect Ví dụ sử dụng: Hình 22: Sử dụng các hành vi của lớp Window trong ứng dụng 5.decorated = false. .drawLine( ).4 Decorator pattern 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.setDecorated(boolean decorated) { this.} } imp.2.

out.print("<Decoration>").print("</Decoration>").getDecorated) { System.out.decorated .getDecorated) { System. } after(Object object) : selectDecorators(object) && if(((DecoratedComponent)object). before(Object object) : selectDecorators(object) && if(((DecoratedComponent)object).} } public void DecoratedComponent.display(String)) && target(object).isDecorated(boolean decorated) { return this. } } Hình 24:Lớp TextDisplay trước và sau khi áp dụng DecoratorPattern . public pointcut selectDecorators(Object object) : call(public void TextDisplay. } Hình 23: Cấu trúc của DecoratorPattern aspect Ví dụ sử dụng: public aspect TextDisplayDecorator extends DecoratorPattern { declare parents : TextDisplay implements DecoratedComponent.

2. public aspect PrinterScreenAdapter { declare parents : Screen implements Printer. Hình 26: Cấu trúc của ProxyPattern aspect public abstract aspect ProxyPattern { protected interface Subject . public void Screen.6 Proxy Pattern 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. } } Hình 25: Áp dụng Adapter pattern 5. Sự thích ứng thông điệp này phải gắn với hai đối tượng.5 Adapter pattern 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.5.print(String s) { outputToScreen(s).2.

} else if (delegate(caller. subject. thisJoinPoint). private pointcut accessByCaller(Object caller) : requestTriggered( ) && this(caller). JoinPoint joinPoint). thisJoinPoint). } protected abstract boolean reject( Object caller. protected abstract boolean delegate( Object caller. private pointcut accessByUnknown( ) : requestTriggered( ) && !accessByCaller(Object). subject. Object around(Object caller. } return proceed(subject). Subject subject. Subject subject. Subject subject) : accessByCaller(caller) && target(subject) { if (reject(caller. Subject subject. thisJoinPoint)) { return delegateRequest(null. . thisJoinPoint)) { return delegateRequest(caller. } return proceed(caller.{ } protected abstract pointcut requestTriggered( ). } Object around(Subject subject) : accessByUnknown( ) && target(subject) { // 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. subject. thisJoinPoint). protected abstract Object rejectRequest( Object caller. subject). thisJoinPoint)) { return rejectRequest(caller. JoinPoint joinPoint). subject. subject.

} Ví dụ sử dụng: public aspect DelegationProxy extends ProxyPattern { declare parents : RealSubject implements Subject.write((String) args[0]). } protected Object delegateRequest( Object caller. Subject subject. JoinPoint joinPoint) { Object[] args = joinPoint. protected boolean reject( Object caller. Subject subject..getArgs( ). JoinPoint joinPoint) { return null. } protected boolean delegate( Object caller. } protected Object rejectRequest( Object caller. if (args != null) { AnotherRealSubject. Subject subject. Subject subject. Subject subject. JoinPoint joinPoint). JoinPoint joinPoint) { return false. } return null. protected abstract Object delegateRequest( Object caller.write(. JoinPoint joinPoint) { return true.)).JoinPoint joinPoint). } } . } else { AnotherRealSubject.write(""). protected pointcut requestTriggered( ) : call(* RealSubject.

Nó cũng duy trì tập các ánh xạ giữa các Subject và các Observer.5. khi một đối tượng thay đổi trạng thái thì các đối tượng phụ thuộc nó được thông báo và cập nhật một cách tự động. Khi chúng ta thừa kế aspect. } protected interface Observer { . Chúng ta xây dựng aspect cho mẫu thiết kế này như sau: Định nghĩa 2 vai trò: Subject và Observer. khi Employe thay đổi trạng thái thì Department phải được cập nhật và thông báo.1 Observer pattern 5.3.1.3 Các mẫu thiết kế cho hành vi của đối tượng 5. Ví dụ chúng ta muốn duy trì quan hệ phụ thuộc giữa Employe và Department. Các aspect thừa kế có thể sử dụng addObserver() hoặc removeObserver() để tác động vào danh sách ánh xạ Hình 27: Cấu trúc của ObserverPattern aspect public abstract aspect ObserverPattern { protected interface Subject { public void addObserver(Observer observer). public void removeObserver(Observer observer).1 Giới thiệu Mẫu thiết kế này dùng để định nghĩa mối quan hệ phụ thuộc 1:n giữa các đối tượng. chúng ta sẽ sử dụng các subaspect để tác động những quyền đó vào Employe và Department. Mỗi Subject có một hay nhiều các Observer.3.

public void Subject.notifyObservers( ) { Iterator iter = this. } private List Subject.removeObserver(Observer observer) { this. Cái gì cấu tạo thành sự cập nhật trong Observer 4.remove(observer). after(Subject subject) : subjectChange(subject) { subject. } } 5. Cái gì cấu tạo thành sự thay đối trong Subject 3.notifyObservers( ).2 Sử dụng 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.public void notifyOfChange(Subject subject).observers. Khi nào Observer bắt đầu theo dõi Subject và khi nào dừng theo dõi Ví dụ sau minh hoạ cách sử dụng Observer pattern .notifyOfChange(this).iterator( ).observers.add(observer).observers. } } protected abstract pointcut subjectChange(Subject s). while (iter. } public void Subject. } private synchronized void Subject.addObserver(Observer observer) { this.next( )).1.observers = new LinkedList( ). Đối tượng nào là Subject và đối tượng nào là Observer ? 2. 1. cụ thể là cần trả lời những câu hỏi sau.hasNext( )) { ((Observer)iter.3.

declare parents : ConcreteClassA implements Observer. public void ConcreteClassA.set*(. } } .notifyOfChange(Subject subject) { this. protected pointcut subjectChange(Subject s) : call(* ConcreteClassB..Hình 28: Cấu trúc lớp trước khi áp dụng ObserverPattern Hình 29:Cấu trúc lớp sau khi áp dụng ObserverPattern public aspect ConcreteClassAObserver extends ObserverPattern { declare parents : ConcreteClassB implements Subject.doSomething( "ConcreteClassA was notified of a change on " + subject).)) && target(s).

Khi đối tượng yêu cầu được đã được xây dựng. Hỗ trợ undo.Hình 30:Sử dụng ObserverPattern trong ứng dụng 5.2 Command Pattern Command pattern hỗ trợ sự đóng gói các yêu cầu như các đối tượng trong phạm vi những quyền của chúng. Command pattern được sử dụng trong các trường hợp sau 1. logging. nó có thể được quản lý như các thực thể tách rời từ đối tượng ban đầu. Tách biệt giữa nguồn của yêu cầu với đối tượng thực hiện yêu cầu Hình 31: Cấu trúc của CommandPattern và các hàm hỗ trợ pattern . hoặc transaction 2. Hàng đợi và thực hiện các lệnh tại các thời điểm khác nhau 3.3. 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.

} private WeakHashMap mappingCommandToReceiver = new WeakHashMap( ). CommandReceiver receiver) { return mappingCommandToReceiver. public boolean isExecutable( ). if (command != null) { CommandReceiver receiver = getReceiver(command). public Object setReceiver(Command command. .put(invoker. } public Command getCommand(CommandInvoker invoker) { return (Command) mappingInvokerToCommand. } protected abstract pointcut commandTrigger(CommandInvoker invoker).public abstract aspect CommandPattern { public interface Command { public void executeCommand(CommandReceiver receiver). null). after(CommandInvoker invoker) : commandTrigger(invoker) { Command command = getCommand(invoker). receiver). } public Object removeCommand(CommandInvoker invoker) { return setCommand(invoker.get(invoker). } public interface CommandInvoker { } public interface CommandReceiver { } private WeakHashMap mappingInvokerToCommand = new WeakHashMap( ).get(command). public Object setCommand(CommandInvoker invoker. command). } public CommandReceiver getReceiver(Command command) { return (CommandReceiver) mappingCommandToReceiver. Command command) { return mappingInvokerToCommand.put(command.

after(CommandInvoker invoker. } protected pointcut removeCommandTrigger(CommandInvoker invoker). } public boolean Command. after(CommandInvoker invoker) : removeCommandTrigger(invoker) { if (invoker != null) removeCommand(invoker). } else { // Do nothing: This Invoker has no associated command } } protected pointcut setCommandTrigger(CommandInvoker invoker.isExecutable( ) { return true. Command command).executeCommand(receiver). command). } } Ví dụ sử dụng command pattern Hình 32: Trước khi áp dụng CommandPattern .command. command) { if (invoker != null) setCommand(invoker. Command command) : setCommandTrigger( invoker.

declare parents : Printer implements CommandReceiver.toString( )). declare parents : VCardPrinter implements CommandReceiver.printVCard(this).timedOut( )) . } else { ((VCardPrinter) receiver). } } public void executeCommand(CommandReceiver receiver) { ((Printer) receiver).println("Command triggered on printer receiver"). declare parents : BusinessCard implements Command. } protected pointcut commandTrigger(CommandInvoker invoker) : call(void TimedEvent. public void BusinessCard.println(this.Hình 33:Trước khi áp dụng CommandPattern public aspect ConcreteCommand extends CommandPattern { declare parents : TimedEvent implements CommandInvoker.executeCommand(CommandReceiver receiver) { if (receiver instanceof Printer) { ((Printer) receiver).

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 đó. 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 đó. Iterator pattern được sử dụng khi 1. . } Hình 34: Sử dụng CommandPattern trong ứng dụng 5. Cung cấp một cách thức đồng bộ.3 Iterator pattern 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.&& target(invoker).3. Hình 35: IteratorPatternAspect và interface định nghĩa vài trò của pattern public abstract aspect IteratorPattern { public interface Aggregate { public Iterator createIterator( ).

public Iterator createReverseIterator( ); } }

Ví dụ:
public aspect EmployeeIteration extends IteratorPattern { declare parents : EmployeeCollection implements Aggregate; public Iterator EmployeeCollection.createIterator( ) { return new EmployeeIterator(this, true); } public Iterator EmployeeCollection.createReverseIterator( ) { return new EmployeeIterator(this, false); }

}

Hình 36: Mô tả sự tương tác của EmployeeIteration với ứng dụng

5.3.4 Mediator pattern
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 đó.

Hình 37: Cấu trúc của MediatorPattern aspect

public abstract aspect MediatorPattern { protected interface Colleague { } protected interface Mediator { } private WeakHashMap mappingColleagueToMediator = new WeakHashMap( ); private Mediator getMediator(Colleague colleague) { Mediator mediator = (Mediator) mappingColleagueToMediator.get(colleague); return mediator; } public void setMediator(Colleague c, Mediator m) { mappingColleagueToMediator.put(c, m); } protected abstract pointcut change(Colleague c); after(Colleague c) : change(c) { notifyMediator(c, getMediator(c)); } protected abstract void notifyMediator(Colleague c, Mediator m); }

Ví dụ sử dụng Mediator pattern:
public aspect DialogMediator extends MediatorPattern {

declare parents : ListBox implements Colleague; declare parents : EntryField implements Mediator; protected pointcut change(Colleague c) : ( execution(void ListBox.setSelection(..)) && this(c)); protected void notifyMediator(Colleague c, Mediator m) { ListBox listBox = (ListBox) c; EntryField entryField = (EntryField) m; entryField.setText(listBox.getSelection( )); } }

Hình 38: Trước và sau khi áp dụng Mediator pattern

5.3.5 Chain of Responsibility Pattern
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ỗi bước thực hiện được quản lý bởi một đối tượng và chịu trách nhiệm trên sự phân công chức năng của hệ thống.

Hình 39: Cấu trúc của ChainOfResponsibilityPattern aspect public abstract aspect ChainOfResponsibilityPattern { protected interface Handler { } public WeakHashMap successors = new WeakHashMap( );

Object request).handleRequest(Object request) { // A default empty implementation that is overridden // if required by the application specific concrete aspects } protected abstract pointcut eventTrigger(Handler handler. if (successor == null) { // Last handler in the chain so must deal with the request // This is a rudimentary implementation and more complex // logic could be applied here or perhaps in the concrete // aspects that extend this abstract one handler. } } } public boolean Handler.handleRequest(request). Object request) { if (handler. } else { // Hand the request on to the next successor in the chain receiveRequest(successor.handleRequest(request). } public void Handler. request) { . request). after(Handler handler. Object request) : eventTrigger(handler.acceptRequest(request)) { handler.acceptRequest(Object request) { // The default as defined here is to reject the request // This is implemented by the application specific // concrete aspects return false.protected void receiveRequest(Handler handler. } else { // The handler will not accept the request Handler successor = getSuccessor(handler).

)) && target(handler) && args(event). declare parents : PrintDialog implements Handler. } public void PrintButton.acceptRequest(event)) { . } public void setSuccessor(Handler handler. Handler successor) { successors. protected pointcut eventTrigger(Handler handler. declare parents : Manager implements Handler.acceptRequest(Object event) { return !this. request). public boolean Handler. } public Handler getSuccessor(Handler handler) { return ((Handler) successors. Object event) : call(void PrintButton.alreadyHandledRequest = false.get(handler)). private boolean Handler.handleRequest(Object event) { if (!this..receiveRequest(handler.put(handler.alreadyHandledRequest. successor).doClick(. } } Ví dụ sử dụng: Hình 40: Sau khi áp dụng ChainOfResponsibilityPattern public aspect HelpChain extends ChainOfResponsibilityPattern { declare parents : PrintButton implements Handler.

out.alreadyHandledRequest = true. this. } System.println("Manager handling request: " + event).acceptRequest(event)) { System.out. } System.println( "PrintButton Forced to handle Request" + "due to being last in the chain (Implementation Decision)").alreadyHandledRequest = true.alreadyHandledRequest = true. } public void Manager.out.println( "Manager Forced to handle Request due to being" + "last in the chain (Implementation Decision)").println( "PrintDialog Forced to handle Request" + "due to being last in the chain (Implementation Decision)").out.out.acceptRequest(event)) { System.out. this. this.println("PrintButton handling request: " + event).println("PrintDialog handling request: " + event).handleRequest(Object event) { if (!this.System.handleRequest(Object event) { if (!this. } public void PrintDialog. } } . } System.

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. public Object getState( ). } public interface Originator { public void setMemento(Memento memento). public abstract aspect MementoPattern { public interface Memento { public void setState(Originator originator). public Memento createMemento( ).Hình 41:Sử dụng ChainOfResponsibilityPattern trong ứng dụng 5. Khả năng này có thể được sử dụng để áp dụng thao tác undo trạng thái đối tượng trong các ứng dụng cụ thể.3. public Object getState( ). } .6 Memento Pattern 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.

createMemento( ) { Memento memento = new DefaultMemento( ). Ví dụ sử dụng Mememto: public aspect EmployeeMemento extends MementoPattern { declare parents : Employee implements Originator. } public Memento Employee.getName( )). this.getState( ). return employee. this. memento.getState( ) throws MementoException { Employee employee = new Employee(this.setName(stateToRestore. Employee stateToRestore = (Employee) object. this. public void Employee.setSalary(stateToRestore. } } Hình 43: Sử dụng MementoPattern trong ứng dụng .getName( ).Hình 42: Cấu trúc của MementoPattern aspect.setMemento(Memento memento) { Object object = memento.setState(this). return memento.getSalary( )). } public Object Employee.getSalary( )).

} public interface Result { } public interface Visitor { public void visitElement(Element element).visitComposite(this). } public void CompositeElement. Hình 44: Cấu trúc của Visitor pattern aspect public abstract aspect VisitorPattern { public interface Element { public void accept(Visitor visitor). public Result getResult( ). đ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.visitElement(this). } public interface CompositeElement extends Element { public Element[] getElements( ). } } Ví dụ sử dụng Visitor pattern: .accept(Visitor visitor) { visitor.3.7 Visitor Pattern 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. } public void Element. Với mô hình AOP.5.accept(Visitor visitor) { visitor. public void visitComposite(CompositeElement element). Visitor cho phép định nghĩa thêm các thao tác mà không cần thay đổi lớp của các thành phần mà nó thao tác trên đó.

declare parents : InventoryReport implements Result. elements[2] = this.getFloppyDisk( ).getProcessor( ). return elements. elements[0] = this. declare parents : Processor implements Element.getElements( ) { Element[] elements = new Element[1]. return elements.getHardDisk( ).getMotherboard( ). elements[1] = this. } } Cấu trúc và quan hệ giữa các thành phần của Computeur Hình 45: Cấu trúc của Computeur Cấu trúc và quan hệ giữa các thành phần của Computeur sau khi áp dụng Visitor pattern . declare parents : Motherboard implements CompositeElement.public aspect InventoryVisitor extends VisitorPattern { declare parents : FloppyDisk implements Element.getElements( ) { Element[] elements = new Element[3]. elements[0] = this. declare parents : Computer implements CompositeElement. } public Element[] Motherboard. public Element[] Computer. declare parents : HardDisk implements Element.

Hình 46: Cấu trúc Computeur sau khi áp dụng Visitor pattern Hình 47:Sử dụng VisitorPattern trong ứng dụng 5.8 Strategy pattern 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 đó.3. public abstract aspect StrategyPattern . 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.

strategy = null.{ Hashtable strategyPerContext = new Hashtable( ). protected interface Strategy { } protected interface Context { } private Strategy Context. else if (strategy instanceof LinearSorter) ((LinearSorter) strategy). public void setConcreteStrategy(Context c. declare parents : BubbleSorter implements Strategy.get(c). return numbers. s).sort(numbers). } } Hình 48:Cấu trúc của StrategyPattern aspect Ví dụ áp dụng: public aspect SortingStrategy extends StrategyPattern { declare parents : Sorter implements Context. int[] numbers) : call(int[] Sorter. declare parents : LinearSorter implements Strategy.sort(numbers).sort(int[])) && target(s) && args(numbers) { Strategy strategy = getConcreteStrategy(s). if (strategy instanceof BubbleSorter) ((BubbleSorter) strategy). } } .put(c. int[] around(Sorter s. } public Strategy getConcreteStrategy(Context c) { return (Strategy) strategyPerContext. Strategy s) { strategyPerContext.

TCPState state) : call( void TCPState +. after(TCPConnection connection) : initialization(new ( )) && target(connection) { listening. connection.Hình 49: Cấu trúc các lớp sắp xếp khi chưa áp dụng StrategyPattern Hình 50: Cấu trúc các lớp sắp xếp sau khi áp dụng StrategyPattern Hình 51: Sử dụng Strategy Pattern trong ứng dụng 5. protected TCPState closed = new TCPClosed( ).setConnection(new SocketConnection( )).9 State Pattern State Pattern cung cấp một cơ chế cho đối tượng có thể biến đổi hành vi của nó dựa trên các trạng thái của nó. public aspect TCPConnectionState { protected TCPState listening = new TCPListen( ).setState(listening). } after(TCPConnection connection. protected TCPState acknowledged = new TCPAcknowledged( ).3.acknowledge( )) .

} } } TCPConnectionState aspect cho thấy lớp TCPConnection sẽ được lắng nghe khi nó được tạo.getState( ) == listening) || (connection.setState(acknowledged). được báo khi phương thức acknowledge() được gọi và đóng khi phương thức close() được gọi. TCPState state) : call( void TCPState +.getState( ) == listening) { acknowledged. Hình 52: Sử dụng state pattern trong ứng dụng .&& target(state) && this(connection) { if (connection. } } after(TCPConnection connection.close( )) && target(state) && this(connection) { if ((connection.setConnection(listening.setState(closed).getConnection( )).getState( ) == acknowledged)) { connection. connection.

transaction. Điểm mạnh của AOP là xây dựng các ứng dụng middleware bao gồm các thao tác phức tạp như security. và trên thực tế AOP đã được triểnkhai trên các ứng dụng thương mại như JBOSS application server phiên bản 4. Spring Framework và đã đạt được một số kết quả ban đầu trong việc triển khai một ứng dụng AOP cụ thể. Trong thời gian tới. Đây là một trong những bước quan trọng trong việc đưa AOP vào áp dụng trong các ứng dụng cụ thể. tracing.. Đặc biệt trong công nghệ Enterprise Java Bean của Sun Microsystem. . đồ án môn học này mới chỉ đi vào khía cạnh ngôn ngữ và việc xây dựng lại các mẫu thiết kế (design pattern) trong mô hình OOP chuyển sang mô hình AOP.0 tiếp theo. AOP có phải là một cuộc cách mạng trong phương pháp lập trình hay không thì còn phải chờ vào những kết quả triển khai thực tế của các sản phẩm hỗ trợ AOP. AOP đã được đưa vào nhiều ngôn ngữ. Do thời gian có hạn. tận dụng những đặc điểm mới của AOP.0. loging. những khó khăn và thách thức cho phương pháp lập trình mới này Chúng em xin chân thành cảm ơn Thầy giáo Huỳnh Quyết Thắng đã định hướng và cung cấp những kiến thức cơ bản cũng như những tài liệu báu để em có thể hoàn thành tốt đồ án này. đồ án sẽ tiếp tục đi sâu hơn nữa trong việc triển khai các ứng dụng cụ thể trên AOP. . các nhà phát triển đã lên kế hoạch đưa AOP vào trong đặc tả phiên bản EJB 3.6 Kết luận AOP đang thực sự trở thành phương pháp luận cho ngành công nghệ phần mềm hiện nay.

org/aspectj/ 6. Nicholas Lesiecki -Wiley publishing 5. John Vlissides Addison Wesley. Mastering AspectJ-Joseph D.com 7.Russell Miles . Richard Helm. http://aosd. Ralph Johnson. Gradecki.net/ . AspectJ in Action-RAMNIVAS LADDAD-Manning publishing . AspectJ CookBook. http://eclipse.Erich Gamma. 1995 2.Aspect Oreinted Software development community & conference . http://theserverside.2004 4.O'Reilly 2004 3.7 Tài liệu tham khảo 1. Elements of Reusable Object-Oriented Software Addison Wesley .

Sign up to vote on this title
UsefulNot useful