工厂的设计模式替代方案:类 具有不同的构造函数
Design pattern alternative for factories : classes with different constructors
我正在编写一个可以启动新进程的应用程序'。我已经确定这些流程在两个方面存在根本差异,它们可以 运行 独立运行或依赖现有流程运行。因此,我创建了两个抽象 classes,继承自基础抽象 class.
我正在尝试编写一个工厂模式或其他设计模式,根据我提供的文件扩展名字符串 return 我需要 class,这将发生在 运行时间。然而,我不认为工厂模式是一个好的、明智的选择,因为这些根本差异导致不同的构造函数。我可以自己编写一个巨大的 switch 或嵌套 if 语句,但对于这个项目,我真的想增加我的 c++ 知识(这是我第一次真正使用继承)。
说我有我的抽象基础 class :
class launchable {
protected:
std::string name;
std::string directory;
std::string path;
std::string fileType;
std::vector<std::string> launchArgs;
bool hasLaunched;
launchable(std::string _name, std::string _directory,std::string _fileType,std::vector<std::string> _args);
public:
virtual void start() = 0;
virtual void stop() = 0;
virtual void writeMessage(std::string theMessage) = 0;
virtual boost::optional<std::string> readMessage() = 0;
};
然后是两个进一步的抽象 class 继承自此,首先是一个独立的 class starts/stops 并写入其自己的进程:
class standalone : public launchable{
protected:
processManager *manager;
std::shared_ptr<processManager::launchableProcess> process;
virtual std::string formatWriteMessage(std::string theMessage) = 0;
standalone(std::string _name, std::string _directory,std::string _fileType,std::vector<std::string> _args,processManager *_manager);
public:
virtual void start() = 0;
virtual void stop() = 0;
void writeMessage(std::string theMessage);
boost::optional<std::string> readMessage();
};
和一个必须 start/stop/read/write 通过独立流程的受抚养人 class:
class dependent : public launchable{
protected:
standalone *dependency;
dependent(std::string _name, std::string _directory,std::string _type,std::vector<std::string> _args,standalone *_dependency);
public:
virtual void start() = 0;
virtual void stop() = 0;
void writeMessage(std::string theMessage);
boost::optional<std::string> readMessage();
};
在命令行上 运行 的具体独立 *nix 可执行文件示例:
class executable : public standalone {
private:
std::string formatWriteMessage(std::string theMessage);
public:
using standalone::standalone;
void start();
void stop();
};
并且示例具体可靠,超级对撞机补丁必须 运行 通过 *nix 命令行解释器:
class supercolliderPatch : public dependent {
public:
using dependent::dependent;
void start();
void stop();
};
所以理想情况下我想要的是(伪代码):
launchable *sclang = launchableFactory.create("exec",ARGS); // returns a standalone
launchable *patch = launchableFactory.create("supercolliderPatch",sclang,ARGS) // returns a dependable, with dependency set to sclang
这些可启动的*实例将存储在 std::vector.
中
基本上我的问题是:我是不是在把 standalone/dependent 的这两个概念混为一谈,或者工厂模式对我有用吗?
抽象工厂让您完全做到这一点:构造一些具体实例并将其视为抽象接口。
如果您找不到一个共同的接口来同时使用两者 类,那么您可能需要重新考虑您的设计,但在您的情况下这似乎不是问题。
你可以试试这个,一些函数式编程,但它可能会对性能产生一些最小的负面影响。它还需要 C++11 或更高版本
std::function<shared_ptr<Base>()> funcs[] = { [](){ return shared_ptr<Base>(new A()); }, [](){ return shared_ptr<Base>(new B()); } };
然后调用:
funcs[i]();
为了安全起见,您可以使用类似 array
的东西。
std::array<std::function<shared_ptr<Base>()>, 2> funcs[] =
{ [](){ return shared_ptr<Base>(new A()); }, [](){ return shared_ptr<Base>(new B()); } };
(funcs->at(i)();
这 "array of functions" 类似于抽象工厂,returns 基 class 的共享指针。
我正在编写一个可以启动新进程的应用程序'。我已经确定这些流程在两个方面存在根本差异,它们可以 运行 独立运行或依赖现有流程运行。因此,我创建了两个抽象 classes,继承自基础抽象 class.
我正在尝试编写一个工厂模式或其他设计模式,根据我提供的文件扩展名字符串 return 我需要 class,这将发生在 运行时间。然而,我不认为工厂模式是一个好的、明智的选择,因为这些根本差异导致不同的构造函数。我可以自己编写一个巨大的 switch 或嵌套 if 语句,但对于这个项目,我真的想增加我的 c++ 知识(这是我第一次真正使用继承)。
说我有我的抽象基础 class :
class launchable {
protected:
std::string name;
std::string directory;
std::string path;
std::string fileType;
std::vector<std::string> launchArgs;
bool hasLaunched;
launchable(std::string _name, std::string _directory,std::string _fileType,std::vector<std::string> _args);
public:
virtual void start() = 0;
virtual void stop() = 0;
virtual void writeMessage(std::string theMessage) = 0;
virtual boost::optional<std::string> readMessage() = 0;
};
然后是两个进一步的抽象 class 继承自此,首先是一个独立的 class starts/stops 并写入其自己的进程:
class standalone : public launchable{
protected:
processManager *manager;
std::shared_ptr<processManager::launchableProcess> process;
virtual std::string formatWriteMessage(std::string theMessage) = 0;
standalone(std::string _name, std::string _directory,std::string _fileType,std::vector<std::string> _args,processManager *_manager);
public:
virtual void start() = 0;
virtual void stop() = 0;
void writeMessage(std::string theMessage);
boost::optional<std::string> readMessage();
};
和一个必须 start/stop/read/write 通过独立流程的受抚养人 class:
class dependent : public launchable{
protected:
standalone *dependency;
dependent(std::string _name, std::string _directory,std::string _type,std::vector<std::string> _args,standalone *_dependency);
public:
virtual void start() = 0;
virtual void stop() = 0;
void writeMessage(std::string theMessage);
boost::optional<std::string> readMessage();
};
在命令行上 运行 的具体独立 *nix 可执行文件示例:
class executable : public standalone {
private:
std::string formatWriteMessage(std::string theMessage);
public:
using standalone::standalone;
void start();
void stop();
};
并且示例具体可靠,超级对撞机补丁必须 运行 通过 *nix 命令行解释器:
class supercolliderPatch : public dependent {
public:
using dependent::dependent;
void start();
void stop();
};
所以理想情况下我想要的是(伪代码):
launchable *sclang = launchableFactory.create("exec",ARGS); // returns a standalone
launchable *patch = launchableFactory.create("supercolliderPatch",sclang,ARGS) // returns a dependable, with dependency set to sclang
这些可启动的*实例将存储在 std::vector.
中基本上我的问题是:我是不是在把 standalone/dependent 的这两个概念混为一谈,或者工厂模式对我有用吗?
抽象工厂让您完全做到这一点:构造一些具体实例并将其视为抽象接口。 如果您找不到一个共同的接口来同时使用两者 类,那么您可能需要重新考虑您的设计,但在您的情况下这似乎不是问题。
你可以试试这个,一些函数式编程,但它可能会对性能产生一些最小的负面影响。它还需要 C++11 或更高版本
std::function<shared_ptr<Base>()> funcs[] = { [](){ return shared_ptr<Base>(new A()); }, [](){ return shared_ptr<Base>(new B()); } };
然后调用:
funcs[i]();
为了安全起见,您可以使用类似 array
的东西。
std::array<std::function<shared_ptr<Base>()>, 2> funcs[] =
{ [](){ return shared_ptr<Base>(new A()); }, [](){ return shared_ptr<Base>(new B()); } };
(funcs->at(i)();
这 "array of functions" 类似于抽象工厂,returns 基 class 的共享指针。