CHƯƠNG 1 TỔNG QUAN VỀ MÔ HÌNH SỬ DỤNG LẠI 1. Giới thiệu chung Thiết kế phần mềm là một công đoạn quan trọng trong quy trình xây dựng và phát triển phần mềm. Cũng nhƣ việc thiết kế phần mềm truyền thống, việc thiết kế phần mềm hƣớng đối tƣợng cần phải đáp ứng đƣợc yêu cầu của bài toán, song cũng cần có tính tổng quát và linh hoạt đủ để có thể giải quyết một phần hoặc toàn bộ các bài toán có thể gặp trong tƣơng lai. Trong quá trình xây dựng và phát triển phần mềm, các thay đổi do yêu cầu từ phía khách hàng, các điều kiện phát sinh hay việc thiết kế một cách cứng nhắc trong quá trình thiết kế thƣờng làm cho hệ thống trở nên rối rắm, các mô đun càng ngày càng bị phụ thuộc vào nhau.
Sự phụ thuộc này làm cho phần mềm ngày càng trở nên phình to và khó bảo trì, thậm chí dẫn đến thất bại. Phƣơng pháp lập trình hƣớng đối tƣợng ra đời góp phần giúp cho việc thiết kế phần mềm trở nên dễ dàng và linh động hơn. Thiết kế hƣớng đối tƣợng cho phép theo dõi và quản lý đƣợc sự phụ thuộc giữa các mô đun trong kiến trúc của hệ thống. Việc tìm cách áp dụng những mô hình đã thành công trong thực tế đối với một số bài toán tƣơng tự đã từng gặp và áp dụng những mô hình đó vào thiết kế của mình mà không cần phải xem xét lại từ đầu, đảm bảo tiết kiệm chí phí, thời gian xây dựng và phát triển phần mềm, nâng cao độ tinh cậy và chất lƣợng phần mềm.
Năm 1995, Erich Gamma, Richard Helm, Join Vlissides, và Ralph Johnson (Gang of Four) đã công bố cuốn sách của họ “Elements of reusable Object-Oriented Software” đánh dấu sự ra đời của “mẫu thiết kế”. Đây là một bƣớc tiến vô cùng quan trọng đối với việc thiết kế phần mềm hƣớng đối tƣợng. Tổng quan về các mẫu thiết kế (Design Pattern) 1. Mẫu thiết kế là gì ? 1.
Các định nghĩa về mẫu thiết kế [4,9] Mẫu thiết kế là một cặp giải pháp/vấn đề đƣợc đặt tên có thể áp dụng trong những ngữ cảnh mới và những hƣớng dẫn để áp dụng nó trong những tình huống mới nhƣ thế nào. [4] Mẫu thiết kế không đơn thuần là một bƣớc nào đó trong các giai đoạn phát triển LUAN VAN CHAT LUONG download : add luanvanchat@agmail.com -13- phần mềm mà nó đóng vai trò là sáng kiến để giải quyết một bài toán thông dụng nào đó. Các giai đoạn phần mềm vẫn hoàn chỉnh mà không có mẫu thiết kế, nhƣng sự góp mặt của mẫu thiết kế sẽ giúp cho việc xác định bài toán cần giải quyết nhanh gọn hơn, từ đó đƣa ra cách giải quyết hợp lý. [9] Mẫu thiết kế không chỉ đƣợc sử dụng để xác định bài toán và cách giải quyết mà còn đƣợc sử dụng nhằm cô lập các thay đổi trong mã nguồn, từ đó làm cho hệ thống có khả năng tái sử dụng cao do mẫu thiết kế tuân thủ rất nghiêm ngặt các nguyên lý thiết kế hƣớng đối tƣợng.
[9] Việc xác định thế nào là một mẫu thiết kế phụ thuộc vào các nhìn nhận vấn đề của mỗi ngƣời. Theo GOF, cách nhìn nhận phổ biến nhất về các mẫu thiết kế là coi chúng giống nhƣ các mô tả về các đối tƣợng phục vụ mục đích trao đổi thông tin trong quá trình thiết kế đã đƣợc hiệu chỉnh để giải quyết những yêu cầu thiết kế trong những trƣờng hợp nhất định. Các thành phần của mẫu thiết kế [8,9] Mỗi mẫu thiết kế trƣớc tiên mô tả một bài toán mà ta gặp nhiều lần rồi mô tả những yếu tố căn bản nhất để giải quyết bài toán theo cách mà ta có thể áp dụng lại nhiều lần. Dựa trên mô tả nhƣ trên về các mẫu thiết kế, ta thấy chúng bao gồm những thành phần cơ bản sau: Tên: Là tên gọi qua đó ta có thể mô tả bài toán cần giải quyết, giải pháp thực hiện hay kết quả.
Việc đặt tên mẫu thiết kế cho phép mô tả các bài toán và giải pháp một cách ngắn gọn. Tạo thành một ngôn ngữ trong cộng đồng những ngƣời thiết kế. Ví dụ, khi nói đến mẫu thiết kế “Façade”, ta hình dung ngay đến mô hình thiết kế một đối tƣợng với vai trò giao dịch của một tập các thành phần nhỏ hơn. Bài toán: Cho phép xác định trong trƣờng hợp nào thì áp dụng mẫu thiết kế thông qua mô tả bài toán và ngữ cảnh của bài toán đó.
Giải pháp giải quyết bài toán: Mô tả những thành phần tạo nên mẫu thiết kế (các lớp, các đối tƣợng) cùng mối quan hệ, vai trò và cách thức phối hợp giữa chúng (cấu trúc, thừa kế). Giải pháp không đề cập đến cách thức thiết kế hay thực hiện cụ thể nào vì nó đƣợc áp dụng trong rất nhiều tình huống khác nhau. Thay vào đó, giải pháp của mẫu thiết kế đƣợc mô tả với tính khái quát cao với cách thức tổ chức chung nhất của các thành phần trong việc giải quyết bài toán. LUAN VAN CHAT LUONG download : add luanvanchat@agmail.com -14- Ví dụ nhƣ mẫu thiết kế đƣợc gọi nhƣ một thành ngữ (mẫu GRASP), mẫu thiết kế có thể mô tả bằng lời hoặc mô hình thiết kế hay bằng mã nguồn.
Hệ quả: Là những gì thu nhận đƣợc cùng với những yếu tố cần cân nhắc khi áp dụng mẫu thiết kế để giải quyết bài toán. Hệ quả thƣờng không đƣợc đề cập khi nói đến một mẫu thiết kế nhƣng đây là yếu tố quyết định khi cần chọn lựa hoặc phân tích chi phí và lợi ích khi áp dụng các mẫu thiết kế. Danh mục các mẫu thiết kế và phân loại [9] Erich Gamma và các đồng sự của ông đề xuất 23 mẫu thiết kế, và đã đƣa ra hai tiêu chí để phân loại các mẫu thiết kế này. Đó là phân loại theo mục đích sử dụng (purpose) và phạm vi áp dụng của mẫu (scope).
Theo mục đích sử dụng: Các mẫu thiết kế đƣợc phân thành 3 nhóm: mẫu kiến tạo, mẫu cấu trúc, mẫu hành vi. Mẫu kiến tạo (Creational Patterns): mẫu kiến tạo trừu tƣợng hoá quá trình khởi tạo đối tƣợng. Các mẫu này giúp hệ thống không phải phụ thuộc vào cách một đối tƣợng đƣợc tạo ra, xây dựng và thể hiện. Mẫu thiết kế kiến tạo bao gồm các mẫu sau: Abstract Factory, Builder, Factory Method, Prototype, Singleton.
Mẫu cấu trúc (Structural Patterns): mẫu thiết kế cấu trúc đề cập đến cách mà các đối tƣợng và lớp đối tƣợng kết hợp để tạo nên một cấu trúc lớn hơn và hữu dụng hơn. Việc thiết kế các lớp đối tƣợng là nhằm đáp ứng các ràng buộc cụ thể của hệ thống. Mẫu cấu trúc mô tả mối quan hệ giữa các lớp này và sắp xếp sao cho nếu có bất kì sự thay đổi nào với hệ thống đều không làm thay đổi những quan hệ đó. Mẫu thiết kế cấu trúc bao gồm các mẫu sau: Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy.
Mẫu hành vi (Behavioral Patterns): mẫu hành vi mô tả sự tƣơng tác giữa các đối tƣợng và cách chúng phân phối, cộng tác, để giải quyết một hay một nhóm trách nhiệm nào đó. Mẫu hành vi bao gồm các mẫu sau: Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor. Theo phạm vi sử dụng: các mẫu thiết kế đƣợc phân thành 2 nhóm: LUAN VAN CHAT LUONG download : add luanvanchat@agmail.com -15- Phạm vi đƣợc nói đến khi ta quyết định nên áp dụng mẫu thiết kế vào các lớp hay các đối tƣợng. Mẫu thiết kế áp dụng cho Lớp (Class): các mẫu này mô tả và giải quyết mối quan hệ giữa các lớp đối tƣợng và lớp con của chúng.
Các mối quan hệ này đƣợc thiết lập qua cơ chế kế thừa và chỉ xảy ra ở thời điểm biên dịch chƣơng trình (compiler-time). Các mẫu thuộc loại này bao gồm: Factory Method, Adapter (class), Interpreter, Template Method. Mẫu thiết kế áp dụng cho Đối tƣợng (Object): các mẫu này mô tả và giải quyết mối quan hệ giữa các đối tƣợng. Các mối quan hệ này có thể thay đổi tại thời điểm chạy chƣơng trình (run-time).
Các mẫu thuộc loại này bao gồm: Abstract Factory, Builder, Prototype, Singleton, Adapter (Object), Bridge, Composite, Decorator, Facade, Flyweight, Proxy, Chain of Responsibility, Command, Iterator, Mediator, Memento, Observer, State, Strategy, Visitor. Sơ đồ mối quan hệ giữa các mẫu thiết kế [9] LUAN VAN CHAT LUONG download : add luanvanchat@agmail.1: Sơ đồ mối quan hệ giữa các mẫu thiết kế 1. Giới thiệu một số mẫu thiết kế điển hình về hành vi và trình diễn [8,9,10] Với phạm vi thực hiện của luận văn, phần này chỉ tổng hợp và giới thiệu một số mẫu thiết kế về hành vi và trình diễn đƣợc ứng dụng nhiều trong phân tích và thiết kế phần mềm, từ đó làm cơ sở để thực hiện áp dụng vào phân tích và thiết kế hệ thống ở phần sau. Ý nghĩa LUAN VAN CHAT LUONG download : add luanvanchat@agmail.com -17- Định nghĩa mối quan hệ phụ thuộc một - nhiều giữa các đối tƣợng sao cho khi một đối tƣợng thay đổi trạng thái thì tất cả các đối tƣợng liên quan cũng sẽ đƣợc thông báo và tự động cập nhật theo.
Mô tả Việc phân chia hệ thống thành nhiều lớp con có quan hệ với nhau là nhu cầu tất yếu để có thể duy trì sự bền vững của hệ thống. Chúng ta không bao giờ muốn cài đặt hệ thống mà tất cả các lớp dính chặt lại với nhau, bởi vì điều này sẽ làm giảm tính tái sử dụng lại của chúng. Ví dụ, nhiều công cụ giao diện đồ hoạ phân tách giao diện (GUI) ra khỏi dữ liệu (DATA) bên dƣới. Các lớp định nghĩa cho giao diện và dữ liệu trên có thể kết hợp với nhau để làm việc cũng nhƣ có thể đƣợc sử dụng 1 cách độc lập.
Mẫu Observers mô tả cách thiết lập mối quan hệ này. Có hai đối tƣợng then chốt trong mẫu này, đó là Subject và Observer. Một đối tƣợng Subject có thể có một hoặc nhiều đối tƣợng Observer phụ thuộc vào nó. Tất cả các đối tƣợng Observer sẽ đƣợc cảnh báo (notify) khi đối tƣợng Subject có sự thay đổi về trạng thái.
Khi đó, các đối tƣợng Observer sẽ lấy thông tin về trạng thái của đối tƣợng Subject để tự cập nhật lại trạng thái của chính nó. Cấu trúc mẫu Observer Hình 1.2: Cấu trúc mẫu Observer Ở cấu trúc trên, khi khởi tạo một đối tƣợng thuộc lớp ConcreteObserver thì sự khởi tạo này phải dựa trên đối tƣợng thuộc lớp ConcreteSubject để lấy thông tin trạng thái hiện tại của đối tƣợng Subject. Đặc điểm của mẫu này là sự ánh xạ qua lại giữa đối tƣợng thuộc lớp Subject và các đối tƣợng thuộc lớp Observer. Đối tƣợng ConcreteObserver sẽ giữ con trỏ của đối tƣợng ConcreteSubject.