工厂模式
工厂方法
动机
软件系统中经常面临着创建对象的工作,由于需求变化,创建对象的具体类型经常变化。通过对象创建绕开new,来避免new过程中的紧耦合(以来具体类)。是接口完成后的第一步工作。
例子
- 这个例子不是线程安全的
- 一共有三个主要的类:Mainform、FileSpliter、SpliterFactory
- Mainform调用SpliterFactory(文件分割器工厂)产生不同的FileSpliter(文件分割器)
- 使用shared_ptr避免内存管理的麻烦
- 工厂模式不是要消除依赖,而是要把依赖“关起来”,在这个例子中依赖只存在于SpliterFactory和FileSpliter
代码
mainform.h
#ifndef MAINFORM_H
#define MAINFORM_H
#include "spliterfactory.h"
class Mainform
{
private:
//工厂应该只有一个
SpliterFactory* factory_;
public:
//利用构造函数指定对应的工厂函数
Mainform(SpliterFactory* factory)
{
this->factory_ = factory;
}
virtual ~Mainform() {}
int do_some()
{
auto spliter = factory_->CreateSpliter();
//...
return 0;
}
};
#endif /* MAINFORM_H */
spliterfactory.h
#ifndef SPLITERFACTORY_H
#define SPLITERFACTORY_H
#include <memory>
#include "filespliter.h"
//抽象基类
class SpliterFactory
{
public:
virtual std::unique_ptr<FileSpliter> CreateSpliter() = 0;
public:
SpliterFactory() {}
virtual ~SpliterFactory() {}
};
//不同的子类
class BinaryFileSpliterFactory : public SpliterFactory
{
public:
//返回unique_ptr,避免手动内存管理,多线程情况下应该用shared_ptr?应该是的。
virtual std::unique_ptr<FileSpliter> CreateSpliter()
{
auto file_spliter = std::unique_ptr<BinaryFileSpliter>(new BinaryFileSpliter());
return file_spliter;
}
public:
BinaryFileSpliterFactory() {}
virtual ~BinaryFileSpliterFactory() {}
};
class TxtFileSpliterFactory : public SpliterFactory
{
public:
virtual std::unique_ptr<FileSpliter> CreateSpliter()
{
auto file_spliter = std::unique_ptr<TxtFileSpliter>(new TxtFileSpliter());
return file_spliter;
}
public:
TxtFileSpliterFactory() {}
virtual ~TxtFileSpliterFactory();
};
#endif /* SPLITERFACTORY_H */
filespliter.h
#ifndef FILESPLITER_H
#define FILESPLITER_H
class FileSpliter
{
public:
FileSpliter() {}
virtual ~FileSpliter() {}
};
class BinaryFileSpliter : public FileSpliter
{
public:
BinaryFileSpliter() {}
virtual ~BinaryFileSpliter() {}
};
class TxtFileSpliter : public FileSpliter
{
public:
TxtFileSpliter() {}
virtual ~TxtFileSpliter() {}
};
#endif /* FILESPLITER_H */
抽象工厂
动机
软件系统中经常面对一系列相互依赖的对象的创建,抽象工厂绕过new,提供一组封装,来避免紧耦合
例子
- 假如有数据库类,提供connect、insert、delete等操作,与上面的简单工厂不同(只有一个操作)
- 那么在创建工厂类的时候要把这些操作封装在一个工厂函数里
- 工厂方法可以看做抽象工厂的特例(只创建一个抽像工厂)
代码
dbfactory.h
#ifndef DBFACTORY_H
#define DBFACTORY_H
#include <memory>
#include "db.h"
class Dbfactory
{
public:
virtual std::unique_ptr<DBConnection> CreateConnection() = 0;
virtual std::unique_ptr<DBCommand> CreateCommand() = 0;
public:
Dbfactory() {}
virtual ~Dbfactory() {}
};
class SqlDBFactory
{
public:
virtual std::unique_ptr<DBConnection> CreateConnection() {}
virtual std::unique_ptr<DBConnection> CreateCommand() {}
public:
SqlDBFactory() {}
virtual ~SqlDBFactory() {}
};
class OracleDBFactory
{
public:
virtual std::unique_ptr<DBConnection> CreateConnection() {}
virtual std::unique_ptr<DBConnection> CreateCommand() {}
public:
OracleDBFactory() {}
virtual ~OracleDBFactory() {}
};
#endif /* DBFACTORY_H */
db.h
#ifndef DB_H
#define DB_H
class DBConnection
{
public:
DBConnection();
virtual ~DBConnection();
};
class DBCommand
{
public:
DBCommand() {}
virtual ~DBCommand() {}
};
class SqlDBConnection
{
public:
SqlDBConnection();
virtual ~SqlDBConnection();
};
class SqlDBCommand
{
public:
SqlDBCommand() {}
virtual ~SqlDBCommand() {}
};
class OracleDBConnection
{
public:
OracleDBConnection();
virtual ~OracleDBConnection();
};
class OracleDBCommand
{
public:
OracleDBCommand() {}
virtual ~OracleDBCommand() {}
};
#endif /* DB_H */