c++设计模式
模板模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
当多个类有相同的方法,并且逻辑相同,只是细节上有差异时,可以考虑使用模板模式。具体的实现上可以将相同的核心算法设计为模板方法,具体的实现细节有子类实现。
缺点:每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
以生产电脑为例,电脑生产的过程都是一样的,只是一些装配的器件可能不同而已。
1,运行结果
2,代码示例
#include <iostream>
#include <thread>
#include <mutex>
#include <unistd.h>
#include <queue>
struct Record {
int work_1 = 0;
int work_2 = 0;
};
class DataQueue {
private:
std::mutex m_mutex;
std::queue<std::shared_ptr<Record> > m_queue;
public:
int pullRecord(std::shared_ptr<Record> &record);
int pushRecord(std::shared_ptr<Record> record);
};
int DataQueue::pullRecord(std::shared_ptr<Record> &record) {
std::lock_guard<std::mutex> guard(m_mutex);
if(m_queue.empty()) return -1;
record = m_queue.front();
m_queue.pop();
return 0;
};
int DataQueue::pushRecord(std::shared_ptr<Record> record) {
std::lock_guard<std::mutex> guard(m_mutex);
m_queue.push(record);
return 0;
};
class AbstractModule {
public:
virtual int pullRecord(std::shared_ptr<Record> &record) = 0;
virtual int pushRecord(std::shared_ptr<Record> record) = 0;
virtual int handle(std::shared_ptr<Record> in_record, std::shared_ptr<Record> &out_record) = 0;
virtual int getCount() = 0;
virtual ~AbstractModule() {};
};
class BasicModule : public AbstractModule {
private:
bool m_first = false;
DataQueue &m_input_queue;
DataQueue &m_output_queue;
public:
BasicModule(DataQueue &input_queue, DataQueue &output_queue):
m_input_queue(input_queue), m_output_queue(output_queue){} ;
// c++11 new features. entrust the constructor.
BasicModule(DataQueue &input_queue, DataQueue &output_queue, bool status):
BasicModule(input_queue, output_queue){m_first=status;};
int pullRecord(std::shared_ptr<Record> &record) override final;
int pushRecord(std::shared_ptr<Record> record) override final;
int handle(std::shared_ptr<Record> in_record, std::shared_ptr<Record> &out_record) override final;
virtual int getCount() = 0;
private:
virtual int pullData(std::shared_ptr<Record> in_Record, int &data) = 0;
virtual int pushData(std::shared_ptr<Record> &out_Record, int data) = 0;
virtual int inference(int &data) = 0;
};
int BasicModule::pullRecord(std::shared_ptr<Record> &record) {
if(m_first) {record = std::make_shared<Record>(); return 0;}
return m_input_queue.pullRecord(record);
}
int BasicModule::pushRecord(std::shared_ptr<Record> record) {
return m_output_queue.pushRecord(record);
}
int BasicModule::handle(std::shared_ptr<Record> in_record, std::shared_ptr<Record> &out_record) {
int data;
if(pullData(in_record, data) == 0) {inference(data); out_record = in_record; pushData(out_record, data);}
return 0;
}
class Work_1 : public BasicModule {
private:
int m_count = 0;
public:
//c++11 new features,inherited the constructor.
using BasicModule::BasicModule;
int getCount() override {return m_count;};
int pullData(std::shared_ptr<Record> in_record, int &data) override {data = in_record->work_1;return 0;};
int pushData(std::shared_ptr<Record> &out_record, int data) override {out_record->work_1 = data;return 0;};
int inference(int &data) override {data = m_count++; return 0;};
};
class Work_2 : public BasicModule {
private:
int m_count = 0;
public:
//c++11 new features,inherited the constructor.
using BasicModule::BasicModule;
int getCount() override {return m_count;};
int pullData(std::shared_ptr<Record> in_record, int &data) override {data = in_record->work_2;return 0;};
int pushData(std::shared_ptr<Record> &out_record, int data) override {out_record->work_2 = data;return 0;};
int inference(int &data) override {data = m_count++; return 0;};
};
class Thread {
private:
bool m_run_flag = true;
std::thread m_thread;
AbstractModule *m_module;
private:
int run() {
std::shared_ptr<Record> in_record;
std::shared_ptr<Record> out_record;
while(m_run_flag) {
if(m_module->pullRecord(in_record) == 0) {
m_module->handle(in_record, out_record);
m_module->pushRecord(out_record);
sleep(1);
}
}
};
public:
Thread(int type, DataQueue &in_queue, DataQueue &out_queue) {
switch(type) {
case 1:
m_module = new Work_1(in_queue, out_queue, true); break;
case 2:
m_module = new Work_2(in_queue, out_queue, false); break;
dafault:
throw std::string("Thread construct. error type!");
}
};
~Thread() {m_run_flag = false; delete m_module;};
int startThread() {
m_run_flag = true;
m_thread = std::thread(&Thread::run, this);
m_thread.detach();
return 0;
};
};
int main() {
DataQueue queue_1, queue_2, queue_3;
Thread thread_1(1, queue_1, queue_2);
Thread thread_2(2, queue_2, queue_3);
thread_1.startThread();
thread_2.startThread();
int count = 50;
while(count--){
sleep(1);
int data_1, data_2;
std::shared_ptr<Record> record;
if(queue_3.pullRecord(record) == 0) {
data_1 = record->work_1;
data_2 = record->work_2;
std::cout << "count:" << count << " data:" << data_1 << " " << data_2 << std::endl;
}
};
return 0;
}