工厂方法模式
#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的时候, 我们还是需要传入一个子类 抽象工厂 的,比如SqlDatabaseFactory
std::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()