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
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:
bao_cao_cuoi_ky_mon_lap_trinh_huong_doi_tuong_chu_de_decorat.docx
Strategy_design_pattern.pptx
Strategy_BT02.docx
Strategy_BT01.docx

