首页 > 工厂方法模式和抽象工厂模式

工厂方法模式和抽象工厂模式

工厂方法模式和抽象工厂模式

        • 工厂方法模式
        • 抽象工厂模式
        • 总结:

工厂方法模式

#include 
#include // 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 
#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 
#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 
#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 // 第二
// 下面的函数中, 用到了三个具体类型, 根据这三个具体类型,我们就需要定义三个抽象类型
// 同时我们说,抽象工厂模式主要解决的问题是,需要创建一系列相关的对象,下面三个对象就是一系列相关的对象
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::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::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::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()

更多相关:

  • 简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式。其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性。 本文是本人对这三种模式学习后的一个小结以及对他们之间的区别的理解。   简单工厂 简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。...

  • 简介 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。 不同点 为了更清晰地理解抽象工厂模式,需要先引入两个概念:产品等级结构 :产品等级结构即产品的继承结构,如一个抽象类是CPU,其子类有intel...

  • 工厂方法模式: 一个抽象产品类,可以派生出多个具体产品类。 一个抽象工厂类,可以派生出多个具体工厂类。 每个具体工厂类只能创建一个具体产品类的实例。 抽象工厂模式: 多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。 一个抽象工厂类,可以派生出多个具体工厂类。 每个具体工厂类可以创建多个具体产品类的实例。 区别:...

  • 又重头想了一下还是以配电脑为例最开始的时候,需要电脑,你得自己去生产电脑的每一个组件,例如你要cpu 就得自己生产cpu 要主板就得自己生产主板。于是出现 简单工厂模式在简单工厂模式中,定义一个返回接口,然后所有的组件实例都从这个工厂中产生例: 工厂---------生产硬件 硬件----------...

  • 在.Net Framework中,配置文件一般采用的是XML格式的,.NET Framework提供了专门的ConfigurationManager来读取配置文件的内容,.net core中推荐使用json格式的配置文件,那么在.net core中该如何读取json文件呢?1、在Startup类中读取json配置文件1、使用Confi...

  •   1 public class FrameSubject extends JFrame {   2    3   …………..   4    5   //因为无法使用多重继承,这儿就只能使用对象组合的方式来引入一个   6    7   //java.util.Observerable对象了。   8    9   DateSub...

  • 本案例主要说明如何使用NSwag 工具使用桌面工具快速生成c# 客户端代码、快速的访问Web Api。 NSwagStudio 下载地址 比较强大、可以生成TypeScript、WebApi Controller、CSharp Client  1、运行WebApi项目  URL http://yourserver/swagger 然后...

  •   在绑定完Action的所有参数后,WebAPI并不会马上执行该方法,而要对参数进行验证,以保证输入的合法性.   ModelState 在ApiController中一个ModelState属性用来获取参数验证结果.   public abstract class ApiController : IHttpController,...

  • 1# 引用  C:AVEVAMarineOH12.1.SP4Aveva.ApplicationFramework.dll C:AVEVAMarineOH12.1.SP4Aveva.ApplicationFramework.Presentation.dll 2# 引用命名空间, using Aveva.Applicati...