1.前言
"工廠+裝飾+策略+觀察者"是常見(jiàn)且常用的設(shè)計(jì)模式之一,但并不是指稱"四大模式"的官方術(shù)語(yǔ)。
"四大模式"通常是指指令式面向?qū)ο缶幊讨械乃膫€(gè)基本概念:封裝、繼承、多態(tài)和抽象。這四個(gè)概念是面向?qū)ο缶幊痰幕?/p>
2.工廠模式
工廠模式(例:工廠方法模式)中,通常存在一個(gè)抽象的工廠類和多個(gè)具體的工廠子類。每個(gè)工廠子類負(fù)責(zé)創(chuàng)建一種具體的對(duì)象,具體的創(chuàng)建邏輯在工廠子類中實(shí)現(xiàn)。客戶端通過(guò)與工廠接口進(jìn)行交互,并由工廠子類來(lái)創(chuàng)建所需的對(duì)象。
/* 將工廠也聲明成一個(gè)基類 */
class TaskBase
{
public:
TaskBase();
virtual ~CalculatorBase();
virtual void exec(unsigned char *data) = 0;
private:
...
};
class TaskA : public TaskBase
{
public:
TaskA();
~TaskA();
virtual void exec(unsigned char *data) override;
private:
...
};
class TaskB : public TaskBase
{
public:
TaskA();
~TaskB();
virtual void exec(unsigned char *data) override;
private:
...
};
int main()
{
TaskBase *task_1 = new TaskA();
TaskBase *task_2 = new TaskB();
TaskBase *current;
int type = 1; // 進(jìn)行工廠的選擇
if(type == 0)
current = task_1;
else
current = task_2;
current->exec();
return 0;
}
這種模式特別適合task任務(wù)的選擇?
3.裝飾模式
裝飾器模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,用于動(dòng)態(tài)地給對(duì)象添加額外的行為,同時(shí)又不修改原始對(duì)象的結(jié)構(gòu)。裝飾器模式通過(guò)將對(duì)象包裝在一個(gè)具有相同接口的裝飾器類中,可以在運(yùn)行時(shí)添加、修改或刪除對(duì)象的功能。
裝飾器模式的核心思想是使用繼承和組合,通過(guò)創(chuàng)建具有相同接口的裝飾器類來(lái)包裝原始對(duì)象。裝飾器類擁有與原始對(duì)象相同的接口,并持有一個(gè)指向原始對(duì)象的引用。裝飾器類可以在執(zhí)行原始對(duì)象的方法前后添加自定義的行為,以擴(kuò)展原始對(duì)象的功能。
#include <iostream>
#include <string>
// 抽象訂單接口
class Order
{
public:
virtual void process() = 0;
};
// 具體訂單類
class SimpleOrder : public Order
{
public:
void process() override
{
std::cout << "處理簡(jiǎn)單訂單" << std::endl;
}
};
// 抽象裝飾器類
class OrderDecorator : public Order
{
protected:
Order* decoratedOrder; // 持有一個(gè)指向原始訂單的引用
public:
OrderDecorator(Order* order) : decoratedOrder(order) {}
void process() override
{
decoratedOrder->process();
}
};
// 具體裝飾器類A
class UrgentOrderDecorator : public OrderDecorator
{
public:
UrgentOrderDecorator(Order* order) : OrderDecorator(order) {}
void process() override
{
OrderDecorator::process();
std::cout << "添加急件處理" << std::endl;
}
};
// 具體裝飾器類B
class InternationalOrderDecorator : public OrderDecorator
{
public:
InternationalOrderDecorator(Order* order) : OrderDecorator(order) {}
void process() override
{
OrderDecorator::process();
std::cout << "添加國(guó)際訂單處理" << std::endl;
}
};
int main()
{
Order* order = new SimpleOrder();
order->process(); // 處理簡(jiǎn)單訂單
Order* urgentOrder = new UrgentOrderDecorator(order);
urgentOrder->process(); // 處理簡(jiǎn)單訂單,并添加急件處理
Order* internationalOrder = new InternationalOrderDecorator(order);
internationalOrder->process(); // 處理簡(jiǎn)單訂單,并添加國(guó)際訂單處理
Order* urgentInternationalOrder = new UrgentOrderDecorator(new InternationalOrderDecorator(order));
urgentInternationalOrder->process(); // 處理簡(jiǎn)單訂單,并同時(shí)添加國(guó)際訂單和急件處理
delete urgentInternationalOrder;
delete internationalOrder;
delete urgentOrder;
delete order;
return 0;
}
在這個(gè)例子中,抽象訂單接口Order
定義了訂單的處理方法process()
。SimpleOrder
是具體訂單類,它實(shí)現(xiàn)了訂單的處理邏輯。OrderDecorator
是抽象裝飾器類,它持有一個(gè)指向原始訂單的引用,并在訂單處理前后添加額外的功能。UrgentOrderDecorator
和InternationalOrderDecorator
是具體裝飾器類,分別給訂單添加了急件處理和國(guó)際訂單處理。
客戶端代碼演示了不同的訂單處理情況。通過(guò)創(chuàng)建不同的裝飾器對(duì)象來(lái)包裝原始訂單對(duì)象,可以在處理訂單時(shí)添加額外的功能。每個(gè)裝飾器類都在執(zhí)行原始訂單的處理方法前后添加了自己特定的行為。
這個(gè)例子展示了裝飾器模式的靈活性,可以在不修改訂單類的情況下,動(dòng)態(tài)地添加、修改或刪除訂單的功能。它允許通過(guò)裝飾器組合來(lái)創(chuàng)建不同的訂單處理方式。
處理簡(jiǎn)單訂單
處理簡(jiǎn)單訂單
添加急件處理
處理簡(jiǎn)單訂單
添加國(guó)際訂單處理
處理簡(jiǎn)單訂單
添加國(guó)際訂單處理
添加急件處理
處理簡(jiǎn)單訂單
添加急件處理
添加國(guó)際訂單處理
?4.策略模式
C++策略模式(Strategy Pattern)是一種行為設(shè)計(jì)模式,它允許在運(yùn)行時(shí)動(dòng)態(tài)地選擇算法或行為。該模式將算法封裝在獨(dú)立的策略類中,使得它們可以相互替換,而不影響客戶端代碼。這種靈活性使得我們可以根據(jù)不同的情境選擇不同的算法,提高代碼的復(fù)用性和可維護(hù)性。?
#include <iostream>
// 定義抽象策略接口
class SendStrategy
{
public:
virtual void sendData(const std::string& data) const = 0;
};
// 定義具體策略類:UART發(fā)送
class UartStrategy : public SendStrategy
{
public:
void sendData(const std::string& data) const override
{
std::cout << "UART發(fā)送數(shù)據(jù):" << data << std::endl;
}
};
// 定義具體策略類:TCP發(fā)送
class TcpStrategy : public SendStrategy
{
public:
void sendData(const std::string& data) const override
{
std::cout << "TCP發(fā)送數(shù)據(jù):" << data << std::endl;
}
};
// 定義具體策略類:UDP發(fā)送
class UdpStrategy : public SendStrategy
{
public:
void sendData(const std::string& data) const override
{
std::cout << "UDP發(fā)送數(shù)據(jù):" << data << std::endl;
}
};
// 定義環(huán)境類
class DataSender {
private:
SendStrategy* strategy;
public:
explicit DataSender(SendStrategy* strategy) : strategy(strategy) {}
void setStrategy(SendStrategy* strategy)
{
this->strategy = strategy;
}
void sendData(const std::string& data)
{
if (strategy)
{
strategy->sendData(data);
}
}
};
int main()
{
// 創(chuàng)建具體策略對(duì)象
SendStrategy* uart = new UartStrategy();
SendStrategy* tcp = new TcpStrategy();
SendStrategy* udp = new UdpStrategy();
// 創(chuàng)建環(huán)境對(duì)象并設(shè)置初始策略
DataSender sender(uart);
// 發(fā)送數(shù)據(jù)
sender.sendData("Hello, World!");
// 切換為TCP發(fā)送
sender.setStrategy(tcp);
sender.sendData("Hello, TCP!");
// 切換為UDP發(fā)送
sender.setStrategy(udp);
sender.sendData("Hello, UDP!");
// 釋放資源
delete uart;
delete tcp;
delete udp;
return 0;
}
我們首先定義了一個(gè)抽象策略接口SendStrategy
,然后實(shí)現(xiàn)了三個(gè)具體的策略類UartStrategy
、TcpStrategy
和UdpStrategy
,分別用于UART、TCP和UDP發(fā)送。
接著,我們定義了環(huán)境類DataSender
,它維護(hù)了一個(gè)指向具體策略對(duì)象的引用,并提供了一個(gè)公共接口sendData()
以供客戶端代碼調(diào)用。
在主函數(shù)中,我們創(chuàng)建了具體策略對(duì)象,并將初始策略設(shè)置為UART發(fā)送。然后,我們使用環(huán)境對(duì)象的sendData()
方法來(lái)發(fā)送數(shù)據(jù)。
接著,我們切換策略為TCP發(fā)送和UDP發(fā)送,并分別調(diào)用環(huán)境對(duì)象的sendData()
方法。
5.觀察者模式
C++觀察者模式(Observer Pattern)是一種行為設(shè)計(jì)模式,它使用一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象(主題)的狀態(tài)發(fā)生變化時(shí),自動(dòng)通知并更新其他依賴于它的對(duì)象(觀察者)。觀察者模式提供了一種松耦合的方式,使得主題和觀察者可以獨(dú)立變化,而不需要相互了解具體的實(shí)現(xiàn)細(xì)節(jié)。
觀察者模式的主要角色包括:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-584070.html
- Subject(主題):它通常是一個(gè)抽象類或接口,定義了增加、刪除和通知觀察者的方法。
- ConcreteSubject(具體主題):它是主題的具體實(shí)現(xiàn),存儲(chǔ)了具體觀察者對(duì)象,并在狀態(tài)發(fā)生變化時(shí)通知觀察者。
- Observer(觀察者):它定義了觀察者接收通知并更新自己的方法。
- ConcreteObserver(具體觀察者):它是觀察者的具體實(shí)現(xiàn),實(shí)現(xiàn)了接收通知和更新自身的方法。
#include <iostream>
#include <vector>
// 定義觀察者接口
class Observer {
public:
virtual void update(const std::string& news) = 0;
};
// 定義具體觀察者類
class Subscriber : public Observer {
private:
std::string name;
public:
explicit Subscriber(const std::string& name) : name(name) {}
void update(const std::string& news) override {
std::cout << name << " 收到新聞:" << news << std::endl;
}
};
// 定義主題類
class NewsChannel {
private:
std::vector<Observer*> observers;
std::string latestNews;
public:
void addObserver(Observer* observer) {
observers.push_back(observer);
}
void removeObserver(Observer* observer) {
// 在實(shí)際應(yīng)用中可能需要實(shí)現(xiàn)刪除觀察者的邏輯
}
void notifyObservers() {
for (auto observer : observers) {
observer->update(latestNews);
}
}
void setNews(const std::string& news) {
latestNews = news;
notifyObservers();
}
};
int main() {
// 創(chuàng)建主題類(新聞?lì)l道)
NewsChannel newsChannel;
// 創(chuàng)建觀察者類(訂閱者)
Observer* subscriber1 = new Subscriber("訂閱者1");
Observer* subscriber2 = new Subscriber("訂閱者2");
// 添加觀察者到主題中
newsChannel.addObserver(subscriber1);
newsChannel.addObserver(subscriber2);
// 發(fā)布新聞
newsChannel.setNews("今天天氣晴朗,適合出游!");
// 釋放資源
delete subscriber1;
delete subscriber2;
return 0;
}
拓展:委托機(jī)制下的觀察者模式文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-584070.html
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
// 定義一個(gè)委托類
template<typename... Args>
class Delegate {
public:
using FunctionPtr = std::function<void(Args...)>;
void Add(FunctionPtr function) {
std::lock_guard<std::mutex> lock(mutex);
delegates.push_back(function);
}
void Remove(FunctionPtr function) {
std::lock_guard<std::mutex> lock(mutex);
delegates.erase(std::remove(delegates.begin(), delegates.end(), function), delegates.end());
}
void Invoke(Args... args) {
std::lock_guard<std::mutex> lock(mutex);
for (auto delegate : delegates) {
delegate(args...);
}
}
private:
std::vector<FunctionPtr> delegates;
std::mutex mutex;
};
// 定義觀察者基類
class Observer {
public:
virtual void Notify() = 0;
};
// 定義具體觀察者類
class ConcreteObserver : public Observer {
public:
ConcreteObserver(Delegate<void>& delegate) : delegate(delegate) {}
void Notify() override {
// 當(dāng)前線程接收到通知后的處理代碼
std::cout << "ConcreteObserver received notification in thread: " << std::this_thread::get_id() << std::endl;
}
private:
Delegate<void>& delegate;
};
// 定義主題類
class Subject {
public:
void AddObserver(Observer* observer) {
std::lock_guard<std::mutex> lock(mutex);
observers.push_back(observer);
}
void RemoveObserver(Observer* observer) {
std::lock_guard<std::mutex> lock(mutex);
observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
}
void NotifyObservers() {
std::lock_guard<std::mutex> lock(mutex);
for (auto observer : observers) {
observer->Notify();
}
}
private:
std::vector<Observer*> observers;
std::mutex mutex;
};
// 工作線程函數(shù)
void WorkerThread(Subject& subject) {
// 在工作線程中執(zhí)行一些任務(wù)...
// 完成后通知觀察者
std::this_thread::sleep_for(std::chrono::seconds(2)); // 模擬工作
subject.NotifyObservers();
}
int main() {
// 創(chuàng)建委托對(duì)象
Delegate<void> delegate;
// 創(chuàng)建觀察者對(duì)象
ConcreteObserver observer(delegate);
// 創(chuàng)建主題對(duì)象
Subject subject;
// 將觀察者注冊(cè)到主題中
subject.AddObserver(&observer);
// 創(chuàng)建工作線程并傳遞主題對(duì)象
std::thread workerThread(WorkerThread, std::ref(subject));
// 主線程中執(zhí)行其他任務(wù)
std::cout << "Main thread doing some work..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
// 等待工作線程結(jié)束
workerThread.join();
return 0;
}
到了這里,關(guān)于C++ 程序設(shè)計(jì):四大模式(工廠+裝飾+策略+觀察者)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!