我想要创建一个工厂,用于创建实现抽象接口的对象,这将返回对内部保存的对象的引用,并且对象不会被复制。这个想法与log4cxx/log4jLogger类设计中的基本相同。我还希望尽可能多地向客户端隐藏详细信息,即查看公开的.h文件不会显示私有成员等实现细节。例如:
EncryptorRef = Encryptor::getEncryptor("AES");
我不知道是否有公认的已发布的准则/示例代码来进行这种设计,因为我不想重新发明轮子,而且这个任务是相当常见的。我想使用静态工厂方法、Singleton存储库以及对具体对象的智能指针/引用作为返回类型。问题:
Encryptor
类?是否有用于智能参考的标准实现?非常感谢!
发布于 2009-11-26 11:36:31
只有当客户端不再需要对对象的引用(例如释放一些锁或其他资源,或者减少一些引用计数)时,才可以使用智能指针作为返回值。如果没有必要这样做,我建议返回一个简单的参考。这样,客户就知道他不必管理对象的生命周期或诸如此类的东西。智能引用的标准实现是Boost.SmartPtr。至于隐藏实现,只需将要公开的接口放到纯抽象基类中,让客户端通过工厂获取实例。然后,他所需要的就是带有抽象基类的头、带有工厂声明的头以及要链接到的二进制文件。
发布于 2009-11-26 11:22:37
为了隐藏实现细节,我建议使用pImpl成语。
发布于 2009-11-26 18:52:00
若要隐藏实现细节,加密类是纯虚拟的,没有数据。这使得主头文件保持简单,并且没有实现细节。如果您想使用继承进行代码重用,那么使用类似于BaseEncryptionImpl的中间类(这将在私有/实现头文件中)。
只有实现静态工厂方法getEncryptor
的源文件必须包括加密实现。
这个工厂方法应该返回一个std::auto_ptr
,而不是一个原始指针,这样才能保证异常安全。备受诟病的auto_ptr
是为从函数返回指针而设计的。此外,它还将头的外部依赖降低到标准库,而不是boost。类的用户可以根据自己的需要使用boost::smart_prt
或boost::scoped_ptr
,两者都有auto_ptr
构造函数。
最初,我会尽可能地保持getEncryptor
的简单性,可能会使用if else if
等来决定您应该创建哪个。这比在单例中实现AbstractFactory注册中心要简单得多。大多数情况下,注册表只是在移动问题。如何初始化注册表?您可以使用每个EncryptionImpl
类定义的静态对象,其构造函数注册和析构函数取消寄存器,但如果链接器决定不需要这些对象,因此不将它们包含在可执行文件或库中,则可能会导致问题。
Encryptor.h
class Encryptor {
public:
virtual void encrypt(const Data & in, Data * out) = 0;
virtual ~Encryptor();
static std::auto_ptr<Encryptor> getEncryptor(const char * name);
};
Encryptor.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;
}
}
Client.cpp
void foo()
{
boost::scoped_ptr enc(Encryption::getEncryption("FOO"));
Data in = ...;
Data out = ...;
enc->encrypt(in, &out);
}
https://stackoverflow.com/questions/1803107
复制相似问题