如何为现有codeBase的公共API? [英] How to create a public API for an existing codebase?
问题描述
我试图创造,它也用C ++编写的私人code碱基公共C ++ API。我试图做到这一点如下:
I'm trying to create a public C++ API for a private code base that is also written in C++. I tried to do this as follows:
- 每个私有类创建一个封装API类。
- 有一个具有一个指向私有类的通用API的基类。
- 的API类的实现不包含任何功能,但只是转发方法调用他们的私人同行。
这似乎是一个合理的做法。然而,在现实很快导致非常笨拙code。下面是再次presents一个例子,我遇到的问题。
This seemed like a reasonable approach. However, in reality it quickly results in very clumsy code. Here is an example that represents the problem I'm experiencing.
(编辑:code也可以看作<一href=\"http://$c$c.google.com/p/stacked-crooked/source/browse/#svn/trunk/PlayGroundCpp/WrapAPI/ProblematicVersion\"相对=nofollow>这里)。
( the code can also be viewed here).
结果
的私有API类(这里没问题)
namespace Core {
// Base class for all Core classes.
class CoreObject
{
public:
virtual ~CoreObject();
};
class Interface;
class Stream;
class Server : public CoreObject
{
public:
Interface * createInterface();
private:
std::vector<Interface*> mInterfaces;
};
class Interface : public CoreObject
{
public:
void addStream(Stream * stream);
const Stream * getStreamByIndex(std::size_t index) const;
std::size_t streamCount() const;
private:
std::vector<Stream*> mStreams;
};
class Stream : public CoreObject
{
public:
void start();
void stop();
private:
std::string mStats;
};
} // Core
结果
公共API类声明(到目前为止好)
namespace Core {
class CoreObject;
}
namespace API {
class APIStream;
class APIInterface;
// Base class for all API classes.
class APIObject
{
public:
APIObject(Core::CoreObject * inCoreObject);
virtual ~APIObject();
Core::CoreObject * getCoreObject();
const Core::CoreObject * getCoreObject() const;
void setCoreObject(Core::CoreObject * inCoreObject);
private:
Core::CoreObject * mCoreObject;
};
class APIServer : public APIObject
{
public:
APIServer();
APIInterface * createInterface();
};
class APIInterface : public APIObject
{
public:
APIInterface();
void addStream(APIStream * stream);
const APIStream * getStreamByIndex(std::size_t index) const;
APIStream * getStreamByIndex(std::size_t index);
std::size_t streamCount() const;
};
class APIStream : public APIObject
{
public:
APIStream();
void start();
void stop();
};
结果
的API实现(太多的演员,通常很笨拙)
#include "API.h"
#include "Core.h"
namespace API {
APIObject::APIObject(Core::CoreObject * inCoreObject) :
mCoreObject(inCoreObject)
{
}
APIObject::~APIObject()
{
}
Core::CoreObject * APIObject::getCoreObject()
{
return mCoreObject;
}
const Core::CoreObject * APIObject::getCoreObject() const
{
return mCoreObject;
}
void APIObject::setCoreObject(Core::CoreObject * inCoreObject)
{
mCoreObject = inCoreObject;
}
//
// APIServer
//
APIServer::APIServer() :
APIObject(new Core::Server)
{
}
APIInterface * APIServer::createInterface()
{
Core::Server * coreServer = static_cast<Core::Server*>(getCoreObject());
Core::Interface * coreInterface = coreServer->createInterface();
APIInterface * result(new API::APIInterface);
result->setCoreObject(coreInterface);
return result;
}
//
// APIInterface
//
APIInterface::APIInterface() :
APIObject(new Core::Interface)
{
}
void APIInterface::addStream(APIStream * apiStream)
{
Core::Stream * coreStream = static_cast<Core::Stream *>(apiStream->getCoreObject());
Core::Interface * coreInterface = static_cast<Core::Interface*>(getCoreObject());
coreInterface->addStream(coreStream);
}
//
// APIStream
//
const APIStream * APIInterface::getStreamByIndex(std::size_t index) const
{
const Core::Interface * coreInterface = static_cast<const Core::Interface*>(getCoreObject());
const Core::Stream * coreStream = coreInterface->getStreamByIndex(index);
// Now how I get the the APIStream object?
return 0;
}
std::size_t APIInterface::streamCount() const
{
const Core::Interface * coreInterface = static_cast<const Core::Interface*>(getCoreObject());
return coreInterface->streamCount();
}
APIStream::APIStream() :
APIObject(new Core::Stream)
{
}
void APIStream::start()
{
static_cast<Core::Stream*>(getCoreObject())->start();
}
void APIStream::stop()
{
static_cast<Core::Stream*>(getCoreObject())->stop();
}
} // API
结果
正如你所看到的实施长相看起来并不太好。我想AP preciate你的答案或者见解就这些问题:
As you can see the implementation looks doesn't look too good. I would appreciate your answers or insights regarding these questions:
- 我有什么错?
- 我应该怎么做了呢?
结果
更新
约翰Dibling的建议似乎工作的真正的好。正如你可以在<一见href=\"http://$c$c.google.com/p/stacked-crooked/source/browse/#svn%2Ftrunk%2FPlayGroundCpp%2FWrapAPI%2FImprovedVersion\"相对=nofollow>提高code ,一切问题都解决了整齐
Update
John Dibling's suggestion seems to work really well. As you can see in the improved code, all problems are solved neatly.我还有明天在工作中应用该解决方案的真正code。我很感兴趣,看看它是如何以及在那里工作。
I still have to apply this solution to the real code at work tomorrow. I'm interested to see how well it works there.
推荐答案
在做这种事情,哪里有或多或少的API和实现对象之间的一到一个关系,我一般使用静态工厂方法,并有实现类从API类派生。像这样的:
When doing this kind of thing, where there is more or less a one-to-one relation between the API and implementation objects, I'll generally use a static factory method, and have the implementation class derive from the API class. Like this:
class Interface
{
public:
static Interface* Create();
virtual void Foo() = 0;
};
文件:impl.h
class Concrete : public Interface
{
public:
void Foo() {};
};
文件:impl.cpp
Interface* Interface::Create()
{
return new Concrete;
}
这具有许多优点。包括:
This has a number of benefits. Including:
-
创建
可以构建许多不同的实现,而接口
的ABI没有改变。 - 的返回类型依赖于语言的协方差规则,因此不需要转换。
- 调试是比较容易的,因为你可以告诉什么样的
接口
您已经得到了。
Create
can construct many different implementations, andInterface
's ABI doesn't have to change.- The return types rely on the language's covariance rules, so no casts are needed.
- Debugging is somewhat easier, because you can tell exactly what kind of
Interface
you've got.
这篇关于如何为现有codeBase的公共API?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!