工厂方法模式和抽象工厂模式
工廠方法模式和抽象工廠模式
- 工廠方法模式
- 抽象工廠模式
- 總結:
工廠方法模式
#include <string>
#include <iostream>// Abstract
class Splitter
{
private:/* data */
public:Splitter(/* args */);virtual ~Splitter();
public:virtual void split() = 0;
};Splitter::Splitter(/* args */)
{
}Splitter::~Splitter()
{
}class BinarySplitter : public Splitter
{
private:/* data */
public:BinarySplitter(/* args */);~BinarySplitter();void split();
};BinarySplitter::BinarySplitter(/* args */)
{
}BinarySplitter::~BinarySplitter()
{
}void BinarySplitter::split() {std::cout << "Binary split" << std::endl;
}class TxtSplitter : public Splitter
{
private:/* data */
public:TxtSplitter(/* args */);~TxtSplitter();void split();
};TxtSplitter::TxtSplitter(/* args */)
{
}TxtSplitter::~TxtSplitter()
{
}void TxtSplitter::split() {std::cout << "Txt split"<< std::endl;
}class PictureSplitter : public Splitter
{
private:/* data */
public:PictureSplitter(/* args */);~PictureSplitter();void split();
};PictureSplitter::PictureSplitter(/* args */)
{
}PictureSplitter::~PictureSplitter()
{
}void PictureSplitter::split() {std::cout << "Picture split" << std::endl;
}class VideoSplitter : public Splitter
{
private:/* data */
public:VideoSplitter(/* args */);~VideoSplitter();void split();
};VideoSplitter::VideoSplitter(/* args */)
{
}VideoSplitter::~VideoSplitter()
{
}void VideoSplitter::split() {std::cout << "Video split" << std::endl;
}
#include <string>
#include "splitter.hpp"// Factory 是一個工廠
class Factory
{
private:/* data */
public:Factory(/* args */);virtual Splitter* creat_splitter(std::string splitter) = 0;~Factory();
};Factory::Factory(/* args */)
{
}Factory::~Factory()
{
}Splitter* Factory::creat_splitter(std::string splitter) {
}class TxtFactory : public Factory
{
private:/* data */
public:TxtFactory(/* args */);~TxtFactory();Splitter* creat_splitter(std::string splitter);
};TxtFactory::TxtFactory(/* args */)
{
}TxtFactory::~TxtFactory()
{
}Splitter* TxtFactory::creat_splitter(std::string splitter) {return new TxtSplitter();
}class PictureFactory : public Factory
{
private:/* data */
public:PictureFactory(/* args */);~PictureFactory();Splitter* creat_splitter(std::string splitter);
};PictureFactory::PictureFactory(/* args */)
{
}PictureFactory::~PictureFactory()
{
}Splitter* PictureFactory::creat_splitter(std::string splitter) {return new PictureSplitter();
}class VideoFactory : public Factory
{
private:/* data */
public:VideoFactory(/* args */);~VideoFactory();Splitter* creat_splitter(std::string splitter);
};VideoFactory::VideoFactory(/* args */)
{
}VideoFactory::~VideoFactory()
{
}Splitter* VideoFactory::creat_splitter(std::string splitter) {return new VideoSplitter();
}class BinaryFactory : public Factory
{
private:/* data */
public:BinaryFactory(/* args */);~BinaryFactory();Splitter* creat_splitter(std::string splitter);
};BinaryFactory::BinaryFactory(/* args */)
{
}BinaryFactory::~BinaryFactory()
{
}Splitter* BinaryFactory::creat_splitter(std::string splitter) {return new BinarySplitter();
}
#include <iostream>
#include "splitter.hpp"
#include "splitter_factory.hpp"class Mainform
{
private:Factory* factory_;/* data */
public:Mainform(Factory *factory);~Mainform();Splitter* get_splitter();
};Mainform::Mainform(Factory *factory) {factory_ = factory;
}Mainform::~Mainform()
{
}Splitter* Mainform::get_splitter() {return factory_->creat_splitter("xxx");
}
#include <iostream>
#include "splitter.hpp"
#include "splitter_factory.hpp"
#include "mainform.hpp"int main()
{// 最外面使用的時候, 肯定是要創建一個具體的工廠類,然后把具體的工廠類提供給我們的對外接口類// 由這個對外接口類返回一個具體的產品 TxtFactory txtfactory;Mainform mainform(&txtfactory);Splitter* splitter = mainform.get_splitter();return 0;
}
抽象工廠模式
#include <vector>// 第二
// 下面的函數中, 用到了三個具體類型, 根據這三個具體類型,我們就需要定義三個抽象類型
// 同時我們說,抽象工廠模式主要解決的問題是,需要創建一系列相關的對象,下面三個對象就是一系列相關的對象
class AbConnection
{
private:/* data */
public:AbConnection(/* args */);~AbConnection();
};AbConnection::AbConnection(/* args */)
{
}AbConnection::~AbConnection()
{
}class AbCommand
{
private:/* data */
public:AbCommand(/* args */);~AbCommand();
};AbCommand::AbCommand(/* args */)
{
}AbCommand::~AbCommand()
{
}class AbDataReader
{
private:/* data */
public:AbDataReader(/* args */);~AbDataReader();
};AbDataReader::AbDataReader(/* args */)
{
}AbDataReader::~AbDataReader()
{
}// 第三
// 下面函數中用到了三個具體類型,那么就需要定義三個具體的類型
// 支持Sql的數據庫相關的類型
class SqlConnection : public AbConnection
{
private:/* data */
public:SqlConnection(/* args */);~SqlConnection();
};SqlConnection::SqlConnection(/* args */)
{
}SqlConnection::~SqlConnection()
{
}class SqlCommand : public AbCommand
{
private:/* data */
public:SqlCommand(/* args */);~SqlCommand();
};SqlCommand::SqlCommand(/* args */)
{
}SqlCommand::~SqlCommand()
{
}class SqlDataReader : public AbDataReader
{
private:/* data */
public:SqlDataReader(/* args */);~SqlDataReader();
};SqlDataReader::SqlDataReader(/* args */)
{
}SqlDataReader::~SqlDataReader()
{
}// 支持Oracle的數據庫相關類型
class OracleConnection : public AbConnection
{
private:/* data */
public:OracleConnection(/* args */);~OracleConnection();
};OracleConnection::OracleConnection(/* args */)
{
}OracleConnection::~OracleConnection()
{
}class OracleCommand : public AbCommand
{
private:/* data */
public:OracleCommand(/* args */);~OracleCommand();
};OracleCommand::OracleCommand(/* args */)
{
}OracleCommand::~OracleCommand()
{
}class OracleDataReader : public AbDataReader
{
private:/* data */
public:OracleDataReader(/* args */);~OracleDataReader();
};OracleDataReader::OracleDataReader(/* args */)
{
}OracleDataReader::~OracleDataReader()
{
}// // 第五步
// // 因為第四步的使用中,new的部分還有具體的類型,這個時候我們可以考慮先使用工廠模式進行實現,
// // 于是針對上面的三個抽象基類,需要定義三個抽象基類對應的三個抽象工廠// class AbConnectionFactory
// {
// private:
// /* data */
// public:
// AbConnectionFactory(/* args */);
// ~AbConnectionFactory();
// virtual AbConnection* CreatConnection() = 0;
// };// AbConnectionFactory::AbConnectionFactory(/* args */)
// {
// }// AbConnectionFactory::~AbConnectionFactory()
// {
// }// class AbCommandFactory
// {
// private:
// /* data */
// public:
// AbCommandFactory(/* args */);
// ~AbCommandFactory();
// virtual AbCommand* CreatCommand() = 0;
// };// AbCommandFactory::AbCommandFactory(/* args */)
// {
// }// AbCommandFactory::~AbCommandFactory()
// {
// }// class AbDataReaderFactory
// {
// private:
// /* data */
// public:
// AbDataReaderFactory(/* args */);
// ~AbDataReaderFactory();
// virtual AbDataReader* CreatDataReader() = 0;
// };// AbDataReaderFactory::AbDataReaderFactory(/* args */)
// {
// }// AbDataReaderFactory::~AbDataReaderFactory()
// {
// }// 第十步
// 既然三個工廠創建的三個產品之間是相互關聯的,那我們就可以考慮,將三個工廠方法合并成一個工廠工廠方法
// 既然是三個工廠方法的基類合并成一個了,我們就實際是定義了一個抽象工廠
// 于是就可以把下面的三個工廠方法的基類給合并成一個,
// 我們就可以把第五步的三個工廠方法給改成一個class AbDatabaseFactory
{
private:/* data */
public:AbDatabaseFactory(/* args */);~AbDatabaseFactory();virtual AbConnection* CreatConnection() = 0;virtual AbCommand* CreatCommand() = 0;virtual AbDataReader* CreatDataReader() = 0;
};AbDatabaseFactory::AbDatabaseFactory(/* args */)
{
}AbDatabaseFactory::~AbDatabaseFactory()
{
}// // 第六步
// // 有了抽象工廠方法類之后, 就需要三個具體工廠方法類
// // 這里因為有Sql和Oracle,然后是三個類,所以需要六個具體的工廠方法類
// class SqlConnectionFactory : public AbConnectionFactory
// {
// private:
// /* data */
// public:
// SqlConnectionFactory(/* args */);
// ~SqlConnectionFactory();
// };// SqlConnectionFactory::SqlConnectionFactory(/* args */)
// {
// }// SqlConnectionFactory::~SqlConnectionFactory()
// {
// }// class SqlCommandFactory : public AbCommandFactory
// {
// private:
// /* data */
// public:
// SqlCommandFactory(/* args */);
// ~SqlCommandFactory();
// };// SqlCommandFactory::SqlCommandFactory(/* args */)
// {
// }// SqlCommandFactory::~SqlCommandFactory()
// {
// }// class SqlDataReader : public AbDataReaderFactory
// {
// private:
// /* data */
// public:
// SqlDataReader(/* args */);
// ~SqlDataReader();
// };// SqlDataReader::SqlDataReader(/* args */)
// {
// }// SqlDataReader::~SqlDataReader()
// {
// }// class OracleConnectionFactory : public AbConnectionFactory
// {
// private:
// /* data */
// public:
// OracleConnectionFactory(/* args */);
// ~OracleConnectionFactory();
// };// OracleConnectionFactory::OracleConnectionFactory(/* args */)
// {
// }// OracleConnectionFactory::~OracleConnectionFactory()
// {
// }// class OracleCommandFactory : public AbCommandFactory
// {
// private:
// /* data */
// public:
// OracleCommandFactory(/* args */);
// ~OracleCommandFactory();
// };// OracleCommandFactory::OracleCommandFactory(/* args */)
// {
// }// OracleCommandFactory::~OracleCommandFactory()
// {
// }// class OracleDataReaderFactory : public AbDataReaderFactory
// {
// private:// public:
// OracleDataReaderFactory(/* args */);
// ~OracleDataReaderFactory();
// };// OracleDataReaderFactory::OracleDataReaderFactory(/* args */)
// {
// }// OracleDataReaderFactory::~OracleDataReaderFactory()
// {
// }// 第十一步
// 同樣的道理, 既然我三個工廠方法的基類已經合成一個了, 那么我的Sql的三個工廠方法,和Oracle的三個工廠方法也應該合成一個
// 于是可以把第六步中的內容修改如下class SqlDatabaseFactory : public AbDatabaseFactory
{
private:/* data */
public:SqlDatabaseFactory(/* args */);~SqlDatabaseFactory();AbConnection* CreatConnection();AbCommand* CreatCommand();AbDataReader* CreatDataReader();
};SqlDatabaseFactory::SqlDatabaseFactory(/* args */)
{
}SqlDatabaseFactory::~SqlDatabaseFactory()
{
}AbConnection* SqlDatabaseFactory::CreatConnection() {return new SqlConnection();
}
AbCommand* SqlDatabaseFactory::CreatCommand() {return new SqlCommand();
}
AbDataReader* SqlDatabaseFactory::CreatDataReader() {return new SqlDataReader();
}class OracleDatabaseFactory : public AbDatabaseFactory
{
private:/* data */
public:OracleDatabaseFactory(/* args */);~OracleDatabaseFactory();AbConnection* CreatConnection();AbCommand* CreatCommand();AbDataReader* CreatDataReader();
};OracleDatabaseFactory::OracleDatabaseFactory(/* args */)
{
}OracleDatabaseFactory::~OracleDatabaseFactory()
{
}AbConnection* OracleDatabaseFactory::CreatConnection() {return new OracleConnection();
}
AbCommand* OracleDatabaseFactory::CreatCommand() {return new OracleCommand();
}
AbDataReader* OracleDatabaseFactory::CreatDataReader() {return new OracleDataReader();
}class EmployeeDAO
{
private:// // 第七步// // 因為需要在后面的函數中get_employees中,所以需要先定義三個抽象的工廠// // 用戶在創建一個EmployeeDAO的時候, 在構造函數中,需要傳入具體的三個工廠,用來初始化三個抽象工廠// AbConnectionFactory* ab_connection_factory;// AbCommandFactory* ab_command_factory;// AbDataReaderFactory* ab_datareader_factory;// 第十二步// 既然已經有了抽象工廠模式,這個時候就可以把第七步中的三個工廠合并成一個工廠了AbDatabaseFactory* ab_database_factory;// 第九步// 看看問題所在// 我們在實際使用中, 需要在main函數中,調用EmployeeDAO的構造函數,第七步中說了,實例化一個EmployeeDAO的時候// 需要傳入三個具體的工廠,在構造函數中, 把上面三個抽象的工廠給實例化了// 那么我們傳入的三個工廠必須是同一個類型的三個抽象工廠// 比如第一個工廠是Sql的,那么第二個工廠不能是Oracle的,因為在下面的一個函數的實際使用中,三個工廠做出來的實際對象// 三個具體對象之間是有直接關系的, 是相互依賴的public:EmployeeDAO(/* args */);~EmployeeDAO();std::vector<EmployeeDAO> get_employees();
};EmployeeDAO::EmployeeDAO(/* args */)
{
}EmployeeDAO::~EmployeeDAO()
{
}// 第一
// 如下就是一系列相互依賴的對象
// 同時存在一個問題就是,如果下次變成了MySql或者Redis的時候,下面函數的整個實現都需要修改
// std::vector<EmployeeDAO> EmployeeDAO::get_employees() {
// SqlConnection* connect = new SqlConnection();
// connect->ConnectString = "xxx";// SqlCommand* command = new SqlCommand();
// command->set_connection(connec);
// command->CommandTxt = "xxx";// SqlDataReader* reader = command->ExecuteReader();
// while (read->Read())
// {
// std::cout << "xxx" << std::endl;
// }// }// // 第四步
// // 既然上面定義抽象類型了, 所以我們需要重新寫第一中的內容, 把其中用到具體類型的地方, 都修改成使用抽象類型的對象// std::vector<EmployeeDAO> EmployeeDAO::get_employees() {
// AbConnection* connect = new SqlConnection();// connect->ConnectString = "xxx";// AbCommand* command = new SqlCommand();
// command->set_connection(connec);
// command->CommandTxt = "xxx";// AbDataReader* reader = command->ExecuteReader();
// while (read->Read())
// {
// std::cout << "xxx" << std::endl;
// }// }// // 第八步
// // 因為上面在類內部定義了三個抽象的工廠指針,所以需要在函數里面使用抽象的工廠指針進行創建具體的產品// std::vector<EmployeeDAO> EmployeeDAO::get_employees() {
// AbConnection* connect = ab_connection_factory->CreatConnection();
// connect->ConnectString = "xxx";// AbCommand* command = ab_command_factory->CreatCommand();
// // 另外需要注意的點是,三個對象之間具有相關性,這個是抽象工廠方法的精髓所在,一定是一系列對象之間具有相關性
// command->set_connection(connec);
// command->CommandTxt = "xxx";// AbDataReader* reader = command->ExecuteReader();
// while (read->Read())
// {
// std::cout << "xxx" << std::endl;
// }// }// 第十三步
// 我們有了一個三合一的抽象工廠,那么這個時候就可以把第八步的內容給修改了
// 當然在定義這個類,EmployeeDAO的時候, 我們還是需要傳入一個子類 抽象工廠 的,比如SqlDatabaseFactorystd::vector<EmployeeDAO> EmployeeDAO::get_employees() {AbConnection* connect = ab_database_factory->CreatConnection();connect->ConnectString = "xxx";AbCommand* command = ab_database_factory->CreatCommand();// 另外需要注意的點是,三個對象之間具有相關性,這個是抽象工廠方法的精髓所在,一定是一系列對象之間具有相關性 command->set_connection(connec);command->CommandTxt = "xxx";AbDataReader* reader = command->ExecuteReader();while (read->Read()){std::cout << "xxx" << std::endl;}}
總結:
工廠方法模式:
一般用于我們需要根據不通的情況創建不同的產品, 為了讓客戶調用的時候不用依賴具體的類,使用工廠方法模式, 一般需要創建創建四組類:
第一種: 抽象產品類 Product
第二種:具體產品類,其父類是Product,具體產品類可以是ProductA,ProductB
第三種:抽象工廠方法類 AbFactory,他提供了一個接口CreateProduct,用于創建產品Product
第四種:具體工廠方法類,其父類是AbFactory,具體工廠方法類可以是FactoryA, FactoryB…,FactoryA和FactoryB都需要實現從父類集成來的CreateProduct,只不過FactoryA返回的是ProductA, FactoryB返回的是ProductB
用戶在使用的過程中,大概用法如下:
第一步定義自己需要具體工廠比如FactoryA fa,
第二步調用fa的CreateProduct方法,獲取具體子類ProductA
抽象工廠模式:用于解決需要創建一系列相互依賴的對象, 重點是解決相互依賴
我們可以先使用工廠方式模式解決這個問題,這里也需要四組類型
第一種: 抽象產品類 Product
第二種:具體產品類,其父類是Product,具體產品類可以是ProductA,ProductB
我們這里可能還有其他抽象類,比如Goods,和上面類似, 需要父類Goods, 和子類GoodsA, GoodsB
第三種:工廠方法父類ProductFactory,GoodsFactory,分別提供CreateProduct和CreateGoods
第四種:具體的工廠方法類ProductFactoryA, ProductFactoryB,GoodsFactoryA, GoodsFactoryB
在使用的時候考慮這樣子一種使用場景, 我們可以利用ProductFactoryA和GoodsFactoryA創建ProductA,和GoodsA,并且ProductA和GoodsA是相互相關的, 那么用戶在使用的過程中, 可能出現如下問題, 創建了ProductA和GoodsB,使用上就會出現錯誤,
于是我們把上面的第三種和第四種類型改動一下,第三種類型中, 我們把工廠(ProductFactory和GoodsFactory)合二為一變成ThingsFactory, 他提供提供了兩個方法 CreateProduct和CreateGoods
第四種實現具體的工廠, ThingsFactoryA在實現CreateProduct和CreateGoods時分別返回 ProductA和GoodsA, 同理ThingsFactoryB
用戶使用的時候:
第一步,定義自己具體需要的抽象工廠 ThingsFactoryA tfa;
Product pa = tfa.CreateProduct()
Goods ga = tfa.CreateGoods()
總結
以上是生活随笔為你收集整理的工厂方法模式和抽象工厂模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求一个不在意你的人个性签名!
- 下一篇: git 快速复制一个新项目