Professional Documents
Culture Documents
- Khi class theo Singleton Pattern, chỉ có duy nhất một đối tượng cụ thể của class
được khởi tạo xuyên suốt chương trình.
- Ưu điểm: + Hạn chế việc sử dụng tài nguyên.
+ Tránh xung đột trong việc truy cập dữ liệu khi có nhiều đối tượng của
cùng 1 class cùng hoạt động.
class Database {
private:
static Database* pInstance;
int Record;
string Name;
// Cách để ngăn việc tạo đối tượng mới vơi mỗi câu lệnh new là KHAI
BÁO CONSTRUCTOR CỦA LỚP DATABASE THÀNH PRIVATE.
Database (string name) {
Name = name;
Record = 0;
}
public:
void editRecord (string S) {
cout << “Chuong trinh dang thuc hien mot ” << S << “ hoat
dong tren ban ghi ” << Record << “ trong co so du lieu ” <<
Name << ‘\n’;
}
string getName() {
return Name;
}
static Database* getInstance (string name) {
if ( pInstance == NULL ) {
pInstance = new Database(name);
}
return pInstance;
}
};
Database* Database::pInstance = NULL;
// Khi gọi hàm getInstance(…) thì sẽ lấy được đối tượng của lớp Database, và đối tượng đó
là đối tượng duy nhất.
class Database {
//…
private:
static mutex Khoa;
public:
//…
static Database* getInstance(string name) {
Khoa.lock();
if (pInstance == NULL) {
pInstance = new Database(name);
}
Khoa.unlock();
return pInstance;
}
};
//…
Mutex Database::Khoa;
*/
+ Tạo đối tượng tĩnh ngay từ lúc khởi chạy chương trình (tức là trước
khi vào hàm main() )
/* #include <string>
using namespace std;
class Database {
private:
int Record;
string Name;
Database (string name) {
Name = name;
Record = 0;
}
public:
void editRecord (string S) {
cout << “Chuong trinh dang thuc hien mot ” << S << “ hoat
dong tren ban ghi ” << Record << “ trong co so du lieu ” <<
Name << ‘\n’;
}
string getName() {
return Name;
}
switch (connectionType)
{
case CONNECTION_TYPE_ORACLE:
connection = new OracleConnection();
break;
case CONNECTION_TYPE_SQLSERVER:
connection = new SqlServerConnection();
break;
case CONNECTION_TYPE_MYSQL:
connection = new MySqlConnection();
break;
default:
connection = new OracleConnection(); // default is Oracle
break;
}*/
- Cách để giải quyết là ta sẽ đặt đoạn code tạo connection vào 1 method của 1 class
để tránh trùng lặp code
/* class DbConnectionFactory
{
public:
static Connection* createConnection(eConnectionType connectionType);
};
Connection* DbConnectionFactory::createConnection(eConnectionType
connectionType)
{
Connection *connection = nullptr;
switch (connectionType)
{
case CONNECTION_TYPE_ORACLE:
connection = new OracleConnection();
break;
case CONNECTION_TYPE_SQLSERVER:
connection = new SqlServerConnection();
break;
case CONNECTION_TYPE_MYSQL:
connection = new MySqlConnection();
break;
default:
connection = new OracleConnection(); // default is Oracle
break;
}
return connection;
}*/
- Hàm DbConnectionFactory::createConnection chính là Factory Method
* Ưu điểm của Factory Method:
- Tách biệt công việc tạo đối tượng ra khỏi xử lý code của khách hàng
<Chỉ cho khách hàng thấy phần giao diện chứ không cho thấy sự thay đổi của
cách thức thực hiện của ứng dụng>
- Dễ bảo trì:
Khi muốn thêm/bớt các liên kết các lớp, hoặc sửa tên. Cách thức thực hiện của
phương thức mà không làm ảnh hưởng đến các phần code khác.
- Facade Pattern là một design pattern khá giống với Adapter Pattern.
- Cả 2 đều dùng để chuyển đối interface của các class nhưng có mục đích khác nhau.
- Facade Pattern sẽ giúp đơn giản hóa interface (tức là khi giao diện quá phức tạp,
loằng ngoàng khiến người dùng khó sử dụng ta sẽ sử dụng đến facade để đơn giản hóa giao
diện và các vấn đề phức tạp sẽ được thực hiện một cách âm thầm theo đúng quá trình để
cho ra kết quả đúng như mong muốn)
TEMPLATE METHOD PATTERN
- Template Method Pattern được áp dụng để định nghĩa cấu trúc chung, bộ khung
chung cho một xử lý nào đó ở lớp cha và cho phép các lớp con định nghĩa lại bộ khung đó
mà không làm thay đổi cấu trcs chung của nó.
- Ví dụ:
class Robot {
public:
Robot() {}
void start() {
cout << "Starting ..." << endl;
}
void getParts() {
cout << "Getting a carburetor ..." << endl;
}
void assemble() {
cout << "Installing the carburetor ..." << endl;
}
void test() {
cout << "Revving the engine ..." << endl;
}
void stop() {
cout << "Stopping ..." << endl;
}
void go() {
start();
getParts();
assemble();
test();
stop();
}
};
Việc sử dụng template method pattern chỉ có tác dụng khi cách thức thực hiện các
hàm hầu như giống nhau và chỉ khác nhau chủ yếu ở thứ tự thực hiện thì khi đó áp
dụng template mới hiệu quả
OBSERVER PATTERN
- Dùng để tạo ra mối quan hệ phụ thuộc one-to-many giữa các đối tượng, khi 1 đối
tượng thay đổi trạng thái thì tất cả các đối tượng phụ thuộc nó sẽ được thông báo và cập
nhật tự động.
- Observer cần phải đăng kí với Subject và mỗi Subject có thể có nhièu hơn 1
Observer
- Subject sẽ lưu thông tin về tất cả các observer đã đăng kí.
- Khi có sự kiện xảy ra, Subject sẽ thông báo đến tất cả các observer đã đăng kí.
- Bất kì lúc nào các observer đã đăng kí cũng có thể hủy đăng kí với Subject và sẽ
ngừng nhận thông báo.
STATE PATTERN
- Cho phép một đối tượng có thể thay đổi hành vi của nó dựa trên trạng thái bên
trong.
- Phù hợp để áp dụng trong trường hợp hành vi một đối tượng phụ thuộc vào trạng
thái của nó và nó phải xác định và thay đối hành vi lúc runtime.
- Sự dụng đối tượng và đóng gói state lại như 1 class trỏ đúng vào cái state object
tương ứng với trạng thai hiện tại và gọi các phương thức tương ứng thông qua con trỏ.
giúp code được tách biệt và đóng gói được xử lý của các state ra các class khác
nhau, dễ bảo trì và mở rộng hơn.