赞
踩
学习视频:https://www.bilibili.com/video/BV1kW411P7KS?p=1
学习资料:https://github.com/liu-jianhao/Cpp-Design-Patterns
本文主要记录了Template Method(模板方法模式)、Strategy(策略模式)、Observer/Event(观察者模式)、Factory Method(工厂方法模式)、Abstract Factory(抽象工厂模式)、Singleton(单件模式、单例设计模式)、Composite(组合模式)。
1.依赖倒置原则(DIP)
2.开放封闭原则(OCP)
3.单一职责原则(SRP)
4.Liskov替换原则(LSP)
5.接口隔离原则(ISP)
6.优先使用对象组合,而不是类继承
7.封装变化点
8.针对接口编程,而不是针对实现编程
程序库开发人员和应用程序开发人员
程序库开发人员(Library)
class Library{
public:
void step1(){... }
void step3(){... }
void step5(){... }
};
应用程序开发人员(Application)
class Application : public Library{
public:
bool step2(){... }
bool step4(){... }
};
main
int main(){
Library lib;
Application app;
lib.Step1();
if (app.Step2()){
lib.Step3();
}
for (int i = 0; i < 4; i++){
app.Step4();
}
lib.Step5();
return 0;
}
程序库开发人员(Library)
class Library{ public: void run(){ //稳定 template method step1(); if(step2()){ step3(); //支持变化(虚函数的多态复用) } for(int i=0;i<4;++i){ step4(); //支持变化(虚函数的多态复用) } step5(); } virtual ~Library(){ } protected: void step1(){... } //稳定 void step3(){... } //稳定 void step5(){... } //稳定 virtual bool step2() = 0; //变化 virtual bool step4() = 0; //变化 };
应用程序开发人员(Application)
class Application : public Library{
protected:
virtual bool step2(){... } //子类重写
virtual bool step4(){... } //子类重写
};
main
int main(){
Library *p = new Application();
p->run();
delete p;
return 0;
}
销售订单的计算,需要考虑各个国家的汇率
销售订单类SalesOrder
enum TaxBase { CN_Tax, US_Tax, DE_Tax }; class SalesOrder{ TaxBase tax; public: double calculateTax(){ //... if (tax == CH_Tax){ //CH*********** } else if (tax == US_Tax){ //US*********** } else if (tax == DE_Tax){ //DE*********** } //.... } };
基类(父类)TaxStrategy
class TaxStrategy{
public:
virtual double calculate(const Context& context){ }
virtual TaxStrategy(){ }
};
派生类(子类)
//中国 class CHTax : public TaxStrategy{ public: virtual double calculate(const Context& context){...} }; //美国 class USTax : public TaxStrategy{ public: virtual double calculate(const Context& context){...} }; //德国 class DETax : public TaxStrategy{ public: virtual double calculate(const Context& context){...} }; //...当有新的国家的合作伙伴时,添加派生类即可
销售订单类SalesOrder
class SalesOrder{
private:
TaxStrategy* strategy;
public:
SalesOrder(StrategyFactory* stratrgyFactory){
this->stategy = strategyFactory->NewStrategy(); //此处使用了工厂生成模式,生成类
}
~SalesOrder(){
delete this->strategy;
}
double calculate_tax(){
strategy->calculate(context);
//...
}
};
文件分割器,界面显示分割加载进度的显示
文件分割类FileSplitter
class FileSplitter { string m_filePath; int m_fileNumber; ProgressBar* m_progressBar; //依赖细节(依赖进度条控件) public: FileSplitter(const string& filePath, int fileNumber, ProgressBar* progressBar) : m_filePath(filePath), m_fileNumber(fileNumber), m_progressBar(progressBar){ } void split(){ //1.读取大文件 //2.分批次向小文件中写入 for (int i = 0; i < m_fileNumber; i++){ //... float progressValue = m_fileNumber; progressValue = (i + 1) / progressValue;//更新进度条 m_progressBar->setValue(progressValue); } } };
界面显示(以进度条形式显示)
class MainForm : public Form{
TextBox* txtFilePath;
TextBox* txtFileNumber;
ProgressBar* progressBar; //显示定义为进度条的形式
public:
void Button1_Click(){
string filePath = txtFilePath->getText();
int number = atoi(txtFileNumber->getText().c_str());
FileSplitter splitter(filePath, number, progressBar);
splitter.split();
}
};
文件分割类FileSplitter
class IProgress{ //定义一个抽象的显示控件 public: virtual void DoProgress(float value)=0; virtual ~IProgress(){} }; class FileSplitter{ string m_filePath; int m_fileNumber; List<IProgress*> m_iprogressList; // 抽象通知机制,支持多个观察 public: FileSplitter(const string& filePath, int fileNumber) : m_filePath(filePath), m_fileNumber(fileNumber){ } void split(){ //1.读取大文件 //2.分批次向小文件中写入 for (int i = 0; i < m_fileNumber; i++){ //... float progressValue = m_fileNumber; progressValue = (i + 1) / progressValue; onProgress(progressValue);//发送通知 } } void addIProgress(IProgress* iprogress){ m_iprogressList.push_back(iprogress); } void removeIProgress(IProgress* iprogress){ m_iprogressList.remove(iprogress); } protected: virtual void onProgress(float value){ List<IProgress*>::iterator itor=m_iprogressList.begin(); while (itor != m_iprogressList.end() ) (*itor)->DoProgress(value); //更新进度条 itor++; } } };
界面显示
class MainForm : public Form, public IProgress { //多继承,这里继承抽象通知机制类,是为了解耦 TextBox* txtFilePath; TextBox* txtFileNumber; ProgressBar* progressBar; public: void Button1_Click(){ string filePath = txtFilePath->getText(); int number = atoi(txtFileNumber->getText().c_str()); ConsoleNotifier cn; FileSplitter splitter(filePath, number); splitter.addIProgress(this); // splitter.addIProgress(&cn); // splitter.split(); splitter.removeIProgress(this); } virtual void DoProgress(float value){ progressBar->setValue(value); } }; class ConsoleNotifier : public IProgress { public: virtual void DoProgress(float value){ cout << "."; } };
还是文件分割的例子,分割的对象可以是二进制文件、文本文件、视频文件
分割的文件类型
class ISplitter {
public:
virtual void split() = 0;
virtual ~ISplitter(){ }
};
class BinarySplitter : public ISplitter{ //分割二进制文件
};
class TxtSplitter : public ISplitter{ //分割文本文件
};
class PictureSplitter : public ISplitter{ //分割视频
};
界面显示
class MainForm : public Form{
TextBox* txtFilePath;
TextBox* txtFileNumber;
ProgressBar* progressBar;
public:
void Button1_Click(){
BinarySplitter splitter = new BinarySplitter(); //依赖具体类
splitter->split();
}
};
抽象的接口
//抽象类
class ISplitter {
public:
virtual void split() = 0;
virtual ~ISplitter(){ }
};
//工厂基类
class SplitterFactory{
public:
virtual ISpplitter* createSplitter() = 0;
virtual ~SplitterFactory(){ }
};
具体的类和工厂
//具体的类 class BinarySplitter : public ISplitter{ //分割二进制文件 }; class TxtSplitter : public ISplitter{ //分割文本文件 }; class VideoSplitter : public ISplitter{ //分割视频文件 }; //具体的工厂 class BinaryFactory : public SplitterFactory{ public: BinarySplitter* createSplitte(){ return new BinarySplitter(); } }; class TxtFactory : public SplitterFactory{ public: TxtSplitter* createSplitte(){ return new TxtSplitter(); } }; class VideoFactory : public SplitterFactory{ public: VideoSplitter* createSplitte(){ return new VideoSplitter(); } };
界面显示
class MainForm : public Form{
SplitterFactory* m_factory; //工厂
public:
MainForm(SplitterFactory* factory){
m_factory = factory;
}
void Button1_Click(){
ISplitter* splitter = m_factory->createSplitter(); //多态new
splitter->split();
}
};
数据访问层,访问不同数据库,connection、command、dataread
EmployeeDAO
class EmploeeDAO{
public:
vector<EmployeeDAO> getEmployees(){
SqlConnection* connection = new SqlConnection(); //绑定在了Sql上
connection->ConnectionString = "...";
SqlCommand* command = new SqlComand();
command->CommandText = "...";
SqlDataReader* reader = command ->ExecuteReader();
while(reader->Read()){
}
}
};
EmployeeDAO
class EmploeeDAO{ IDBConnectionFactory* dbConnectionFactory; IDBCommandFactory* dbCommandFactory; IDataReaderFactory* dataReaderFactory; public: vector<EmployeeDAO> getEmployees(){ IDBConnection* connection = dbConnectionFactory->CreateDBConnection(); connection->ConnectionString = "..."; IDBCommand* command = dbCommandFactory->CreateDBComand(); command->CommandText = "..."; command->SetConnection(connection); //关联性 IDataReader* reader = command ->ExecuteReader();//关联性 while(reader->Read()){ } } };
数据库访问有关的基类、子类
//数据库访问有关的基类 class IDBConnection{ }; class IDBConnectionFactory{ public: virtual IDBConnection* CreateDBConnection() = 0; }; class IDBCommand{ }; class IDBCommandFactory{ public: virtual IDBCommand* CreateDBCommand() = 0; }; class IDataReader{ }; class IDataReaderFactory{ public: virtual IDataReader* CreateDataReader() = 0; }; //支持SQL Server class SqlConnection: public IDBConnection{ //... }; class SqlConnectionFactory:public IDBConnectionFactory{ //... }; class SqlCommand: public IDBCommand{ //... }; class SqlCommandFactory:public IDBCommandFactory{ //... }; class SqlDataReader: public IDataReader{ //... }; class SqlDataReaderFactory:public IDataReaderFactory{ //... }; //支持Oracle class OracleConnection: public IDBConnection{ //... }; class OracleCommand: public IDBCommand{ //... }; class OracleDataReader: public IDataReader{ //... }; //...
EmployeeDAO
class EmploeeDAO{
IDBFactory* dbFactory;
public:
vector<EmployeeDAO> getEmployees(){
IDBConnection* connection = dbFactory->CreateDBConnection();
connection->ConnectionString = "...";
IDBCommand* command = dbFactory->CreateDBComand();
command->CommandText = "...";
command->SetConnection(connection); //关联性
IDataReader* reader = command ->ExecuteReader();//关联性
while(reader->Read()){
}
}
};
数据库访问有关的基类、派生类,工厂基类、派生类
//数据库访问有关的基类 class IDBConnection{ }; class IDBCommand{ }; class IDataReader{ }; class IDBFactory{ //即将工厂类抽象为基类 public: virtual IDBConnection* CreateDBConnection() = 0; virtual IDBCommand* CreateDBCommand() = 0; virtual IDataReader* CreateDataReader() = 0; }; //支持SQL Server class SqlConnection: public IDBConnection{ }; class SqlCommand: public IDBCommand{ }; class SqlDataReader: public IDataReader{ }; class SqlDBFactory:public IDBFactory{ //工厂派生类 public: virtual IDBConnection* CreateDBConnection()=0; virtual IDBCommand* CreateDBCommand()=0; virtual IDataReader* CreateDataReader()=0; }; //支持Oracle class OracleConnection: public IDBConnection{ }; class OracleCommand: public IDBCommand{ }; class OracleDataReader: public IDataReader{ }; //...
Singleton类
class Singleton{
public:
static Singleton* m_instance;
private:
Singleton();
Singleton(const Singleton& other);
public:
static Singleton* getInstance();
};
线程非安全的版本:getInstance()
Singleton* Singleton::getInstance(){
if(m_instance == nullptr){
m_instance = new Singleton();
}
return m_instance;
}
线程安全,但锁代价过高:getInstance()
Singleton* Singleton::getInstance(){
Lock lock;
if(m_instance == nullptr){
m_instance = new Singleton();
}
return m_instance;
}
双检查锁,但由于内存读写reorder不安全:getInstance()
Singleton* Singleton::getInstance(){
if(m_instance == nullptr){
Lock lock;
if(m_instance == nullptr){
m_instance = new Singleton();
}
}
return m_instance;
}
C++11版本之后的跨平台实现(volatile)
std::atomic<Singleton*> Singleton::m_instance; std::mutex Singleton::m_mutex; Singleton* Singleton::getInstance() { Singleton* tmp = m_instance.load(std::memory_order_relaxed); std::atomic_thread_fence(std::memory_order_acquire);//获取内存fence if (tmp == nullptr) { std::lock_guard<std::mutex> lock(m_mutex); tmp = m_instance.load(std::memory_order_relaxed); if (tmp == nullptr) { tmp = new Singleton; std::atomic_thread_fence(std::memory_order_release);//释放内存fence m_instance.store(tmp, std::memory_order_relaxed); } } return tmp; }
Component基类
class Component{
public:
virtual void process() = 0;
virtual ~Component(){ }
};
Composite派生类
//树节点 class Composite : public Component{ string m_name; list<Component*> m_elements; public: Composite(const string &s):m_name(s){ } void add(Component* element){ m_elements.push_back(element); } void remove(Component* element){ m_elements.remove(element); } void process(){ // 1. process current node // 2. process leaf node for(auto &e : m_elements) e->process(); //多态调用 } };
Leaf派生类
//叶子结点
class Leaf : public Component{
string m_name;
public:
Leaf(string s):m_name(s){ }
void process(){...}
};
Invoke函数
void Invoke(Component &c){
//...
c.process();
//...
}
main
int main(){ Composite root("root"); Composite treeNode1("treeNode1"); Composite treeNode2("treeNode2"); Composite treeNode3("treeNode3"); Composite treeNode4("treeNode4"); Leaf leaf1("leaf1"); Leaf leaf2("leaf2"); root.add(&treeNode1); treeNode1.add(&treeNode2); treeNode2.add(&leaf1); root.add(&treeNode3); treeNode3.add(&treeNode4); treeNode4.add(&leaf2); process(root); process(leaf2); process(treeNode3); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。