为多协议支持的服务器设计客户端

时间:2012-06-20 06:37:50

标签: oop design-patterns

这是我第一次参与为外部服务器编写完整的客户端(我对设计模式非常新)。

该服务器提供几种协议来连接和发送命令,例如REST,SOAP等等。

所有这些协议都执行几乎相同的操作集,但它有所不同。我需要为它设计和实现一个完整的客户端框架,它将支持所有这些协议。

了解并通过几个互联网链接,在我看来,它使用抽象的工厂模式和接口。

我目前对实施它的想法如下:

  1. 为Connection(ConnectionFactory)创建一个抽象工厂类。根据输入,提及要使用的协议,将创建相应的Connection对象。这个抽象类将有一个抽象方法(processMessage)。必须在所有协议的连接类中实现此方法。这个单一的方法(processMessage)将采用一个提到执行请求类型的方式。每个协议都有一个单独的请求名称。如何使用常量来处理它?<​​/ p>

  2. 为请求,响应和客户端定义接口。所有协议都有自己的Request,Response和Client类,它们将实现各自的接口。

  3. 请向我提供有关此设计的宝贵意见;请建议我更好的东西,我可以在这里做。 我仍然无法完成目录结构,请帮助我。

1 个答案:

答案 0 :(得分:2)

如果您计划为不同的协议定义类层次结构,请尝试避免为数据类型(请求,响应等)创建并行层次结构。这通常被认为是反模式,并且被称为“并行继承层次结构”。这是一个例子question。这种方法的主要缺点是必须维护多个并行类层次结构。

创建连接工厂听起来很合理。它应该最有可能返回一个类实例,它具有方法createMessage(),用于将消息 发送到 服务器,而processMessage()用于从接收消息 em> 服务器和工厂将插入下面解释的ProtocolHandler。

对于请求和响应,您可以使用Strategy pattern在Connection类中定义ProtocolHandler成员,其中每个实现都是一个可以处理,解析,编组等各自协议细节的类( REST,SOAP等)。 Connection类的processMessage()和createMessage()方法将使用ProtocolHandler类层次结构。

这是c ++中的一些伪代码,我还没有编译或测试它,但我希望它能让你很好地了解我想要解释的内容。

// Your factory will create the Connection instance and fill in the
// corresponding ProtocolHandler concrete implementation instance

class Connection
{
public:
    // Depending on what else you need for the Connection,
    // the constructors may be different
    Connection() : handler_(NULL) {}
    Connection(ProtocolHandler *handler) : handler_(handler) {}

    inline void setProtocolHandler(ProtocolHandler *handler) {handler_ = handler;}
    inline ProtocolHandler *getProtocolHandler() {return handler_;}

    void processMessage(const string &msg) {
        handler_->decode(msg);
        // any extra logic here
    }

    string createMessage() {
        // any extra logic here
        return handler_->encode();
    }

    // Put the rest of your connection stuff here

private:
    ProtocolHandler *handler_;

};

// Notice that Im handling the protocol msg buffers in a std::string, this
// may or may not work for you, replace accordingly depending on your needs

class ProtocolHandler
{
public:

    // abstract methods
    // name these accordingly as handle, parse, marshal, etc
    virtual string encode() = 0;
    virtual void decode(const string &msg) = 0;

    // Other methods you may need here
};

class RestProtocolHandler : public ProtocolHandler
{
public:
    virtual string encode() { /* your rest msg encode impl here */ }
    virtual void decode(const string &msg) { /* your rest msg decode impl here */ }

    // Other methods and/or attributes you may need here
};

// More concrete ProtocolHandler implementations here