如何为现有codeBase的公共API? [英] How to create a public API for an existing codebase?

查看:154
本文介绍了如何为现有codeBase的公共API?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创造,它也用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:


  1. 创建可以构建许多不同的实现,而接口的ABI没有改变。

  2. 的返回类型依赖于语言的协方差规则,因此不需要转换。

  3. 调试是比较容易的,因为你可以告诉什么样的接口您已经得到了。

  1. Create can construct many different implementations, and Interface's ABI doesn't have to change.
  2. The return types rely on the language's covariance rules, so no casts are needed.
  3. Debugging is somewhat easier, because you can tell exactly what kind of Interface you've got.

这篇关于如何为现有codeBase的公共API?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆