Đồ án Các mẫu thiết kế phần mềm hướng đối tượng và áp dụng

Chương mở đầu này tôi xin được giới thiệu một số nét chung về đồ án tốt nghiệp mà tôi lựa chọn để thực hiện. Đồng thời, trong phần này, tôi cũng trình bày một số nét tổng quan về đề tài của đồ án tốt nghiệp, về những lý do, động cơ thúc đẩy nghiên cứu và tìm hiểu đề tài của tôi, về những mục đích đặt ra và yêu cầu của đề tài mà tôi đã nghiên cứu thực hiện trong thời gian qua.

doc86 trang | Chia sẻ: oanh_nt | Lượt xem: 1368 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Đồ án Các mẫu thiết kế phần mềm hướng đối tượng và áp dụng, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
ương pháp để đạt được hiệu quả là đưa ra một đối tượng bao quát đơn nhất, cung cấp một giao diện đơn giản để nhìn được chức năng tổng thể của một hệ thống con. Ví dụ, trong môi trường lập trình, các ứng dụng truy xuất đến hệ thống con biên dịch của nó, chứa các lớp như Scanner, Parser, ProgramNode, BytecodeStream và ProgramNodeBuilder cài đặt compiler. Một số ứng dụng riêng cần truy cập những lớp này một cách trực tiếp. Nhưng hầu hết các client của một compiler không chi tiết như phân tích cú pháp hoặc bộ sinh mã nguồn. Nó chỉ đơn thuần dịch phần ít mã. Như vậy, giao diện có hiệu quả mạnh nhhung ở mức thấp trong hệ thống con biên dịch và chỉ kết nối phần nhiệm vụ của chúng. Để cung cấp mức cao mà có thể che cho client khỏi các lớp này, hệ thống con biên dịch cũng bao hàm một lớp Compiler, lớp này định nghĩa một giao diện đồng nhất chức năng của compiler. Lớp Compiler hoạt động giống như một giao diện tổng quát, ở đây là facade; Nó đưa ra một giao diện đơn giản và đơn hình cho hệ thống con compiler. Nó kết hợp các lớp này để cài dặt chức năng compiler mà không cần ẩn đi hoàn toàn về chúng. Ở đây, Compiler facade làm đơn giản hơn cho hầu hết các nhà lập trình không cần ẩn đi các công việc và chức năng ở mức thấp. Ứng dụng Cần cung cấp một giao diện đơn giản tới hệ thống con phức tạp. Làm cho hệ thống con có khả năng sử dụng lại được và dễ dàng thay đổi thích nghi, nhưng cũng khó hơn khi sử dụng cho client mà không cần thay đổi chúng. Façade có thể cung cấp một khung nhìn mặc định đơn giản đơn giản của hệ thống con khi phù hợp cho hầu hết các client. Chỉ có các client cần nhiều tuỳ biến sẽ cần phải quan sát rộng ra façade. Có một số sự phụ thuộc giữa các client và các lớp thực hiện của khái niệm trừu tượng. Đưa ra một façade để phân tách hệ thống con từ client và các hệ thống con khác, từ đó, phát triển hệ thống con một cách độc lập và hữu hiệu. Muốn phân tầng hệ thống con. Sử dụng façade để định nghĩa một điểm đầu vào tới từng mức hệ thống con. Nếu các hệ thống con là phụ thuộc, chúng có thể đơn giản hoá sự phụ thuộc giữa chúng bằng cách tạo kết nối chúng với từng phần riêng lẻ khác thông qua façade của chúng. Cấu trúc Facade Subsystem classes Thành phần Façade: Biết các lớp hệ thống con nào hoạt động theo yêu cầu. Client yêu cầu các đối tượng của hệ thống con phải phù hợp. Subsystem classes: Thực hiện chức năng hệ thống con. Chịu sự phân công công việc của Façade Object. Phối hợp cộng tác Client giao tiếp với hệ thống con bằng cách gửi các yêu cầu tới Façade, và Façade này sẽ hướng client đến đối tượng hệ thống con phù hợp. Mặc dù, các đối tượng hệ thống con thực hiện công việc thực nhưng façade có thể thực hiện công việc của chính nó để chuyển giao diện của nó tới giao diện của hệ thống con. Các client sử dụng Façade không cần phải truy cập vào các đối tượng hệ thống con một cách trực tiếp. Kết quả Bảo vệ khách hàng từ những thành phần của hệ thống con, vì thế sẽ giảm được số lượng các đối tượng mà khách hàng phải giải quyết và làm cho hệ thống con được sử dụng dễ dàng. Tăng cường mối liên kết giữa hệ thống con và các client của nó. Các thành phần trong hệ thống con được kết nối chặt chẽ. Mối liên kết giúp bạn thay đổi các thành phần của hệ thống con mà không ảnh hưởng đến các client của nó. Façade giúp phân lớp hệ thống và sự phụ thuộc giữa các đối tượng. Các façade có thể lọc bỏ sự phức tạp hoặc những lệ thuộc có tính chất lòng vòng. Điều này có thể là kết quả quan trọng khi khách hàng và hệ thống con hoạt động độc lập. Giảm sự phụ thuộc biên dịch là cần thiết trong hệ thống phần mềm lớn. Bạn muốn tiết kiệm thời gian bằng cách tối thiểu hoá việc biên dịch lại khi các lóp hệ thống con thay đổi. Giảm sự lệ thuộc biên dịch với Façade có thể giới hạn việc biên dịch lại cần thiết cho sự thay đổi nhỏ trong hệ thống con quan trọng. Façade có thể làm đơn giản hệ thống cổng kết nối với các flatform khác bởi vì nó kém phù hợp với việc xây dựng một hệ thống con phụ thuộc vào việc xây dựng tất cả những cái khác. Nó không ngăn chặn ứng dụng từ việc sử dụng các lớp hệ thống con nếu chúng cần đến. Vì vậy bạn có thể chọn lựa giữa việc sử dụng dễ dàng và mang tính tổng quát. Cài đặt Giảm sự liên kết giữa client và hệ thống con : Sự liên kết giữa client và hệ thống con thậm chí có thể giảm hơn nữa bằng cách tạo cho façade một lớp trừu tượng có các lớp con cụ thể làm cho có sự khác biệt trong việc thực hiện của hệ thống con. Client có thể giao tiếp với hệ thống con thông qua giao diện của lớp Façade trừu tượng. Việc kết nối trừu tượng này có thể giúp cho client khỏi biết đến việc thực hiện nào của hệ thống con là được sử dụng. Lựa chọn để phân lớp là để cấu hình đối tượng Façade với các đối tượng hệ thống con khác nhau. Để làm theo yêu cầu của Façade, đơn giản là thay thế một hoặc nhiều đối tượng của hệ thống con. Lớp hệ thống con chung ngược với lớp hệ thống con riêng lẻ: Hệ thống con là tương tự một lớp mà trong đó cả hai đều có giao diện , và đều gói gọn một số vấn đề - một lớp bao hàm trạng thái và thao tác, trong khi hệ thống con đóng gói các lớp. Tìm hiểu hiệu quả giao diện public và private của lớp thì mới có thể tìm hiểu về giao diện public và private của hệ thống con. Đối với giao diện hệ thống con, chung bao gồm các lớp mà tất cả các client có thể truy cập. giao diện Private chỉ dùng cho việc mở rộng hệ thống con. Lớp Façade là một phần của giao diện chung, nhưng không phải là phần duy nhất. Các lớp hệ thống con khác cũng đều được sử dụng chung. Làm cho các lớp riêng của hệ thống phụ sẽ có ích, nhưng một vài ngôn ngữ hướng đối tượng hỗ trợ nó. Gần đây C++ đã thêm vào không gian tên đối với ngôn ngữ giúp bạn đưa ra được các lớp chung của hệ thống con. Các mẫu liên quan Abstract Factory có thể được sử dụng với Façade để cung cấp một giao diện cho việc tạo các đối tượng hệ thống con trong phương pháp độc lập hệ thống con. Mediator tương tự như Façade trong đó nó trừu tượng hoá chức năng của các lớp có sẵn. Tuy nhiên, mục đích của Mediator là để trừu tượng hoá bất kỳ một giao tiếp nào giữa các đối tượng với cùng nhiệm vụ, chức năng, tập trung hoá thường xuyên mà không thuộc về bất kỳ một đối tượng nào trong số đó. Các cộng tác của mediator đều nhận thức và giao tiếp với mediator thay cho việc giao tiếp trực tiếp giữa các cộng tác có liên quan. Ngược lại, Façade chỉ trừu tựợng phối ghép các đối tượng hệ thống con để làm chúng dễ sử dụng hơn. Nó không chỉ rõ các chức năng mới và các lớp hệ thống con không biết về nó. Thường thường chỉ có đối tượng Façade được yêu cầu, vì vậy các đối tượng Façade thường là Singleton. Flyweight mẫu Mục đích Sử dụng việc dùng chung để hỗ trợ cho số lượng lớn các đối tượng tốt đã biêt (fine-grained) một cách có hiệu quả Ứng dụng Hiệu quả của Flyweight mẫu phụ thuộc vào việc nó được sử dụng ở đâu, như thế nào. Việc ứng dụng của Flyweight mẫu khi tất cả các vấn đề sau đây là đúng. Một ứng dụng sử dụng nhiều đối tượng Chi phí bảo quản lớn bởi vì số lượng tuyệt đối của đối tượng Tất cả trạng thái đối tượng có thể được tác động từ bên ngoài Nhiều nhóm đối tượng có thể được thay thế bởi quan hệ của vài đối tượng chung khi trạng thái ngoài được xoá bỏ. Ứng dụng không phụ thuộc vào việc đồng nhất đối tượng. Vì các đối tượng Flyweight có thể được dùng chung, các kiểm tra tính đồng nhất sẽ thật sự đối với đối tượng dễ phân biệt. Cấu trúc: FlyweightFactory GetFlyWeight(key) FlyweightFactory GetFlyWeight(key) If {flyweight(key) exits}{ Return existing flyweight; } else{ create new flyweight. Add n to protocol flyweight; Return the new flyweight; } Client ConcreteFlyweight Operation(extinnsicState) IntrinsicState UnshareedConcreteFlyweight Operation(extinnsicState) allState Biểu đồ đối tượng chỉ ra làm thế nào các flyweight được dùng chung; aClient aClient aFlyweightFactory flyweight aConcreteFlyweight intansicState aConcreteFlyweight intansicState Flyweight pool Thành phần: Flyweight:Khai báo một giao diện thông qua những flyweight có thể nhận và hoạt động ở trạng thái ngoài. ConcreteFlyweight: Thực hiện giao diện Flyweight và lưu trữ thêm đối với trạng thái trong, nếu có. Đối tượng ConcreteFlyweight phải có thể dùng chung. Bất kì trạng thái nào lưu trữ phải là trạng thái trong. Đó là, nó phải độc lập với ngữ cảnh đối tượng ConcreteFlyweight. UnsharedConcreteFlyweight: Không phải tất cả các lớp con của Flyweight cần phải dùng chung. Giao diện Flyweight có thể chung, không bắt buộc. Có điểm chung giữa các đối tượng ConcreteFlyweight để có các đối tượng Flyweight có các nhánh con cùng mức trong cấu trúc đối tượng flyweight(như các lớp hàng và cột) FlyweightFactory Tạo và quản lí các đối tượng Flyweight. Đảm bảo rằng các flyweight được dùng chung một cách thích hợp. Khi client yêu cầu flyweight thì đối tượng flyweight factory cung cấp trường hợp hiện hữu hoặc tạo ra một trường hợp, nếu không tồn tại. Client: Duy trì mối quan hệ giữa các flyweight. Tính toán hay lưu trữ trạng thái ngoài của flyweight. Phối hợp cộng tác. Trạng thái mà flyweight cần để thực hiện chức năng như được kí tự hoá cả bên trong và bên ngoài. Trạng thái trong lưu giữ đối tượng ConcreteFlyweight.Trạng thái ngoài được lưu giữ bởi đối tượng client. Các client chuyển trạng thái này đến flyweight khi chúng cần đến hoạt động của nó. Các client không nên giải thích trực tiếp với ConcreteFlyweight. Client phải thu được các đối tượng ConcreteFlyweight được dành riêng từ đối tượng Flyweight để đảm bảo chúng được dùng chung một cách thích hợp. Kết quả. Flyweight có thể đưa ra chi phí thời gian chạy kết hợp với việc chuyển, tìm kiếm và/hoặc tính toán trạng thái ngoài. đặc biệt nếu nó đã được lưu trữ như trạng thái bên trong.Tuy nhiên, hầu hết chi phí không gian sẽ sai lệch khi nhiều Flyweight được dùng chung. Bộ lưu trữ là mang tính chức năng của một vài yếu tố: Việc giảm tổng số các trường hợp cho việc dùng chung. Số lượng trạng thái trong cho một đối tượng. Liệu trạng thái bên ngoài có được lưu trữ hay không. Cài đặt Xoá bỏ trạng thái bên ngoài: Khả năng ứng dụng của mẫu được quyết định chủ yếu dễ dàng như thế nào để định rõ đối tượng bên ngoài và xoá nó khỏi đối tượng được dùng chung. Xoá bỏ trạng thái bên ngoài sẽ không giúp làm giảm chi phí lưu trữ nếu nó có nhiều trạng thái khác nhau của trạng thái bên ngoài như là việc có các đối tượng trước khi dùng chung. Trường hợp lý tưởng là trạng thái bên ngoài có thể được tính toán từ cấu trúc riêng biệt của đối tượng, một đối tượng nhỏ hơn nhiều so với bộ lưu trữ yêu cầu. Quản lý các đối tượng dùng chung: Vì các đối tượng được dùng chung nên các client không nên giải thích một cách trực tiếp. FlyweightFactory đưa các khách hàng xác định một flyweight đặc biệt. Các đối tượng của FlyweightFactory thường sử dụng bộ lưu trữ liên kết để giúp các client tra cứu các tiện ích của Flyweight. Ví dụ FlyweightFactory trong trình soạn thảo Document có thể giữ bảng của Flyweight được lập bằng mã kí tự. Người quản lí quay trở lại thuộc tính của Flyweight để đưa ra mã của nó, tạo ra flyweight nếu nó chưa tồn tại. Khả năng có thể dùng chung cũng ngụ ý rằng một vài dạng của referency counting hoặc thu lượm dữ liệu không thích hợp để phục hồi bộ lưu trữ của Flyweight khi mà nó không cần đến nữa. Tuy nhiên nó cũng không cần thiết nếu số lượng các flyweight là cố định. Trong trường hợp đó, flyweight cũng đánh giá để giữ lại lâu dài. Các mẫu liên quan: Flyweight mẫu thường được kết hợp với composite mẫu để được thực hiện một cấu trúc biểu đồ logic có tính chu kỳ trong đồ hoạ (directed-acyclic graph) với các nút lá được dùng chung. Nó thường tốt nhất để thực hiện đối tượng State và Strategy như là Flyweight. Proxy Mục đích Đưa ra một thay thế hoặc phần giữ chỗ( phần bộ nhớ máy tính dành cho thông tin sẽ được cung cấp về sau) cho đối tượng khác để kiểm soát truy xuất của nó. ví dụ Soạn thảo tài liệu có thể được nhúng trong các đối tượng đồ hoạ trong tài liệu. Một số đối tượng đồ hoạ, ví dụ tường quét hình ảnh là rất tốn chi phí để tạo. Nhưng để mở một tài liệu lại rất nhanh, nên chúng ta tránh tạo tất cả các đối tượng chi phí lớn môĩ khi tài liệu được mở. Yêu cầu ở đây là tạo hình ảnh theo yêu cầu và hình ảnh bị ẩn đi mỗi khi trường hợp này xảy ra. Nhưng điều quan trọng là cần phải ghép tài liệu vào hình ảnh như thế nào? Và làm thế nảo mà ta ẩn đi thực tế ảnh được tạo theo yêu cầu như thế nào nên không cần phức tạp cài đặt soạn thảo. Giải pháp là sử dụng một đối tượng khác, một hình ảnh proxy, hoạt động với mục đích thay thế cho hình ảnh thật. Hình ảnh proxy tạo hình ảnh thật chỉ khi soạn thảo tài liệu yêu cầu hiển thị bằng cách gọi hàm Draw của nó. Proxy hướng các yêu cầu sau một cách trực tiếp tới hình ảnh. Vì vậy cần giữ mối liên quan đến hình ảnh sau khi nó được tạo ra. Giả sử các hình ảnh được lưu trong các file chia nhỏ. Trong trường hợp này, chúng ta có thể sử dụng tên file như là một tham chiếu đến đối tượng thực. Trình soạn thảo tài liệu truy xuất đến hình ảnh nhúng thông qua giao diện được định nghĩa bởi lớp đồ hoạ ảo. ImageProxy là một lớp cho hình ảnh tạo ra theo yêu cầu, và nó duy trì tên file như là một tham chiếu tới hình ảnh trên đĩa. Nó cũng lưu giới hạn của hình ảnh và tham chiếu đến thể hiện hình ảnh thực. Tham chiếu này sẽ không có giá trị cho đến khi proxy khởi tạo hình ảnh thực. Hàm Draw đảm bảo hình ảnh được khởi tạo trước khi hướng đến các yêu cầu. GetExtend đưa ra yêu cầu tới hình ảnh, chỉ khi nó được khởi tạo; mặt khác ImageProxy trả lại giới hạn mà nó lưu trữ. Ứng dụng Proxy có thể được áp dụng bất cứ khi nào có nhu cầu để làm tăng tính chuyển đổi đa chiều và phức tạp tới một đối tượng hơn là một con trỏ đơn giản. Có một số điều kiện khi áp dụng Proxy mẫu : Remote proxy cung cấp việc biểu diễn cục bộ cho đối tượng trong các không gian địa chỉ khác nhau. Proxy ảo tạo ra các đối tượng chi phí cao dựa trên yêu cầu. Proxy bảo vệ kiểm soát truy xuất đến đối tượng thông thường. Các proxy bảo vệ thường hữu ích khi các đối tượng có quyền truy cập khác nhau. Tham chiếu thông minh là sự thay thế cho một con trỏ rỗng để thực hiện các hoạt động thêm vào khi một đối tượng được truy xuất, Đếm số tham chiếu với đối tượng thực để nó có thể tự động giải phóng khi không có tham chiếu nào nữa. Tải đối tượng lưu vào bộ nhớ khi tham chiếu lần đầu. Kiểm tra xem đối tượng thực sao cho nó bị khoá trước khi truy xuất để đảm bảo không có đối tượng nào có thể thay thế nó. Cấu trúc: Client Subject Request() RealSubject->Request() Subject Request() Subject Request() …. Biểu đồ đối tượng của cấu trúc proxy tại thời gian chạy. aClient subject aProxy realSubject aRealSubject Thành phần: Proxy: Duy trì một tham chiếu cho phép proxy truy cập chủ đề thực. Proxy có thể liên quan đến Subject nếu các giao diện của RealSubject và Subject là như nhau. Cung cấp giao diện giống như của Subject để proxy có thể thay cho chủ thể thực. Điều khiển truy cập đến chủ thể thực và có chức năng tạo và xoá nó. Một số nhiệm vụ khác phụ thuộc vào kiểu proxy. Remote proxy có chức năng mã hoá yêu cầu và đối số của nó; dùng để gửi lệnh đã được mã hoá đến chủ thể thực vào những không gian địa chỉ khác nhau. Virtual proxy có thể lưu giữ thêm thông tin về chủ thể thực để chúng có thể trì hoãn việc truy cập nó. Protection proxy: kiểm tra xem người gọi có chấp nhận truy cập để thực hiện yêu cầu. Subject: Định nghĩa một giao diện chung cho RealSubject và Proxy nên một Proxy có thể được sử dụng bất kỳ nơi đâu mà RealSubject mong muốn. RealSubject: Định nghĩa một đối tượng thực mà proxy biểu diễn. Phối hợp cộng tác Proxy hướng yêu cầu đến chủ thể thực khi thích hợp, phụ thuộc vào từng dạng của proxy. Kết quả. Proxy giới thiệu ở cấp độ gián tiếp khi truy cập đối tượng. Sự bổ sung gián tiếp có nhiều công dụng tuỳ thuộc vào loại proxy. Remote proxy có thể ẩn đi thực tế rằng một không gian địa chỉ ở trong một không gian địa chỉ khác. Virtual Proxy có thể được biểu diễn sự tối ưu như việc tạo ra một đối tượng theo yêu cầu. Còn một vấn đề tối ưu hoá nữa là Proxy có thể ẩn đi từ phía client. Được gọi là sao chép dựa trên ghi lưu, và có liên quan đến việc khởi tạo yêu cầu. Việc sao chép đối tượng lớn và phức tạp có thể là một hoạt động tốn kém. Nếu bản sao chép không bao giờ được sửa đổi thì nó sẽ không phải chịu chi phí này. Bằng việc sử dụng một proxy để làm chậm quá trình sao chép, ta đảm bảo rằng chỉ phải trả chi phí sao chép đối tượng khi mà nó được sửa đổi. Để làm sao chép dựa trên ghi lưu, chủ thể phải được tham chiếu. Việc sao chép proxy sẽ chẳng thực hiện được gì nhiều hơn việc gia tăng tham chiếu này. Chỉ khi client yêu cầu một hoạt động để sửa đổi chủ thể làm cho proxy thực sự sao chép nó. Trong trường hợp đó, Proxy buộc phải giảm tham chiếu của chủ thể . Khi tham chiếu này tiến đến 0, chủ thể bị xoá. Sao chép dựa trên lưu ghi có thể giảm chi phí đáng kể đối với chủ thể lớn. Cài đặt Proxy có thể khai thác các đặc điểm ngôn ngữ sau : Quá tải thành viên truy cập thao tác trong C++. Proxy không cần biết dạng của đối tượng thật. Những mẫu liên quan: Adapter: Một adapter cung cấp một giao diện khác tới đối tượng nó điều biến. Theo mục đích này, proxy cung cấp giao diện tương tự như là chủ thể của nó. Decorator: Mặc dù decorator có thể có các thực hiện giống nhau như proxy, decorator có mục đích khác nhau. Một decorator thêm một hoặc nhiều hơn nhiệm vụ tới đối tượng, vị trí mà proxy kiểm soát việc truy cập đến đối tượng. Kết luận: Adaptor và Bridge có một số thuộc tính giống nhau. Cả hai mẫu này đều tăng cường tính linh động bởi việc cung cấp một mức gián tiếp tới đối tượng khác. Cả hai mẫu này đều liên quan tới những yêu cầu đối với đối tượng này từ một giao diện. Sự khác nhau chủ yếu giữa hai mẫu này dựa vào những mục đích riêng của nó. Adadaptor tập trung giải quyết sự không tương đồng giữa hai giao diện hiện có, nó không tập trung vào các giao diện này được thực hiện như thế nào, hoặc có được coi là có hoạt động độc lập hay không. Đó là cách để tạo hai lớp thiết kế độc lập cùng hoạt động với nhau. Bridge trái lại kết nối một khái niệm trừu tượng với các bước thực hiện của nó. Nó cung cấp một giao diện ổn định đến các đối tượng khác ngay cả khi nó giúp bạn phân biệt các lớp thực hiện nó, đồng thời định vị trí các bước thực hiện mới trong hệ thống có liên quan. Sự khác nhau giữa Adaptor mẫu và Bridge là thường được sử dụng tại những điểm khác nhau trong vòng đời của phần mềm . Một adaptor đều trở nên cần thiết khi bạn nhận thấy rằng hai lớp đối xứng nhau nên hoạt động cùng nhau nhìn chung để tránh việc mã phụ thuộc, việc kết nối là không thể thấy trước được; Ngược lại người sử dụng mỗi Bridge phải hiểu được trước rằng, mỗi trừu tượng phải có một số bước thực hiện và cả hai có thể liên quan đến nhau. Adaptor mẫu giúp chương trình hoạt động sau khi chúng được tạo ra, còn bridge mẫu làm cho chương trình hoạt động trước khi chúng được tạo ra. Điều đó không có nghĩa là adaptor mẫu kém tính năng hơn Bridge. Mỗi một mẫu này giải quyết một vấn đề khác nhau. Có thể coi giao diện là một adadaptor, nhưng việc thông dịch đã chỉ ra thực tế là giao diện sẽ xác định một giao diện mới và bất cứ lúc nào một adaptor mẫu được tái sử dụng. Lưu ý rằng một Adaptor mẫu giúp hai giao diện đồng thời tồn tại và hoạt động cùng nhau để tạo ra một giao diện mới. Tương quan giữa Composite, Decorator và Proxy. Composite và Decorator có các biểu đồ cấu trúc giống nhau và phản ánh thực tế là cả hai Composite và decorator đều phụ thuộc vào thành phần kết cấu để tạo một số đối tượng đóng mở. Điểm chung này có thể giúp bạn nghĩ tới một đối tượng bổ trợ như một phương tiện kết nối. Nhưng đặc điểm này không đúng với đặc điểm của mẫu Decorator . Sự giống nhau là ở những điểm nối và lặp lại với những mục đích khác nhau. Decorator được thiết kế nhằm cung cấp tính năng cho các đối tượng không có các lớp Composite. Decorator tránh được sự nổ của lớp Composite mà xuất phát từ tính năng của các điểm nối có liên quan, có thể được xử lý đồng loạt ở nhiều đối tượng. Sự tập trung của nó không đồng loạt mà tiêu biểu. Những mục đích này là rõ ràng nhưng không bổ trợ cho nhau. Kết quả là Decorator và Composite thường được sử dụng phối hợp với nhau. Sẽ có một lớp ảo và một số các lớp Compositen có thể được kết hợp với nhau, một vài trong số đó là các Decorator và một số khác thực hiện xây dựng hệ thống. Trong trường hợp này, cả hai Composite và Decorator sẽ có một giao diện chung. Theo Decorator mỗi kết cấu là thành phần cơ bản. Theo Composite mỗi Composite là một lá. Tất nhiên chúng không sử dụng với nhau khi ta nhận thấy điều này, mục đích thực hiện của chúng là khác nhau. Mẫu có cấu trúc giống Decorator là Proxy. Cả hai mẫu này mô tả cách cung cấp một cấp độ hướng gián tiếp tới một đối tượng và sự thực hiện của cả proxy và Decorator nhằm thông báo cho đối tượng khác đã được yêu cầu, tuy nhiên chúng lại được thiết kế với các mục đích khác nhau Cũng giống như Decorator, Proxy thiết lập đối tượng và cung cấp giao diện xác định cho client. Không giống như Decorator , Proxy không liên quan đến việc tiếp xúc và tháo gỡ các thiết bị và đồng thời không được thiết kế cho các thành phần kết cấu. Mục đích của nó là cung cấp vị trí cho các đối tượng khi không thuận tiện khi không để truy nhập đối tượng một cách trực tiếp. Trong Proxy mẫu các đối tượng xác định chức năng chính và tiếp cận tới chúng, trong Decorator thành phần kết cấu cung cấp một số bộ phận của chức năng nhiều hơn các de còn lại. Decorator xác định vị trí mà một chức năng cả các đối tượng có thể được quyết định tại một tệp thời gian, ít nhất là không thuận lợi. Sự đóng mở làm cho thành phần kết cấu trở nên cần thiết cho de. Trường hợp này không giống đối với Proxy, vì Proxy tập trung vào mối liên quan giữa Proxy và đối tượng của nó. Mối liên quan này có thể được giải thích bằng số liệu. Sự khác nhau này là rất cơ bản, vì chúng có các phương pháp giải quyết tiêu biểu trong việc thiết kế hướng đối tượng, nhưng điều này không có nghĩa là các mẫu này không thể nối kết với nhau. Bạn có thể nhận thấy, Proxy và de bổ trợ các chức năng tới một Proxy hoặc một Decorator riêng rẽ. Và rút ngắn khoảng cách giữa các đối tượng, mặc dù sự kết hợp này có thể có ích, nhưng cũng cần phải quyết định mẫu nào hữu ích hơn. Các mẫu hoạt động (BEHAVIOR Pattern) BEHAVIOR Pattern được quan tâm với các thuật toán và nhiệm vụ quyền hạn giữa các đối tượng. BEHAVIOR MẫU chỉ mô tả các mẫu của các đối tượng hoặc các lớp mà còn các mẫu của truyền thông giữa chúng. Những mẫu này mô tả luồng điều khiển phức tạp mà khó có thể theo tại run- time. Các mẫu lớp Behavior sử dụng tính kế thừa để sắp xếp hoạt động giữa các lớp: Template method : là một định nghĩa trừu tượng của một thuật toán. Interpreter Biểu diễn ngữ pháp như là biểu đồ lớp và thực hiện interpreter như là một thao tác trong trường hợp của những lớp này. Các mẫu đối tượng Behavior sử dụng kết cấu đối tượng hơn là tính kế thừa, một số mô tả một nhóm các đối tượng ngang bằng hợp tác để hoàn thành một nhiệm vụ mà không đối tượng riêng lẻ nào có thể tự thực hiện được. Một số mẫu đối tượng hoạt động thường liên quan đến hoạt động bao gói trong một đối tượng và uỷ quyền tới chúng. Các mẫu thường xác định một lớp trừu tượng, mô tả đối tượng một cách vắn tắt và các mẫu này có tên lấy được từ tên của đối tượng. Đối tượng Strategy rút gọn thuật toán Đối tượng State rút gọn một hành vi độc lập Đối tượng Mediator rút gọn giao thức giữa các đối tượng. Đối tượng Iterator rút gọn phương pháp truy nhập các thành phần. CHAIN OF RESPONSIBILITY. Mục đích Tránh tổ hợp nơi gửi các yêu cầu tới nơi nhận của nó bằng cách đưa ra hơn một đối tượng điểu kiện để nắm bắt yêu cầu. Tổ hợp các đối tượng nhận và chuyển yêu cầu dọc theo tổ hợp này tới khi một đối tượng nắm giữ được nó. Ứng dụng: Nhiều hơn một đối tượng có thể nắm giữ yêu cầu. Handler có thể được xây dựng một cách tự động. Cần đưa ra một yêu cầu tới một trong nhiều đối tượng không cần xác định nơi nhận một cách rõ ràng. Một tập các đối tượng mà có thể nắm giữ các yêu cầu nên được định nghĩa động. Client Handler HanhdleRequest() Handler HanhdleRequest() Handler HanhdleRequest() successor Cấu trúc: Cấu trúc đối tượng có thể được xem xét thông qua: aClient aHandler aConcreteHandler successor aConcreteHanhdler successor Thành phần: Hander: định nghĩa một giao diện cho việc nắm giữ các yêu cầu. (optional) thực hiện kết nối kế tiếp. ConcreteHandler: Nắm giữ các yêu cầu nó chịu trách nhiệm tới. Có thể truy cập tới thành phần kế tiếp của nó. Nếu ConcreteHandler có thể nắm giữ các yêu cầu, nó cũng làm được, mặt khác nó hướng các yêu cầu tới thành phần kế tiếp của nó. Client. khởi tạo cyêu cầu tới đối tượng ConcreteHandler trên chuỗi. Kết quả Giảm thiểu sự kết hợp Thêm tính linh hoạt trong việc ấn định trách nhiệm tới các đối tượng. Chain of Responsibility đưa bạn thêm tính linh hoạt trong việc phân phối trách nhiệm giữa các đối tượng, có thể thêm vào hoặc thay đổi trách nhiệm chuỗi tại thời gian chạy. Xác nhận không được đảm bảo : Từ lúc một yêu cầu không có nơi nhận chắc chắn, không có đảm bảo nếu nó được nắm giữ, yêu cầu có thể bị rơi xuống điểm cuối của chuỗi mà không được giữ. Một yêu cầu có thể không được nắm giữ khi chuỗi không được cấu hình đúng cách. Cài đặt Việc thực hiện một chuỗi kế tiếp. Có hai cách để thực hiện một chuỗi thành công. Đó là: Xác định các liên kết mới, sử dụng kết nối hiện tại, kết nối các kế tiếp, biểu diễn các yêu cầu. Mẫu liên quan: Chain of Responsibility thường được áp dụng cùng với Composite. Thành phần cha có thể hoạt động như là thành phần kế tiếp của nó. COMMAND. Mục đích Bao gói một yêu cầu như là một đối tượng bằng cách đó cho phép bạn tham số hoá client cùng các yêu cầu, hàng đợi khác nhau hoặc chặt các yêu cầu, và đưa ra các thao tác không thể xoá được. Ứng dụng Tham số hoá các đối tượng bằng tác động để thực hiện. Định nghĩa xác định hàng đợi và thực hiện các yêu cầu tại các thời điểm khác nhau. Một đối tượng Command có thể có thời gian sống không phụ thuộc vào yêu cầu gốc. Hỗ trợ cho việc làm lại. Hỗ trợ việc loại bỏ các thay đổi nên chúng có thể được áp dụng lại trong trường hợp phá vỡ hệ thống. Cấu trúc một hệ thống theo chiều hướng các thao tác mức cao trong các thao tác ban đầu. Như một cấu trúc là thông thường trong các hệ thống thông tin mà cung cấp việc thực hiện. Một chuyển tiếp đóng gói một tập các thay đổi đến dữ liệu. Command có giao diện chung, cho phép bạn gọi tất cả các thực hiện theo cùng một cách. Thành phần: Command Khai báo một giao diện cho việc thực hiện một thao tác. ConcreteCommand Định nghĩa ràng buộc giữa đối tượng Nơi nhận và một action. Thực hiện Execute bằng gọi ra thao tác chịu trách nhiệm on Nơi nhận. Client Tạo một đối tượng ConcreteCommand và thiết lập nơi nhận của nó. Invoker hỏi command để thực hiện yêu cầu. Nơi nhận Cho biết làm thế nào để thực hiện các thao tác kết nối tới việc thực hiện một yêu cầu. Bất kỳ một lớp nào có thể phục vụ như một Nơi nhận. Cộng tác: Client tạo đối tượng ConcreteCommand và xác định nơi nhận của nó. một đối tượng Invoker lưu trữ đối tượng ConcreteCommand. Việc gọi ra kết quả là một yêu cầu bằng việc gọi ra Execute dựa trên command. Khi một command có thể được phá vỡ, ConcreteCommand lưu trạng thái cho việc phá vỡ command trước khi gọi đến Execute. Đối tượng ConcreteCommand gọi các thao tác trên nơi nhận của nó để thực hiện yêu cầu. Kết quả: Command phân tách đối tượng mà gọi thao tác từ đối tượng mà biết làm thế nào để thực hiện nó. Các Command là các đối tượng lớp đầu tiên. Chúng có thể được đánh tín hiệu hoặc mở rộng giống như bất kỳ một đối tượng nào khác. Bạn có thể cài đặt các yêu cầu tới yêu cầu phức hợp dễ dàng để thêm một yêu cầu, do bạn không cần thay đổi các lớp hiện có. Cài đặt Độ thông minh như thế nào mà một yêu cầu có thể có? Chỉ đơn thuần là định nghĩa sự liên kết giữa nơi nhận và các hoạt động để đưa ra yêu cầu. Thực hiện mọi thứ bằng chính nó mà không cần việc uỷ quyền tới một nơi nhận trong tất cả. Khi muốn định nghĩa các yêu cầu mà không phụ thuộc vào các lớp hiện tại, khi không có nơi nhận phù hợp tồn tại, hoặc khi có yêu cầu biết nơi nhận một cách chính xác. Hỗ trợ undo và redo : Các yêu cầu có thể hỗ trợ undo và redo nếu cung cấp phương pháp để đảo ngược chiều việc thực hiện của chúng. Tránh lỗi chồng chất trong xử lý undo : Hiện tượng trễ có thể có vấn đề trong đảm bảo tin cậy, Lỗi có thể bị tích lại như các yêu cầu đã thực hiện, không được thực hiện và được thực hiện lại, lặp lại. Các mẫu liên quan: Một composite có thể được sử dụng để thực hiện MacroCommands. Một Memento có thể giữ trạng thái các yêu cầu command để thực hiện lại hiệu quả của nó. một yêu cầu mà phải được copy trước khi thực hiện trên các hoạt động của history danh sáchs như là Prototype. INTERPRETER Mục đích Đưa ra một ngôn ngữ, định nghĩa một biểu diễn cho ngữ pháp của nó cùng với một phiên dịch sử dụng việc biểu diễn để giải thích các câu trong ngôn ngữ. Ứng dụng Sử dụng Interpreter khi có một ngôn ngữ để thông dịch, và ta cần biểu diễn các câu lệnh trong ngôn ngữ dưới dạng cây cú pháp trừu tượng Sử dụng tốt nhất khi Ngữ pháp đơn giản Tính hiệu quả không phải là mối quan tâm hàng đầu. Cấu trúc: Client AbstracExpression \Interpret(Context) TerminalExpression Interpret(Context) NonterminalExpression Interpret(Context) Context Thành phần: AbstractExpression. Khai báo một thao tác trừu tượng Interpret là chung cho tất cả các nút trong cây cú pháp trừu tượng. TerminalExpression Thực hiện thao tác Interpret kết hợp với các ký pháp cuối trong ngữ pháp. một instance được yêu cầu cho mọi ký tự cuối trong câu.s NonterminalExpression Một lớp được yêu cầu cho mọi quy tắc R::= R1 R2 R3…….. Rn trong ngữ pháp. Duy trì các biến của dạng AbstractExpression cho các ký pháp R1 đến Rn . Thực hiện một thao tác Interpret cho các ký pháp không kết thúc trong ngữ pháp. Interpret gọi đệ quy chính nó trong các biến biểu diễn R1 đến Rn. Context chứa thông tin toàn cục tới phần phiên dịch. Client Xây dựng(hoặc được đưa tới) một cây cú pháp trừu tượng biểu diễn thành phần câu trong ngôn ngữ mà ngữ pháp định nghĩa. Cây cú pháp trừu tượng được nhúng từ thể hiện của NonterminalExpression vào lớp TerminalExpression. Gọi ra thao tác Interpret. Cộng tác: Client xây dựng một câu như là cây cú pháp trừu tượng của một thể hiện NonterminalExpresion và TerminalExpression. Sau đó client khởi tạo ngữ cảnh và gọi thao tác Interpret. Mỗi nút NonterminalExpression định nghĩa Interpret trong trường hợp của Interpret trong từng biểu thức con. Thao tác Interpret của từng TerminalExpression định nghĩa trường hợp gốc của việc đệ quy. Các thao tác Interpret tại mỗi nút sử dụng ngữ cản để lưu và truy cập trạng thái của interpreter. Kết quả Dễ dàng mở rộng và thay đổi ngữ pháp : do các mẫu sử dụng các lớp để biểu diễn các quy tắc ngữ pháp, cần sử dụng tính kế thừa để thay đổi hoặc mở rộng cú pháp. Các biểu thức hiện tại có thể được modified một cách gia tăng, và các biểu thức mới có thể được định nghĩa như là variation trên các biểu thức cũ. Việc thực hiện ngữ pháp cũng đơn giản, Các lớp xây dựng nút trong tầng cú pháp trừu tượng có các thực hiện giống nhau. Những lớp này thường dễ ghi, và thường là thế hệ của chúng có thể tự động với các biên dịch hoặc bộ sinh cú pháp. Các cú pháp phức tạp thường khó để bảo trì. Thêm vào các phuơng pháp mới để giải thích các biểu thức. Cài đặt Tạo cây cú phápabstract ( không giải thích làm thế nào để tạo một cây cú pháp trừu tượng). Định nghĩa một thao tác Interpreter : không phải định nghĩa thao tác Interpreter trong biểu thức lớp. Sử dụng các kí hiệu cuối với mẫu Flyweight. Các mẫu liên quan: Composite: Cây cú pháp trừu tượng là một trường hợp của Composite. Flyweight chỉ ra làm thế nào để sử dụng chung các ký pháp cuối trong cây cú pháp trừu tượng. Iterator: Interpreter có thể sử dụng Iterator để chuyển đổi cấu trúc. Visitor có thể được dùng để duy trì hoạt động trong từng nút trong cây cú pháp trừu tượng trong một lớp. ITERATOR Mục đích Đưa ra một phương pháp để truy xuất các thành phần của các đối tượng kết tập một cách tuần tự không cần giải thích bằng cách mô tả ở dưới. Một đối tượng tập hợp như là một danh sách có thể cho bạn phương pháp để truy cập các thành phần của chúng không cần giải thích cấu trúc bên trong của nó, hơn nữa, cần phải thực hiện các danh sách này bằng nhiều phương pháp khác nhau, phụ thuộc vào bạn thực hiện như thế nào. Nhưng bạn có thể không cần mở rộng giao diện danh sách với các thao tác cho nhiều việc chuyển đổi khác nhau. Ứng dụng Để truy cập các nội dung của đối tượng tập hợp mà không cần giải thích các biểu diễn bên trong. Hỗ trợ các đa chuyển đổi của các đối tượng tập hợp. Cung cấp một giao diện đồng đều cho các cấu trúc tập hợp khác nhau( có nghĩa là để xác nhận bước lặp đa hình). Aggregate CreateIterator() Iterrator First() Next() IsDone() CurrentItem() ConcreteAggregate Createiterator() Return new ConcreteIterator(this) Concreteiterator Client Cấu trúc: Thành phần: Iterator Định nghĩa một giao diện cho việc truy cập và chuyển đổi các thành phần. ConcreteIterator Thực hiện giao diện Iterator. giữ một chuỗi vị trí hiện tại trong chuyển đổi của một kết tập. Aggregate Định nghĩa một giao diện cho việc tạo một đối tượng Iterator. ConcreteAggregate Thực hiện giao thức tạo Iterator để đưa ra một trường hợp ConcreteIterator phù hợp. Cộng tác: Một ConcreteIterator giữ một chuỗi đối tượng hiện tại trong một kết tập và có thể tính toán đối tượng tiếp theo trong một chuyển đổi. Kết quả Chu cấp các phép biên đổi trong chuyển đổicủa một tập hợp. Các tập hợp phức tạp có thể được duyệt bằng nhiều cách. Các Iterator làm đơn giản hoá giao diện tương thích. Nhiều hơn một chuyển đổi có thể sẽ xảy ra trong một tập hợp. Cài đặt Iterator có nhiều thực hiện sự biến đổi và sự lựa chọn cân bằng thường phụ thuộc vào việc kiểm soát cấu trúc ngôn ngữ của bạn cung cấp. Ai kiểm soát các bước lặp : quyết định xem iteration hay client. Nếu client kiểm soát thì iterator được gọi là external iterator và ngược lại là internal iterator. Ai định nghĩa giải thuật chuyển đổi. Tính thiết thực của iterator. Có thể nguy hiểm khi sửa đổi một tập hợp trong khi chúng ta đang chuyển đổi. Nếu thành phần được thêm hoặc xoá từ tập hợp có thể kết thúc truy nhập một thành phần hai lần hoặc bỏ qua nó một cách hoàn toàn. Một giải pháp đơn giản là sao chép kết tập và chuyển bản sao chép này . Các thao tác Iterator được thêm vào. Sử dụng các iterator đa hình trong C++. Iterator có thể truy cập đặc quyền. Các Iterator cho các thành phần. Các mẫu liên quan: Composite: Interator thường được áp dụng vào các cấu trúc đệ quy như là Composite. Factory Method: Các Interator đa hình dựa vào factory method để giải thích cụ thể về lớp con Iterator thích hợp. Memento thường được dùng cùng với Iterator mẫu. Một iterator có thể được sử dụng memento để thu được trạng thái của iteration. Iterator lưu vào memento bên trong. MEDIATOR. Mục đích Định nghĩa một đối tượng bao gói một tập các đối tượng tương tác với nhau như thế nào. Memento tăng độ tổ hợp bằng cách giữ các đối tượng khỏi các liên quan lẫn nhau, và nó cho phép thay đổi tương tác một cách độc lập. Ứng dụng Một tập các đối tượng kết nối trong các trường hợp định nghĩa tốt nhưng phức tạp. Việc đưa ra kết quả độc lập là không cấu trúc được và khó hiểu. Việc sử dụng lại một đối tượng là khó do nó có liên quan đến và kết nối với nhiều đối tượng khác. Một hoạt động mà nó được phân phối giữa một vài các lớp có thể tuỳ biến không cần phân lớp. Mediator Colleague ConcreteMediator ConcreteColleaguemột ConcreteColleague2 Cấu trúc: Cấu trúc đối tượng đặc biệt có thể được nhìn dưới dạng aColleague mediator aColleague mediator aConcreteMediator aColleague mediator aColleague mediator aColleague mediator MEMENTO. Mục đích Không cần can thiệp vào việc bao gói, kết quả và mở rộng trạng thái bên trong của đối tượng nên một đối tượng có thể được khôi phục lại tại trạng thái sau đó. Ứng dụng Một snapshot của trạng thái của đối tượng phải được lưu nên nó có thể được phục hồi tới trạng thái sau đó. Một giao diện trực tiếp để thu được trạng thái có thể đưa ra cài đặt chi tiết và phá vỡ sự đóng gói của đối tượng. Cấu trúc: Originator SetMemento(Memento m) CreateMemento() state Memento GetState() SetState() state Caretaker return new Memento(state) State = m->GetState() memento Thành phần: Memento: Lưu trạng thái trong của đối tượng Originator. Memento có thể lưu như nhiều hoặc một ít trạng thái trong của orginator như cần thiết tại việc thận trọng orginator của nó. Bảo vệ truy cập ngược (against) bởi các đối tượng hơn là originator. Các memento đạt hiệu quả với hai giao diện. Caretaker xem xét các giao diện hẹp tới Memento- nó có thể chỉ thông qua memento tới đối tượng khác. Originator, được xem như một giao diện rộng, nó cho phép việc truy cập tới tất cả các dữ liệu cần thiết để lưu trữ bản thân nó vào trạng thái trước. Một cách lí tưởng, chỉ có originator tạo ra memento có thể cho phép truy cập trạng thái bên trong của memento. Originator. Tạo một memento để lưu một snapshot của trạng thái bên trong hiện tại. sử dụng memento để lưu trữ trạng thái bên trong của nó. Caretaker; Có chức năng đối với việc giữ an toàn của memento. Không bao giờ thao tác hoặc thử nghiệm nội dung của memento. Cộng tác: Một Caretaker yêu cầu một Memento từ một Originator, giữ nó một thời gian, và chuyển nó ngược lại tới originator. Đôi khi một Caretaker không chuyển Memento ngược lại tới Orginator, do Originator có thể không bao giờ cần revert tới trạng thái sớm hơn. Memento là bị động, Chỉ có originator tạo ra memento sẽ đăng nhập hoặc thử lại trạng thái của nó. Kết quả Đảm bảo giới hạn đóng gói. Đơn giản hoá Originator. Sử dụng các memento có thể rất đắt. Định nghĩa các giao diện rộng và hẹp. Cài đặt Hỗ trợ ngôn ngữ Memento có hai giao diện : Một cho Origiano, một cho các đối tượng khác. Lưu trữ các thay đổi gia tăng. Các mẫu liên quan: Command: Command có thể sử dụng memento để duy trì trạng thái của các thao tác có thể thực hiện lại. Iterator: Memento có thể được sử dụng cho iteration như được mô tả ở trên. OBSERVER. Mục đích Định nghĩa sự phụ thuộc một - nhiều giữa các đối tượng nên khi một đối tượng thay đổi trạng thái, tất cả các phụ thuộc vào chúng cũng được thông báo và tự động thay đổi theo. Ứng dụng Khi một khái niệm trừu tượng có hai khía cạnh, một cái phụ thuộc vào cái khác. Sự đóng gói những khía cạnh này trong các đối tượng phân chia cho phép bạn thay đổi và sử dụng lại chúng một cách độc lập. Khi thay đổi tới một đối tượng yêu cầu thay đổi những cái khác, và bạn không biết được bao nhiêu đối tượng sẽ phải thay đổi. Khi một đối tượng sẽ được biết những đối tượng khác không cần giả định về những đối tượng này là ai. Trong khía cạnh khác, bạn không cần biết những đối tượng này được kết hợp chặt chẽ. Kết quả Cho phép biến đổi các đối tượng và observer một cách độc lập, do đó có thể sử dụng lại subject không cần sử dụng lại observer và thay thế riêng lẻ. Cho phép bạn thêm vào observer không cần sửa đổi chủ thể hoặc các quan sát khác. Ngoài ra còn có sự kết hợp trừu tượng Subject và Observer. Hỗ trợ cho truyền thông quảng bá. Những cập nhật đột xuất. Cài đặt Ánh xạ các chủ thể sang vật quan sát của chúng. Quan sát nhiều hơn một đối tượng. Ai tạo ra các cập nhật thao tác thiết lập trạng thái trong Subject gọi Notify sau khi chúng thay đổi trạng thái Subject. Do đó client không cần nhớ lời gọi Notify trên Subject, nhưng một số thao tác liên tiếp sẽ gây ra liên tiếp các cập nhật mà có thể không mang lại hiệu quả. Làm cho các client có nhiệm vụ để gọi Notify đúng thời điểm, do đó client có thể chờ để tạo cập nhật sau khi các trạng thái đã được thay đổi. Nhưng không có thêm được các cập nhật tạo cần thiết ngay sau đó. Việc tham khảo ý kiến để xoá các đối tượng không dứt khoát. Xác định các sự biến đổi của quyền lợi một cách rõ ràng. Bao gói các cú pháp cập nhật phức tạp. Kết nối các lớp Subject và Observer. STATE. Mục đích Cho phép một đối tượng thay đổi các hoạt động của nó khi trạng thái bên trong của nó thay đổi. Đối tượng sẽ xuất hiện để thay đổi lớp đó. Ứng dụng Một hoạt động của đối tượng phụ thuộc vào trạng thái của nó, và nó phải thay đổi hoạt động của nó tại thời gian chạy phụ thuộc vào trạng thái đó. Các thao tác có lớn, các biểu thức điều kiện đa thành phần mà phụ thuộc vào trạng thái của đối tượng. Trạng thái này thường được biểu diễn bởi một hoặc nhiều hằng số được cho trước. State sắp đặt từng nhánh của điều kiện trong lớp phân chia. Điều này cho phép bạn xử lý trạng thái của đối tượng như là một đối tượng trong điều kiện đúng mà có thể biến đổi độc lập từ các đối tượng khác. Cấu trúc: Context Request() State Hander () ConcreteStateA Handler() State->Hander () ConcreteStateB Handler() Thành phần: Context Định nghĩa một giao diện tới các client. Duy trì một trường hợp của ConcreteSubclass để định nghĩa trạng thái hiện tại. State Định nghĩa một giao diện cho việc bao gói các hoạt động cùng với trạng thái riêng biệt của Context. ConcreteState subclass. Mỗi lớp con thực hiện một hoạt động cùng với trạng thái của Context. Kết qủa Khoanh vùng hoạt động trạng thái đã chỉ ra và phân chia hoạt động cho các trạng thái khác nhau. State mẫu sắp xếp tất cả các hoạt động kết nối với trạng thái thành phần vào một biến đối tượng. Làm cho các chuyển đổi trạng thái rõ ràng, dứt khoát. Các đối tượng trạng thái có thể bị chia sẻ. Cài đặt Ai định nghĩa các chuyển đổi trạng thái. Tạo và phá bỏ các đối tượng trạng thái. Sử dụng tính kế thừa động. STRATEGY. Mục đích Định nghĩa một họ các thuật toán, bao gói từng thuật toán, và làm cho chúng có thể thay thế được. Strategy cho phép thuật toán biến đổi độc lập từ các client sử dụng nó. Ứng dụng Một số các lớp quan hệ khác nhau duy nhất với các quan hệ của chúng. Các Strategy cung cấp một cách để cấu hình lớp với một trong nhiều hoạt động. Cần nhiều biến đổi khác nhau của một thuật toán. Một thuật toán sử dụng dữ liệu mà client không biết về nó. Sử dụng Strategy mẫu để tránh được việc đưa ra phức tạp, các cấu trúc dữ liệu thuật toán đã chỉ ra. Một lớp xác định nhiều hoạt động, và những biểu hiện này như các câu lệnh đa điều kiện trong các thao tác của nó. Thay cho một số các điều kiện, dịch chuyển các nhánh điều kiện quan hệ tới lớp strategy của nó. Kết quả. Các họ của các thuật toán quan hệ. Một lựa chọn tới phân lớp con. Các strategy khử biểu thức điều kiện. Một chọn lựa trong các thực hiện. Có strategy có thể cung cấp các cách thực hiện khác nhau của cùng một hoạt động. Client có thể chọn lựa giữa các strategy với thời gian khác nhau, không gian và cân bằng khác nhau. Kết nối trên giữa Strategy và Context. Client phải có hiểu biết về các Strategy khác nhau. Gia tăng số lượng các đối tượng. Cài đặt Việc thực hiện các giao diện Strategy và Context Các strategy như là các tham số nhãn. Tạo các đối tượng strategy mang tính mặc định. TEMPLATE. Mục đích Định nghĩa khung của một thuật toán trong thao tác, dựa theo một số bước tới các lớp con. Template cho phép các lớp con định nghĩa lại một số bước nào đó của thuậtt toán mà không cần thay đổi cấu trúc của thuật toán. Ví dụ Template method định nghĩa một thuật toán dưới dạng các thao tác trừu tượng mà các lớp con ghi đè lên để cung cấp các hoạt động cụ thể. Bằng việc định nghĩa một số bước trong thuật toán sử dụng các thao tác trừu tượng , template method gắn các t ứ tự này, nhưng nó cho phép các lớp con có thể biến đổi những bước này để phù hợp với yêu cầu của chúng. Ứng dụng Dùng Template Method mẫu khi: Để thực hiện các phần bất biến của thuật toán và rời nó tới các lớp con để thực hiện hoạt động mà nó có thể biến đổi. Khi một hoạt động chung giữa các lớp con có thể được quản lí và khoanh vùng trong lớp chung để tránh mã hoá hai lần.Trước hết, phải nhận dạng ra được sụ khác nhau trong mã có sẵn và sau đó phân chia sự khác nhau này sang một số thao tác mới. Cuối cùng, dịch chuyển các mã khác nhau này cùng với template method để gọi một trong số những thao tác mới này. Để kiểm soát được việc mở rộng. Có thể định nghĩa một template method để gọi thao tác móc nối tại các vị trí đặc biệt, từ đó cho phép việc mở rộng chỉ tại các vị trí đó. Cấu trúc: AbstractClass TemplateMethod() PrimitiveOperationmột() PrimitiveOperation2() ConcreteClass PrimitiveOperation1() PrimitiveOperatio2() PrimitiveOperation1() PrimitiveOperation2() Thành phần: AbstractClass Định nghĩa thao tác trừu tượng đầu tiên mà các lớp con thực hiện định nghĩa để thực hiện các bước của thuật toán. Thực hiện template method định nghĩa một khung của thuật toán. Template gọi các thao tác ưu tiên như là các thao tác được định nghĩa trong AbstractClass hoặc các thao tác trong các đối tượng khác. ConcreteClass. Thực hiện thao tác ưu tiên để đưa ra các bước định nghĩa - lớp con (subclass-specific) của thuật toán. Phối hợp cộng tác ConcreteClass dựa vào AbstractClass để thực hiện các bước bất biến của thuật toán. Kết quả Là một kỹ thuật cơ bản đối với việc sử dụng lại code, chúng đặc biệt quan trọng trong thư viện lớp, do chúng mang ý nghĩa cho factoring out hoạt động thông thường trong thư viện các lớp. Đưa ra một cấu trúc điều khiển đảo ngược. Gọi các loại dưới đây của thao tác. Các thao tác concrete. Các thao tác trừu tượng Các thao tác ưu tiên. Factory method. Móc nối các thao tác, cung cấp các hoạt động lựa chọn mà các lớp con có thể mở rộng nếu cần thiết. điều quan trọng đối với template Method là định nghĩa thao tác nào là móc nối, thao tác nào là trừu tượng. Để sử dụng lại lớp trừu tượng một cách hiệu quả, các writer của lớp con phải hiểu được thao tác nào được thiết kế để ghi đè lên. Cài đặt Sử dụng C++ để truy cập điều khiển. Template Method bản thân nó không bị ghi lồng lên. Tối thiểu hoá các thao tác ưu tiên. Định tên cho sự chuyển đổi. VISITOR. Mục đích Biểu diễn một thao tác được thực hiện trên tất cả các thành phần của cấu trúc đối tượng. Visitor cho phép bạn định nghĩa thao tác mới mà không cần thay đổi các lớp của các thành phần mà nó thực hiện. Ứng dụng Một cấu trúc đối tượng chứa một số lớp của đối tượng với các giao diện không giống nhau, và bạn muốn thực hiện những thao tác trên những đối tượng này mà phụ thuộc vào các lớp chắc chắn của nó. Một số thao tác rõ ràng và không cần phải thực hiện trên các đối tượng dựa trên đối tượng trong một cấu trúc đối tượng, muốn dùng để tránh làm ảnh hưởng các lớp của chúng với những thao tác này. Visitor cho phép bạn giữ các thao tác quan hệ cùng nhau bằng việc định nghĩa chúng trong một lớp. Khi cấu trúc đối tượng được sử dụng chung bởi một số ứng dụng, sử dụng Visitor để đặt thao tác trong những ứng dụng cần thiết. Những lớp xác định cấu trúc đối tượng hiếm khi thay đổi , nhưng bạn phải thường xuyên phải define những thao tác mơi trên cấu trúc. Thay đổi các lớp cấu trúc đối tượng yêu cầu việc định nghĩa lại giao diện tới tất cả các visitor, điều này là thiết yếu. Nếu các lớp cấu trúc đối tượng thay đổi thường xuyên sau đó thì tốt hơn là định nghĩa các thao tác trong những lớp đó. Kết quả Visitor làm cho việc thêm các thao tác mới dễ dàng. Một Visitor tập trung nhiều thao tác quan hệ và phân chia những thao tác không quan hệ. Việc thêm vào các lớp ConcreteElement là khó. Xem xét thông qua các biểu đồ lớp. Tổng kết lại trạng thái. Phá vỡ tinh đóng gói Cài đặt Việc phải giải quyết tăng gấp đôi. Phân quyền trách nhiệm để chuyển tải cấu trúc đối tượng. Kết luận: Chain sẽ giải quyết về số lượng các đối tượng, tất cả các đối tượng này có thê tồn tại trong cùng một hệ thống. Chain of responsibility minh hoạ những điểm khác nhau trong các bp, không phải là tất cả đều xác định các mối quan hệ giữa các lớp đối tượng này. Chain of responsibility mô tả sự tác động qua lại giữa số các đối tượng.Trong Command, Token đại diện cho một số đối tượng State tại một thời điểm xác định. Trong cả hai trường hợp này, token có thể có một đại diện phức tạp nhưng client thì chưa có điều này. Các giao diện Subject và Object trong mẫu Observer được thiết kế cho những sự thay đổi thông tin, vì vậy mẫu Observer là tốt nhất cho các đối tượng kết nối khi có các dữ liệu phụ thuộc lẫn nhau giữa chúng. Mediator mẫu kết nối các đối tượng bằng việc đề cập đến nhau gián tiếp thông qua một đối tượng mediator. Giới thiệu nội dung dự án Để sử dụng các mẫu thiết kế này cần phải dựa trên một dự án cụ thể. Trong thời gian thực tập tôi có may mắn được thực tập tại công ty sản xuất phần mềm Khai Trí và được tiếp xúc tham gia, theo dõi dự án của công ty, mà công ty đã áp dụng các mẫu thiết kế dự án cua mình. Để người đọc hiểu rõ về nội dung dự án và các ngữ cảnh trước khi đi sâu vào thiết kế, tôi xin trình bày một chương để tóm tắt nội dung của dự án và bạn đọc có thể có những hiểu biết trước khi đi sâu vào các vấn đề thiết kế chi tiết của dự án. Chương này tuy ngắn nhưng quan trọng, do nó sẽ la nền tảng định hướng cho nội dung của các chương sau. Đây là dự án đã được thực hiện và triển khai, được đưa vào hoạt động thực tiễn của công ty sản xuất phần mềm Khai Trí( 123- Triệu Việt Vương – Hà Nội) về phần mềm tra cứu pháp luật và luật việt. Ở đây tôi không nói đến tính năng cụ thể của nội dung pháp luật và luật việt, và theo tôi được hiểu thì đây là công ty chuyên về phần mềm Pháp điển và Luật việt đầu tiên ở Việt Nam. Đây là một sản phẩm phần mềm đã được thực hiện từ lâu, và đưa vào thị trường tiêu thụ hơn 5 năm, nhưng do đòi hỏi của con người cũng như tốc độ phát triển của công nghệ phần mềm, sản phẩm của công ty cần được nâng cấp để nâng cao tính năng với người sử dụng. Và đây cũng là một dự án lớn được chia thành nhiều giai đoạn, nhiều công việc và từng thành phần nhỏ một. Tôi chỉ có điều kiện theo dõi và tham gia vào một phần nhỏ của dự án, và được tạo điều kiện cả về vật chất, kinh nghiệm và thời gian để tìm hiểu, nghiên cứu về các mẫu thiết kế.

Các file đính kèm theo tài liệu này:

  • docDAN207.doc
Tài liệu liên quan