Báo cáo cuối kỳ môn Lập trình hướng đối tượng - Chủ đề: Decorator design patem

Decorator design patem  
I. Giới thiệu  
Decorator là một mẫu thiết kế cấu trúc thường được sử dụng.  
Mẫu thiết kế này sẽ linh động thay đổi tính chất (functionality)  
đã có trong một đối tượng khi chương trình đang chạy (runtime)  
mà không ảnh hưởng đến các tình chất đã tồn tại của các đối  
tượng khác.  
II. Động lực  
- Một trong những vấn đề trong hướng đối tượng là mở rộng  
phương thức đối tượng sử dụng phương thức kế thừa ta cần  
triển khai code để mở rộng đối tượng có sẵn viết lại (overide)  
các thương thức của lớp đó. Và những mở rộng đó sẽ được  
cài đặt ngay khi biên dịch chương trình  
- Thay vì phải code lại như trên chúng ta sử dụng phương pháp  
tạo ra một lớp mới đồng thời chúng ta sẽ áp dụng sự thay đổi  
trên tất các đối tượng thuộc lớp này. Mở rộng theo cách linh  
động là chúng ta sẽ cung cấp một cơ cấu mà cơ cấu này cho  
phép chúng ta thay đổi một đối tượng đã tồn tại nhưng không  
làm ảnh hưởng đến các đối tượng khác của cùng lớp đó.  
III. Tóm tắt cấu trúc  
Component: giao diện (interface) chung để các đối tượng cần  
thêm chức năng trong quá trình chạy thì triển khai giao diện  
này.  
ConcreteComponent : Một cài đặt cho giao diện Component  
mà nó định nghĩa một đối tượng cần thêm các chức năng trong  
quá trình chạy.  
Decorator : một lớp trừu tượng dùng để duy trì một tham chiếu  
của đối tượng thành phần và đồng thời cài đặt các thành phần  
của giao diện.  
ConcreteDecorator : Một cài đặt của Decorator, nó cài đặt  
thêm các thành phần vào đầu của các đối tượng thành phần.  
IV. Ví dụ cụ thể  
Không dùng decorator  
Giả sử chúng ta có một class bánh mì (in ra màn hình loại bánh  
mì và giá cả)  
Ban đầu loại mọi người mua tại cửa hàng nhất là bánh mì thịt ta  
tạo một class bánh mì  
Class BanhMi  
{
Public:  
void function()  
{
Cout<<” loai: banh mi thit: gia 10k”;  
}
};  
Tuy nhiên một số khách hàng khác lại k thích ăn bánh mì thịt họ  
thích ăn bánh mì chả  
Thế là ta lại viết một class khác tên là bánh mì chả cá  
Class BanhMiChaCa  
{
Public:  
void function()  
{
Cout<<” loai: banh mi cha ca: gia 10k ”;  
}
};  
Thế rồi đã xong, rồi một người khác khác lại đến mua bánh mì  
thịt với chả cá  
Ta lại phải viết thêm một class bánh mì chả cá thit  
Class BanhMiChaThit  
{
Public:  
void function()  
{
Cout<<” loai: banh mi thit + cha ca: giá 15k ”;  
}
};  
Cứ thế lại rồi lại có khách ăn những loại bánh mì khác như chả  
lụa , gà xé , rồi không tương ớt ….v.v.v cứ mỗi loại ta thêm một  
class mới, phương án này khả thi tuy nhiên gây tốn thời gian và  
phiền phức cho người viết code. Từ đó decorator parttern được  
sử dụng giúp bạn chỉnh sửa các class cũ một cách tối ưu nhất  
Sử dụng decorator  
Đầu tiên ta tạo ra một class bánh mì  
class BanhMi  
{
protected:  
string name = "banh mi ";  
int rate_;  
public:  
BanhMi()  
{
rate_ = 0;  
};  
BanhMi(string a, int rate)  
{
name = name + a;  
rate_ = rate;  
};  
~BanhMi(){};  
virtual string getDescription() const  
{
return name;  
};  
virtual int funtion() const  
{
return rate_;  
}
};  
Sau đó tạo một class loaibanhmi kế thừa class BanhMi bọc lại các kiểu  
bánh mì mà cửa hàng bán  
class LoaiBanhMi :public BanhMi  
{
};  
Sau đó bạn tạo các class với từng loại bạn cho rằng khách hàng có thể  
yêu cầu  
class BanhMiThit : public LoaiBanhMi  
{
private:  
BanhMi* mBanhMi;  
public:  
BanhMiThit(BanhMi* banhmi)  
{
mBanhMi = banhmi;  
};  
string getDescription()  
{
if (mBanhMi==NULL)  
{
return (mBanhMi->getDescription() + " thit");  
}
else  
return " thit";  
};  
int funtionconst()  
{
return rate_;  
};  
};  
class BanhMiCha : public LoaiBanhMi  
{
private:  
BanhMi* mBanhMi;  
public:  
BanhMiCha(BanhMi* banhmi)  
{
mBanhMi = banhmi;  
};  
string getDescription() const  
{
if (mBanhMi)  
{
return (mBanhMi->getDescription() + " cha ");  
}
else  
return " cha";  
};  
int funtion() const  
{
return rate_ + 5;  
};  
};  
Một số loại bánh mì  
class BanhMiThit : public LoaiBanhMi  
{
private:  
BanhMi* mBanhMi;  
public:  
BanhMiThit(BanhMi* banhmi)  
{
mBanhMi = banhmi;  
};  
string getDescription()  
{
if (mBanhMi==NULL)  
{
return (mBanhMi->getDescription() + " thit");  
}
else  
return " thit";  
};  
int funtionconst()  
{
if (mBanhMi);  
return mBanhMi->funtion() + 10;  
return 10;  
};  
};  
// truong hop khach muon banh mi thit cha, gia la 15 k  
class BanhMiCha : public LoaiBanhMi  
{
private:  
BanhMi* mBanhMi;  
public:  
BanhMiCha(BanhMi* banhmi)  
{
mBanhMi = banhmi;  
};  
string getDescription() const  
{
if (mBanhMi)  
{
return (mBanhMi->getDescription() + " cha ");  
}
else  
return " cha";  
};  
int funtion() const  
{
if (mBanhMi);  
return mBanhMi->funtion() + 5;  
return 10;  
};  
};  
Cài đặt trong hàm main  
void main()  
{
BanhMi* BanhMi_;  
BanhMi_ = new BanhMi("thit",10);  
cout << " " << BanhMi_->getDescription() << " gia: " <<  
BanhMi_->funtion() << "k " << endl;  
BanhMi_ = new BanhMiCha(BanhMi_);  
cout << " " << BanhMi_->getDescription() << " gia: " <<  
BanhMi_->funtion() << "k" << endl;  
delete BanhMi_;  
system("pause");  
}
Kết quả khi chạy chương trình  
V. Ưu nhược điểm của decorator parttern  
Ưu điểm:  
- Cung cấp một giải pháp linh hoạt hơn khi thêm các chức  
năng cho một đối tượng so với cách kế thừa  
- Cung cấp giải pháp dễ dàng thay đổi hành vi của đối tượng  
Nhược điểm:  
- Có nhiều class chức năng khiến việc bảo trì có phần nào đó  
khó khan  
VI: Bài tập  
Câu 1: cho đoạn code sau hỏi sau khi chạy xong hàm main in ra  
những gì  
#ifndef _KEM_H_  
#define _KEM_H_  
#include<iostream>  
#include<string>  
using namespace std;  
class Kem  
{
string Ten;  
int Gia;  
public:  
Kem();  
virtual string getKem();  
virtual int getGia();  
};  
class HuongVi :public Kem{  
protected:  
Kem *MyKem;  
};  
class SoCoLa :public HuongVi  
{
public:  
SoCoLa(Kem *myKem);  
string getKem();  
int getGia();  
};  
class Dau :public HuongVi  
{
public:  
Dau(Kem *myKem);  
string getKem();  
int getGia();  
};  
#endif  
#include"Kem.h"  
Kem::Kem()  
{
Ten = "Kem";  
Gia = 5;  
}
string Kem::getKem(){  
return Ten;  
}
int Kem::getGia(){  
return Gia;  
}
SoCoLa::SoCoLa(Kem *myKem)  
{
MyKem = myKem;  
}
string SoCoLa::getKem()  
{
if (MyKem)  
return MyKem->getKem() + " + SoCoLa";  
return "Kem SoCoLa";  
}
int SoCoLa::getGia()  
{
if (MyKem)  
return MyKem->getGia() + 10;  
return 10;  
}
Dau::Dau(Kem *myKem)  
{
MyKem = myKem;  
}
string Dau::getKem()  
{
if (MyKem)  
return MyKem->getKem() + " + Dau";  
return "Kem Dau";  
}
int Dau::getGia()  
{
if (MyKem)  
return MyKem->getGia() + 7;  
return 7;  
}
#include"Kem.h"  
void main()  
{
Kem* A = new Kem;  
Kem* B = NULL;  
cout << A->getKem() << endl;  
cout << "Gia:" << A->getGia() << endl;  
A = new SoCoLa(A);  
cout << A->getKem() << endl;  
cout << "Gia:" << A->getGia() << endl;  
A = new Dau(A);  
cout << A->getKem() << endl;  
cout << "Gia:" << A->getGia() << endl;  
cout << "==================" << endl;  
B = new SoCoLa(B);  
cout << B->getKem() << endl;  
cout << "Gia:" << B->getGia() << endl;  
B = new Dau(B);  
cout << B->getKem() << endl;  
cout << "Gia:" << B->getGia() << endl;  
delete A, B;  
}
Câu 2: dựa vào demo decorator viết một chương trình tính tiền uống  
nước  
docx 13 trang myanh 22020 Free
Bạn đang xem tài liệu "Báo cáo cuối kỳ môn Lập trình hướng đối tượng - Chủ đề: Decorator design patem", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

File đính kèm:

  • docxbao_cao_cuoi_ky_mon_lap_trinh_huong_doi_tuong_chu_de_decorat.docx
  • pptxStrategy_design_pattern.pptx
  • docxStrategy_BT02.docx
  • docxStrategy_BT01.docx