MỞ ĐẦU Một trong những tiêu chuẩn quan trọng để đánh giá chất lƣợng phần mềm là khả năng tái sử dụng. Thực tế cho thấy mỗi dự án phần mềm là một thực thể phức tạp và duy nhất. Nhƣng giữa các thực thể đó ta vẫn tìm thấy sự lặp lại ở một hoặc nhiều điểm. Qua quá trình nghiên cứu, hƣớng giải quyết cho các vấn đề mang tính chất lặp đi lặp lại khi phát triển các hệ thống phần mềm đã đƣợc các chuyên gia đúc kết và nâng lên mức tổng quát.
Từ đó hình thành khái niệm mẫu thiết kế. Năm 1995, Erich Gamma và các cộng sự của ông đã công bố cuốn sách “Elements of reusable Object Oriented Software” và đã đánh dấu sự ra đời của thiết kế mẫu. Đây là 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. Hiện nay, nhiều hệ thống phần mềm đƣợc thiết kế theo cách tiếp cận hƣớng đối tƣợng và áp dụng mô hình mẫu thiết kế (Design Pattern).
Mẫu thiết kế giúp ta giải quyết bài toán nhanh gọn, có khả năng tái sử dụng mà không cần phải thiết kế lại. Mẫu thiết kế dựa trên nguyên lý thiết kế hƣớng đối tƣợng và nó đƣợc xem nhƣ là công cụ để phát hiện và mô tả bài toán ở mức trừu tƣợng cao mà vẫn bao hàm đầy đủ ngữ nghĩa của bài toán ứng dụng. Erich Gamma và các cộng sự đã đƣa ra 23 mẫu thiết kế nổi tiếng (các mẫu GOF – Gang of Four). Các mẫu thiết kế đó đã đƣợc áp dụng rất thành công trong thiết kế các phần mềm hƣớng đối tƣợng.
Tuy nhiên với sự phát triển nhanh chóng của công nghiệp phần mềm và phƣơng pháp thiết kế hƣớng đối tƣợng, đã nảy sinh rất nhiều tình huống đòi hỏi và phát sinh những mẫu thiết kế mới cho phù hợp. Cho đến nay đã có rất nhiều các mẫu thiết kế đã đƣợc đƣa ra dựa trên việc cải biến các mẫu trên cũng nhƣ các mẫu thiết kế mới. Do đó cần thiết có những nghiên cứu phƣơng pháp luận về mẫu thiết kế. Đồng thời trên cơ sở đó đƣa ra các phƣơng pháp để xây dựng lên các mẫu thiết kế trong những tình huống phát sinh.
Vì vậy tôi đã lựa chọn đề tài “Phát triển mẫu thiết kế phần mềm và ứng dụng” để tìm lời giải đáp cho những vấn đề trên. 1 LUAN VAN CHAT LUONG download : add luanvanchat@agmail.com CHƢƠNG 1. TỔNG QUAN VỀ MẪU THIẾT KẾ PHẦN MỀM 1. Vấn đề trong thiết kế phần mềm hƣớng đối tƣợng Việc thiết kế phần mềm nói chung và phần mềm hƣớng đối nói riêng là một việc khó.
Thiết kế phần mềm hƣớng đối tƣợng phải đảm bảo giải quyết đƣợc vấn đề mong muốn, đồng thời phải đảm bảo có thể đƣợc mở rộng trong tƣơng lai mà không hải thiết kế lại. Tuy nhiên khi thiết kế hƣớng đối tƣợng một phần mềm, không thể đảm bảo rằng thiết kế đó là đúng và đáp ứng đƣợc các yêu cầu trên. Do đó cần đƣa ra một vài phƣơng án để từ đó lựa chọn đƣợc phƣơng án tốt nhất. Phƣơng án này đôi khi đƣợc dùng lại nhiều lần khi gặp các vấn đề tƣơng tự.
Ta hay gặp những vấn đề tƣơng tự nhau đƣợc phát triển thành các mẫu thiết kế, để sử dụng cho các hệ thống phần mềm ứng dụng. Khái niệm Mẫu thiết kế Mẫu đã tồn tại trong một thời gian dài trong quá trình phát triển phần mềm, tuy nhiên chƣa có một định nghĩa hoàn thiện cho nó. Mẫu mô tả vấn đề một cách lặp đi lặp lại và các giải pháp cho vấn đề đó. Nó đƣợc xem nhƣ là một khuôn mẫu đƣợc áp dụng để giải quyết các trƣờng hợp của cùng một loại vấn đề.
Mẫu thiết kế đƣợc dùng trong công nghệ phần mềm là các giải pháp cho vấn đề trong thiết kế các hệ thống phần mềm. Đây là tập các giải pháp đã đƣợc công nhận có giá trị và ngƣời phát triển phần mềm áp dụng để giải quyết các vấn đề tƣơng tự. Cũng nhƣ trong phân tích và thiết kế hƣớng đối tƣợng, việc sử dụng mẫu thiết kế cần phải đạt đƣợc khả năng tái sử dụng các giải pháp chuẩn đối với vấn đề xảy ra thƣờng xuyên. Christopter Alexander đã định nghĩa [1]: “Mỗi mẫu mô tả một vấn đề mang tính chất xuất hiện lặp đi lặp lại trong môi trƣờng của chúng ta, một giải pháp cho vấn đề đó”.
Một định nghĩa khác về mẫu của Gamma [1]: “Một mẫu thể hiện bản chất cốt lõi của một giải pháp cho một vấn đề xuất hiện lặp đi lặp lại trong một ngữ cảnh đƣợc chỉ định rõ”. Mỗi một mẫu mô tả một vấn đề xảy ra lặp đi lặp lại trong môi trƣờng và mô tả cái cốt lõi của giải pháp để cho vấn đề đó. Bằng cách nào đó bạn đã dùng nó cả triệu lần mà không làm giống nhau 2 lần. Nội dung các mẫu thiết kế GOF [6] 1.
Nhóm mẫu tạo lập Nhóm gồm có 5 mẫu: AbstractFactory, Abstract Method, Builder, Prototype và Singleton. Nhóm này liên quan tới việc khởi tạo các thể nghiệm của đối tƣợng, tách biệt với cách đƣợc thực hiện từ ứng dụng. Xem thông tin của các mẫu trong nhóm dựa vào biểu đồ phụ thuộc vào mẫu đó, mẫu thiên về hành vi hay cấu trúc. 2 LUAN VAN CHAT LUONG download : add luanvanchat@agmail.
Abstract Factory Trong các hệ điều hành giao diện đồ hoạ, bộ công cụ cung cấp giao diện ngƣời dùng dựa trên chuẩn xem và cảm nhận (look-and–feel). Có rất nhiều kiểu giao diện xem và cảm nhận và giao diện ngƣời dùng khác nhau thanh cuộn tài liệu (scroll bar), cửa sổ (window), nút bấm (button), hộp soạn thảo (editbox),. Nếu xem chúng là các đối tƣợng thì chúng có một số thuộc tính và hành vi khá giống nhau về mặt hình thức nhƣng lại khác nhau về cách thực hiện. Chẳng hạn đối tƣợng button, window và editbox có cùng các thuộc tính là chiều dài, rộng, cao, toạ độ,… các phƣơng thức là Resize(), SetPosition(),.
Tuy nhiên các đối tƣợng này không thể gộp vào một lớp vì theo nguyên lý xây dựng lớp, các đối tƣợng thuộc cùng 1 lớp phải có các phƣơng thức hoạt động nhƣ nhau, trong khi tuy rằng các đối tƣợng ở đây có cùng giao diện nhƣng cách thực hiện các hành vi lại hoàn toàn khác nhau. Vấn đề đặt ra là xây dựng một lớp tổng quát, chứa những điểm chung của các đối tƣợng để từ đó có thể dễ dàng sử dụng lại. Ta gọi lớp này là lớp WidgetFactory. Các lớp đối tƣợng window, button và editbox thừa kế lớp này.
Trong thiết kế hƣớng đối tƣợng, ta xây dựng mô hình các lớp đó nhƣ sau: Hình 1. Sơ đồ lớp mẫu Abstract Factory Lớp WidgetFactory có 2 phƣơng thức là CreateScrollBar() và CreateWindow(). Đây là lớp trừu tƣợng tổng quát cho MotifWidgetFactory và PMWidgetFactory. Các lớp MotifWidgeFactory và PMWidgetFactory thừa kế lớp WidgetFactory.
Các nhóm lớp Window và ScrollBar là các lớp trừu tƣợng. Lớp Window có các lớp con cụ thể là PMWindow và MotifWindow. Lớp ScrollBar có các lớp con cụ thể là PMScrollBar và MotifScrollBar. Các đối tƣợng thuộc lớp này đƣợc các đối tƣợng thuộc lớp 3 LUAN VAN CHAT LUONG download : add luanvanchat@agmail.com WidgetFactory (MotifWidgetFactory và PMWidgetFactory) gọi trong các hàm khởi tạo đối tƣợng.
Đối tƣợng client thông qua lớp giao diện của các đối tƣợng MotifWidgetFactory, PMWidgetFactory, Window và ScrollBar để làm việc với các đối tƣợng PMWindow, MotifWindow, PMScrollBar,MotifScrollBar. Điều này có thể thực hiện đƣợc nhờ cơ chế binding trong các ngôn ngữ hỗ trợ lập trình hƣớng đối tƣợng nhƣ C++, C#, Java, SmallTalk,… Các đối tƣợng PMWindow, MotifWindow, PMScrollBar, MotifScrollBar đƣợc tạo trong thời gian chạy chƣơng trình nên trình ứng dụng (đối tƣợng thuộc lớp client) chỉ cần giữ một con trỏ trỏ đến đối tƣợng thuộc lớp WidgetFactory, và thay đổi địa chỉ con trỏ để có thể làm việc với các đối tƣợng trên. Các tình huống này thƣờng có cùng một cách giải quyết đã đƣợc chứng tỏ là tối ƣu. Nó đƣợc tổng quát hoá thành một mẫu thiết kế gọi là AbstractFactory.
Định nghĩa: mẫu Abstract Factory cung cấp cho trình khách một giao diện cho một tập các đối tƣợng thuộc các lớp khác nhau mà không phải trực tiếp làm việc với từng lớp con cụ thể. Sơ đồ lớp mẫu Abstract Factory AbstractFactory (ContinentFactory): khai báo một giao diện cho các lớp dẫn xuất cụ thể. 4 LUAN VAN CHAT LUONG download : add luanvanchat@agmail.com ConcreteFactory (AfricaFactory, AmericaFactory): cài đặt các thao tác để tạo ra các đối tƣợng dẫn xuất chi tiết. AbstractProduct (Herbivore, Carnivore): khai báo một giao diện trừu tƣợng cho đối tƣợng dẫn xuất.
Product (Wildebeest, Lion, Bison, Wolf): định nghĩa một đối tƣợng dẫn xuất đƣợc tạo ra bởi một factory cụ thể tƣơng ứng, cài đặt giao diện AbstractProduct. Client (AnimalWorld): sử dụng giao diện đƣợc khai báo bởi các lớp AbstractFactory và AbstractProduct. Ví dụ sau đây là các lớp trên đƣợc cài đặt trong C++: //Cài đặt cho lớp WidgetFactory: class WidgetFactory{ public: virtual Window* CreateWindow(); virtual ScrollBar* CreateScrollBar(); }; //Cài đặt cho lớp MotifWidgetFactory và PMWidgeFactory: class MotifWidgetFactory:public WidgetFactory{ public: Window* CreateWindow(){ return new MotifWindow(); } ScrollBar* CreateScrollBar(){ return new MotifScrollBar(); } }; class PMWidgetFactory:public WidgetFactory{ public: Window* CreateWindow(){ return new PMWindow(); } ScrollBar* CreateScrollBar(){ return new PMScrollBar(); } }; //Lớp đối tượng Window: class Window{ //định nghĩa các thuộc tính và phương thức. }; class MotifWindow:public Window{ //định nghĩa các thuộc tính và các phương thức.
}; class PMWindow:public Window{ //định nghĩa các thuộc tính và các phương thức. }; 5 LUAN VAN CHAT LUONG download : add luanvanchat@agmail.com //Các lớp thuộc nhóm ScrollBar. class ScrollBar{ //định nghĩa các thuộc tính và phương thức. }; class MotifScrollBar:public ScrollBar{ //định nghĩa các thuộc tính và phương thức.
}; class PMScrollBar:public ScrollBar{ //định nghĩa các thuộc tính và phương thức. }; //Để truy cập đến các đối tượng này tại chương trình ứng dụng //ta có thể thực hiện như sau: class Client{ private: WidgetFactory* wf; }; Các mẫu liên quan: AbstractFactory thƣờng đƣợc cài đặt cùng với Singleton, FactoryMethod và đôi khi cả Prototype. Các lớp con cụ thể thƣờng đƣợc cài đặt bằng singleton. Bởi singleton có thể tạo ra những đối tƣợng đồng nhất cho dù chúng ta gọi nó ở đâu đó trong chƣơng trình.
Builder Trong những ứng dụng lớn với các chức năng phức tạp và giao diện đồ sộ, việc khởi tạo ứng dụng thƣờng gặp nhiều khó khăn. Chúng ta không nên dồn các việc này cho một hàm khởi tạo, vì nhƣ thế sẽ rất khó kiểm soát và không phải lúc nào các thành phần của ứng dụng cũng đƣợc khởi tạo một cách đồng bộ. Có thành phần đƣợc tạo lúc dịch chƣơng trình nhƣng cũng có thành phần tuỳ theo từng yêu cầu của ngƣời dùng, hoàn cảnh của ứng dụng mà nó sẽ đƣợc tạo ra. Do vậy ngƣời ta giao việc này cho một đối tƣợng chịu trách nhiêm khởi tạo và chia việc khởi tạo ứng dụng một cách riêng rẽ để có thể khởi tạo riêng biệt ở các hoàn cảnh khác nhau.