2

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

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

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

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

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

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

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

请提供您对此设计的宝贵意见;请给我一些更好的建议,我可以在这里做。我仍然无法最终确定目录结构,请帮助我。

4

1 回答 1

2

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

创建 Connection 工厂听起来很合理。它很可能会返回一个类实例,该实例具有用于向服务器发送消息的 createMessage() 方法和用于服务器接收消息的 processMessage() 方法,并且工厂将插入接下来解释的 ProtocolHandler。

至于请求和响应,您可以使用策略模式在 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
于 2012-06-20T06:50:13.347 回答