最近我一直在编写与此类似的代码:
messagehandler.h:
#include "message.h"
class MessageHandler {
public:
virtual ~MessageHandler() {}
virtual void HandleMessage(Message *msg) = 0:
};
persistmessagehandler.h:
MessageHandler *CreatePersistMessageHandler();
persistmessagehandler.cpp:
#include "messagehandler.h"
#include "persist.h"
class PersistMessageHandler : public MessageHandler {
private:
PersistHandle ph;
size_t count;
InternalCheck();
public:
PersistMessageHandler(int someParam);
virtual ~PersistMessageHandler ();
virtual void HandleMessage(Message *msg):
};
PersistMessageHandler::PersistMessageHandler(int someParam)
{
ph.Initialize();
}
... rest of implementation.
MessageHandler *CreatePersistMessageHandler(int someParam)
{
return new PersistMessageHandler(someParam);
}
这里的原因是隐藏PersistMessageHandler。客户端不需要包含PersistMessageHandler类的头,包含实现可能需要的所有包含和类型,以及更清晰地分离接口和实现。 。它总是会动态分配,
所有PersistMessageHandler用户只需调用CreatePersistMessageHandler(..);直接或间接从工厂获得一个。
但是。我没有看到这种方法在其他地方使用得太多。以上是好的做法吗?对于简单的案例,还有其他/更好的选择吗?
答案 0 :(得分:6)
你总是要尽可能地隐藏起来。你的方式(将实现类放入.cpp)是在c ++中执行此操作的常用方法。
答案 1 :(得分:2)
这是隐藏客户端实施细节的好方法。如果您在Windows中工作,您可能还会考虑使用__interface而不是抽象基类。
接口是一个MSVC编译器扩展,看起来像一个抽象基类,但与普通的c ++类相比,它具有不同的创建和销毁规则。它是Windows中的标准工作方式,因此有一些系统支持的工具可用于处理进程外对象以及在.NET代码中使用它们。
答案 2 :(得分:1)
当然 - 它看起来像a form of the factory pattern。工厂的用户对其内部细节不感兴趣,他们只关心它所创造的东西。
答案 3 :(得分:1)
隐藏实现细节的过程称为Encapsulation。 最小化用户构建依赖关系的过程称为Insulation。约翰·拉科斯(John Lakos)写了一本关于这两个主题的伟大(但时效)的书:
http://www.amazon.com/Large-Scale-Software-Design-John-Lakos/dp/0201633620
答案 4 :(得分:0)
最大限度地减少对实现细节的依赖确实很好,隐藏抽象基类(ABC,又称接口)之外的东西是一个很好的惯用解决方案。
使用ABC的缺点是你失去了你班级的价值语义,这可能是或不可接受/可取的。
一种隐藏实现细节而没有这个缺点的技术是Pimpl。猜猜你应该知道。
在大多数情况下,我更喜欢ABC。