繁体   English   中英

如何为实现相同接口的两个类制作双向适配器?

[英]How to make bidirectional adapter for two classes that implement the same interface?

interface Server
{
    void accept(String xml);
    void send();
}

class ServerThatUsesXML implements Server
{
    Server server;

    @Override
    public void accept(String xml) {
        if (xml.equals("XML"))
            System.out.println("Data accepted successfully.");
        else
            System.out.println("There was a problem in processing the data.");
    }

    @Override
    public void send() {
        server.accept("XML");
    }
}

class ServerThatUsesJSON implements Server
{
    Server server;

    @Override
    public void accept(String json) {
        if (json.equals("JSON"))
            System.out.println("Data accepted successfully.");
        else
            System.out.println("There was a problem in processing the data.");
    }

    @Override
    public void send() {
        server.accept("JSON");
    }
}

class Converter
{
    public String convertToXML(String json)
    {
        return "XML";
    }

    public String convertToJSON(String xml)
    {
        return "JSON";
    }
}

class Adapter implements Server
{
    Server xml, json;
    Converter converter = new Converter();

    public Adapter(Server xml, Server json) {
        this.xml = xml;
        this.json = json;
    }

    @Override
    public void accept(String input) {
        // converter.convertTo...
    }

    @Override
    public void send() {
        // converter.convertTo...
    }
}

public class Main {

    public static void main(String[] args) {
        ServerThatUsesXML xml = new ServerThatUsesXML();
        ServerThatUsesJSON json = new ServerThatUsesJSON();

        xml.server = json;
        json.server = xml;

        xml.send(); // There was a problem in processing the data.
        json.send(); // There was a problem in processing the data.

        Adapter adapter = new Adapter(xml, json);
        xml.server = adapter;
        json.server = adapter;

        xml.send();
        json.send();
        // Both calls should print "Data accepted successfully.".
    }
}

在此示例中,我有两台服务器。 不幸的是,一台服务器使用XML ,另一台使用JSON 他们都必须相互交流。 所以我做了一个适配器,实现了Server接口,包含了两台服务器。 我希望每当ServerThatUsesXML向适配器发送某些内容时,适配器将其转换为JSON并将其转发给ServerThatUsesJSON JSON请求转换为XML请求也是如此。

问题在于,由于两个服务器实现了相同的接口,所以两个服务器具有相同的方法和相同的签名。 因此,当我在Adapter上调用accept时, Adapter将不知道请求来自哪里以及请求应该以哪种方式 go。 我应该将它传递给JSON服务器吗? 还是应该将其传递给XML服务器?

我有两个解决方案,但它们看起来不太干净......所以我问是否有更好的方法来解决这个问题。

第一个解决方案:检查文本的格式。 如果是XML文本,则将其转换为JSON并将其发送到ServerThatUsesJSON JSON转换为XML的请求也是如此。 这种方法可能是最糟糕的,因为它不检查发件人并且仅根据文本格式转发请求。 它还通过文本检查格式。 这不是那么有效。

Second solution: to make two adapters, one that accepts XML and sends JSON , and another one that accepts JSON and sends XML . 然后将第一个传递给ServerThatUsesXML 并将第二个传递给ServerThatUsesJSON 这个解决方案看起来比第一个更好(至少它更有效)。

我的问题是:我可以创建两个accept函数,例如accpetXMLacceptJSON并在accept function 中,根据调用者的类型,我可以调用XML版本或JSON版本。 代码应如下所示:

public void accept(String input, ....)
{
    if (senderType == ServerThatUsesXML)
        acceptJSON(converter.convertToJSON(input));
    else
        acceptXML(converter.convertToXML(input));
}

GoF 在第 143 页提到了“双向适配器”。

具体来说,当两个不同的客户端需要以不同的方式查看 object 时,它们很有用。

但是,对于Server界面,不同的客户端以完全相同的方式查看它。 只有一个接口可以适配,而不是两个,所以这是双向适配器可能不适合的线索。

GoF 中的示例显示了使用多个 inheritance 的双向 class 适配器。

在这种情况下,多个 inheritance 是一个可行的解决方案,因为适配类的接口有很大不同。 双向 class 适配器符合两个适配类,并且可以在任一系统中工作。

很明显,这告诉我们双向 class 适配器不适合Server用例。 我认为有足够的证据可以得出结论,使用相同的接口来适配两个类对于双向适配器根本不可行。 虽然 GoF 没有提到双向object适配器(使用组合而不是多重继承),但它似乎会遇到与一个 API 不同输入格式的相同问题。

顺便说一句,不同字符串格式的问题更多是字符串类型编程的影响。 它可以通过使用对象而不是原语进行编程来解决。 如果服务器反序列化他们的输入,问题就消失了。 这是一个令人惊讶的常见问题:服务器具有类型信息(因为它们知道要接受什么格式),但它们通过将序列化数据(例如字符串)传递给另一个必须处理不同格式的 object 来丢弃该信息。

Returning to the topic of the Adapter pattern, you might implement different (one-way) adapters: one specifically for the XML server that converts to JSON and another specifically for the JSON server that converts to XML. 该解决方案类似于将Converter传递到每个Server并使 String 格式成为Server的问题的注释,这与避免传播 Strings 的反序列化解决方案本质上是相同的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM