为了隐藏实现细节,使 Encryption 类成为纯虚拟的,没有数据。这使主头文件保持简单并且没有实现细节。如果您想使用继承来重用代码,请使用像 BaseEncryptionImpl 这样的中间类(这将在私有/实现头文件中)。
只有实现静态工厂方法的源文件getEncryptor
必须包含加密实现。
这个工厂方法应该返回一个std::auto_ptr
与原始指针相反的异常安全的指针。备受诟病auto_ptr
的是为从函数返回指针而设计的。此外,它还减少了头文件对标准库的外部依赖,而不是 boost。您的类的用户可以使用boost::smart_prt
或boost::scoped_ptr
根据他们的需要使用,两者都有auto_ptr
构造函数。
最初我会getEncryptor
尽可能简单,可能使用if else if
等来决定你应该创建哪个。这比在单例中实现 AbstractFactory 的注册表要简单得多。大多数时候,注册表只是解决问题。你如何初始化注册表?您可以使用每个EncryptionImpl
类定义的静态对象,其构造函数注册而析构函数注销,但如果链接器决定您不需要这些对象,因此不将它们包含在可执行文件或库中,这可能会导致问题。
加密器.h
class Encryptor {
public:
virtual void encrypt(const Data & in, Data * out) = 0;
virtual ~Encryptor();
static std::auto_ptr<Encryptor> getEncryptor(const char * name);
};
加密器.cpp
#include "Encryptor.h"
#include "EncryptorA.h"
#include "EncryptorB.h"
std::auto_ptr<Encryptor> Encryptor::getEncryptor(const char * name)
{
// EncryptorA::NAME is a std::string
if (EncryptorA::NAME == name) {
return std::auto_ptr<Encryptor>(new EncryptorA);
}
else if (EncryptorB::NAME == name) {
return std::auto_ptr<Encryptor>(new EncryptorB);
}
else {
throw EncryptionNotDefined;
}
}
客户端.cpp
void foo()
{
boost::scoped_ptr enc(Encryption::getEncryption("FOO"));
Data in = ...;
Data out = ...;
enc->encrypt(in, &out);
}