katcat_vn1986

New Member

Download miễn phí Các nguyên lý cơ bản trong thiết kế hệ điều hành





Lớp Square được kế thừa từ lớp Rectangle, và do đặc điểm của hình vuông là hai cạnh bằng nhau, nên khi đặt chiều rộng thì chúng ta cũng phải đặt chiều dài và ngược lại. Bỏ qua lý do tốn bộ nhớ (do phải lưu cả chiều dài và chiều rộng), chúng ta xét về logic thực hiện chương trình. Chúng ta thử tạo ra hai đối tượng hình vuông và hình chữ nhật và gọi hàm f thao tác trên hai đối tượng này theo hàm main như sau:



Để tải bản Đầy Đủ của tài liệu, xin Trả lời bài viết này, Mods sẽ gửi Link download cho bạn sớm nhất qua hòm tin nhắn.
Ai cần download tài liệu gì mà không tìm thấy ở đây, thì đăng yêu cầu down tại đây nhé:
Nhận download tài liệu miễn phí

Tóm tắt nội dung tài liệu:

dùng, chúng ta chỉ tập trung đến thao tác vẽ (draw) của các đối tượng. Giả sử yêu cầu ban đầu của chương trình Draw là chỉ thao tác trên hai loại đối tượng là hình tròn và hình vuông. Sử dụng phương pháp lập trình cấu trúc (structured programming) (hay còn gọi phương pháp lập trình hướng thủ tục – procedural programming), chương trình phác thảo sơ lược sẽ có dạng như sau (sử dụng ngôn ngữ C++):
PHP Code:
enum ShapeType {circle, square}; struct Shape {   ShapeType itsType; }; struct Circle {   ShapeType itsType;   double itsRadius;   Point itsCenter; }; struct Square {   ShapeType itsType;   double itsSide;   Point itsTopLeft; }; // không cần quan tâm chi tiết đến cài đặt hai hàm này void DrawSquare(struct Square*); void DrawCircle(struct Circle*); typedef struct Shape *ShapePointer; void DrawAllShapes(ShapePointer list[], int n) {   int i;   for (i=0; iitsType)     {       case square:         DrawSquare((struct Square*)s);         break;       case circle:         DrawCircle((struct Circle*)s);         break;     }   } } 
Đoạn mã ở trên có thể dễ dàng đọc hiểu. Trong đó hàm DrawAllShapes có nhiệm vụ vẽ các đối tượng hình học (hình tròn, hình vuông) ra màn hình. Tham số của hàm DrawAllShapes là một mảng các con trỏ chứa địa chỉ của các đối tượng hình học cần được vẽ. Để đạt được điều đó, hàm DrawAllShapes đến phiên nó lại cần sự trợ giúp của hai hàm vẽ cụ thể cho hai loại đối tượng hình học là hàm DrawCircle và DrawSquare. Để gọi được hai hàm này, hàm DrawAllShapes cần xác định đối tượng hiện tại đang thao tác là đối tượng nào thông qua biến thành viên itsType của từng đối tượng. Có vẻ chương trình Draw đã được hoàn thành và đúng với yêu cầu đề ra. Vấn đề sẽ xuất hiện khi chúng ta muốn vẽ thêm một đối tượng khác, như hình tam giác chẳng hạn. Lúc này, hàm DrawAllShapes cần xử lý thêm một trường hợp nữa là hình tam giác. Đoạn mã thêm vào và sửa đối sẽ như sau:
PHP Code:
enum ShapeType {circle, square, triangle};//kiểu dữ liệu liệu kê struct Triangle {   ShapeType itsType;   Point itsVertices[3]; }; // không cần quan tâm chi tiết đến cài đặt hàm này void DrawTriangle(struct Triangle*); void DrawAllShapes(ShapePointer list[], int n) {   int i;   for (i=0; iitsType)     {       case square:         DrawSquare((struct Square*)s);         break;       case circle:         DrawCircle((struct Circle*)s);         break;       // thêm vào       case triangle:         DrawTriangle((struct Triangle*)s);         break;     }   } } 
Để ý trong trường hợp này, khi một yêu cầu mới phát sinh (vẽ hình tam giác), thì đoạn mã của hàm DrawAllShapes đã bị thay đổi. Bản thiết kế chương trình Draw của chúng ta đã vi phạm nguyên lý đóng mở. Vậy bản thiết kế chương trình Draw nên như thế nào? Hai kỹ thuật chính để đạt được nguyên lý Đóng - Mở là sự trừu tượng (abstraction) và tính đa hình (đa xạ : polymorphism). các bạn có thể tự tìm hiểu hai kỹ thuật trừu tượng hóa và đa hình, vốn là hai kỹ thuật mà bất cứ một ngôn ngữ lập trình hướng đối tượng, bao gồm C++, phải hỗ trợ. tui không trình bày chi tiết hai kỹ thuật trên mà chỉ trình bày sơ lược theo ví dụ thiết kế Draw mà chúng ta đang hướng đến. Chương trình Draw ở trên có thể mô hình như sau: Nghĩa là hàm DrawAllShapes sử dụng trực tiếp (được thể hiện bằng đoạn thẳng có dấu mũi tên mảnh) hai đối tượng (hai lớp) Circle và Square, tương ứng là hình tròn và hình vuông. Chúng ta sẽ trừu tượng hóa quan hệ này bằng cách tạo ra một đối tượng gọi là hình (Shape). Một cách cảm tính chúng ta có thể thấy một đối tượng hình tròn hay hình vuông hay hình tam giác đều là một đối tượng hình. Hàm DrawAllShapes thay vì thao tác trực tiếp trên các đối tượng hình tròn và hình vuông sẽ thao tác trên các đối tượng hình chung chung mà chúng ta đã trừu tượng hóa. Mô hình chương trình Draw sẽ trở thành như sau: Các lớp Circle, Square sẽ được kế thừa (được thể hiện bằng đoạn thẳng có dấu mũi tên đậm) từ lớp Shape. Đoạn mã chương trình Draw cho mô hình thiết kế mới sẽ như sau:
PHP Code:
class Shape { public:     // hàm thuần ảo (pure virtual)         virtual void Draw() const=0; }; class Square : public Shape {         protected:                 double itsSide;                 Point itsTopLeft;     public:         // không cần quan tâm chi tiết cài đặt hàm này         virtual void Draw() const; }; class Circle : public Shape {         protected:                 double itsRadius;                 Point itsCenter;     public:         // không cần quan tâm chi tiết cài đặt hàm này         virtual void Draw() const; }; void DrawAllShape(set& list) {     for(iterator i(list); i; i++)         (*i) ->Draw(); }; 
Qua đoạn mã chương trình Draw mới, có thể thấy hàm DrawAllShapes không quan tâm chi tiết đến từng đối tượng hình cụ thể như là hình tròn hay hình vuông (không có câu lệnh if), mà nó chỉ quan tâm đến sự trừu tượng của các đối tượng hình này – Shape. Nhờ cơ chế đa hình (đa xạ) mà hàm Draw của lớp Shape sẽ được liên kết với hàm Draw của lớp Circle hay Square tùy thuộc vào đối tượng hiện tại thuộc lớp Circle hay Square. Trong đoạn chương trình trên cũng xuất hiện một khái niệm mà các bạn ít quen thuộc là iterator và set, các bạn có thể tự tìm hiểu thêm trong thư viện STL đi kèm với C++. Quay trở lại với chương trình Draw của chúng ta, nếu muốn chương trình vẽ thêm đối tượng tam giác thì chúng ta chỉ việc thêm vào lớp Triangle, được dẫn xuất (thừa kế) từ lớp Shape.
PHP Code:
class Shape {         public:     // hàm thuần ảo (pure virtual)         virtual void Draw() const=0; }; class Square : public Shape {         protected:                 double itsSide;                 Point itsTopLeft;     public:         // không cần quan tâm chi tiết cài đặt hàm này         virtual void Draw() const; }; class Circle : public Shape {         protected:                 double itsRadius;                 Point itsCenter;     public:         // không cần quan tâm chi tiết cài đặt hàm này         virtual void Draw() const; }; class Triangle : public Shape {         protected:                 Point vertices[3];     public:         // không cần quan tâm chi tiết cài đặt hàm này         virtual void Draw() const; }; void DrawAllShape(set& list) {     for(iterator i(list); i; i++)         (*i) ->Draw(); }; 
Có thể thấy, chúng ta chỉ cần thêm mới vào lớp Triangle, hàm DrawAllShapes, cũng như tất cả các thành phần đoạn mã đã có của chương trình Draw, không hề thay đổi. Bản thiết kế mới của chương trình Draw thỏa mãn nguyên lý Đóng – Mở. Open-closed là nguyên li trung tâm, rất quan trọng trong thiết kế hướng đối tượng vì chính nguyên lí này làm cho lập trình hướng đối tượng có tính tái sử dụng (reusability) và dễ bảo trì (maintainability). Tham khảo thêm ở đây và ở đây. Như đã đề cập ở trên hai kỹ thuật quan trọng để đạt được nguyên lý đóng mở là trừu tượng hóa và tính
 
Các chủ đề có liên quan khác

Các chủ đề có liên quan khác

Top