简体   繁体   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.".
    }
}

In this example, I have two servers.在此示例中,我有两台服务器。 Unfortunately, one server uses XML , and the other uses JSON .不幸的是,一台服务器使用XML ,另一台使用JSON They both have to communicate with each other.他们都必须相互交流。 So I made an adapter that implements the Server interface and contains the two servers.所以我做了一个适配器,实现了Server接口,包含了两台服务器。 I want whenever the ServerThatUsesXML sends something to the adapter, the adapter converts it to JSON and forward it to the ServerThatUsesJSON .我希望每当ServerThatUsesXML向适配器发送某些内容时,适配器将其转换为JSON并将其转发给ServerThatUsesJSON And the same holds for converting JSON requests to XML requests.JSON请求转换为XML请求也是如此。

The problem is that since the two servers implement the same interface, both servers has the same methods with the same signature.问题在于,由于两个服务器实现了相同的接口,所以两个服务器具有相同的方法和相同的签名。 So when I call accept for example on the Adapter , the Adapter won't know where did the request come from and which way the request should go.因此,当我在Adapter上调用accept时, Adapter将不知道请求来自哪里以及请求应该以哪种方式 go。 Should I pass it to the JSON server?我应该将它传递给JSON服务器吗? or should I pass it to the XML server?还是应该将其传递给XML服务器?

I have two solutions but they don't look so clean... So I'm asking whether there is a better approach to solve this problem.我有两个解决方案,但它们看起来不太干净......所以我问是否有更好的方法来解决这个问题。

First solution: to check the format of the text.第一个解决方案:检查文本的格式。 If it's an XML text, convert it to JSON and send it to the ServerThatUsesJSON .如果是XML文本,则将其转换为JSON并将其发送到ServerThatUsesJSON The same holds for the requests converting from JSON to XML .JSON转换为XML的请求也是如此。 This approach is probably the worst, since it doesn't check the sender and forwards the requests only based on the format of the text.这种方法可能是最糟糕的,因为它不检查发件人并且仅根据文本格式转发请求。 Also it goes through the text to check the format.它还通过文本检查格式。 This is not so efficient.这不是那么有效。

Second solution: to make two adapters, one that accepts XML and sends JSON , and another one that accepts JSON and sends XML . Second solution: to make two adapters, one that accepts XML and sends JSON , and another one that accepts JSON and sends XML . And then pass the first one to the ServerThatUsesXML .然后将第一个传递给ServerThatUsesXML And pass the second one to the ServerThatUsesJSON .并将第二个传递给ServerThatUsesJSON This solution looks better that the first one (at least it's more efficient).这个解决方案看起来比第一个更好(至少它更有效)。

My question is: can I make two accept functions for example accpetXML and acceptJSON and in the accept function, depending on the type of the caller, I either call the XML version or the JSON version.我的问题是:我可以创建两个accept函数,例如accpetXMLacceptJSON并在accept function 中,根据调用者的类型,我可以调用XML版本或JSON版本。 The code should look something like this:代码应如下所示:

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

The GoF mentions "two-way adapters" on page 143. GoF 在第 143 页提到了“双向适配器”。

Specifically, they're useful when two different clients need to view an object differently.具体来说,当两个不同的客户端需要以不同的方式查看 object 时,它们很有用。

With the Server interface, however, different clients view it in exactly the same way.但是,对于Server界面,不同的客户端以完全相同的方式查看它。 There is only one interface to adapt rather than two, so this is a clue that a two-way adapter may not be suitable.只有一个接口可以适配,而不是两个,所以这是双向适配器可能不适合的线索。

The example from the GoF shows a two-way class adapter using multiple inheritance. GoF 中的示例显示了使用多个 inheritance 的双向 class 适配器。

Multiple inheritance is a viable solution in this case because the interfaces of the adapted classes are substantially different.在这种情况下,多个 inheritance 是一个可行的解决方案,因为适配类的接口有很大不同。 The two-way class adapter conforms to both of the adapted classes and can work in either system.双向 class 适配器符合两个适配类,并且可以在任一系统中工作。

Clearly this tells us that a two-way class adapter is not suitable to the Server use case.很明显,这告诉我们双向 class 适配器不适合Server用例。 I think it may be sufficient evidence to conclude that adapting two classes with the same interface is not a viable use for two-way adapters at all.我认为有足够的证据可以得出结论,使用相同的接口来适配两个类对于双向适配器根本不可行。 While the GoF does not mention a two-way object adapter (using composition rather than multiple inheritance) it would seem to encounter the same problem of different input formats to one API.虽然 GoF 没有提到双向object适配器(使用组合而不是多重继承),但它似乎会遇到与一个 API 不同输入格式的相同问题。

Incidentally, the problem with different String formats is more an effect of Stringly Typed programming.顺便说一句,不同字符串格式的问题更多是字符串类型编程的影响。 It can be solved by programming with objects instead of primitives.它可以通过使用对象而不是原语进行编程来解决。 If the servers would deserialize their inputs, the problem vanishes.如果服务器反序列化他们的输入,问题就消失了。 This is a surprisingly common problem: servers have type information (because they know what format to accept) but they throw that information away by passing serialized data (such as a String) to another object that has to deal with different formats.这是一个令人惊讶的常见问题:服务器具有类型信息(因为它们知道要接受什么格式),但它们通过将序列化数据(例如字符串)传递给另一个必须处理不同格式的 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. 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. This solution is similar to the comments of passing the Converter into each Server and making the String format the Server s' problem, which is essentially the same deserialization solution that avoids propagating Strings.该解决方案类似于将Converter传递到每个Server并使 String 格式成为Server的问题的注释,这与避免传播 Strings 的反序列化解决方案本质上是相同的。

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

相关问题 如何分离实现相同接口的两个类的函数模拟? - How to separate function mocks of two classes that implement the same interface? 如何创建两个具有相同名称,签名和返回类型的方法的类,就像它们实现相同的接口一样 - How to make two classes which both have method with the same name, signature and return type behave like they would implement the same interface 在Java中,如何区分实现相同接口的类? - In Java, how to distinguish classes that implement the same interface? 如何使用迭代器为两个类实现接口 - How to implement an interface for two classes with an iterator 如何知道两个类是否实现一个公共接口? - How to know if two classes implement a common interface? 如何注入实现同一接口的两个不同类的两个实例? - How to inject two instances of two different classes which implement the same interface? 如何给两个不同的类相同的接口? - How to give two different classes the same interface? 如何在仅使用批注实现相同接口的不同类中使用@autowired - How to use @autowired in different classes that implement the same interface with only annotations 如何实例化(在方法内部)实现同一接口的不同类? - How to instantiate (inside a method) different classes that implement the same interface? 实现相同接口的多个类的方法相同 - Same method for multiple classes that implement the same interface
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM