mardi 5 mai 2020

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. They both have to comunicate with each other. So I made an adapter that implements the Server interface and contains the two servers. I want whenever the ServerThatUsesXML sends something to the adapter, the adapter converts it to JSON and forward it to the ServerThatUsesJSON. And the same holds for converting JSON requests to XML requests.

The problem is that since the two servers implement the same interface, both servers has the same methods with the same signiture. So when I call accept for example on the Aapter, the Adapter won't know where did the request come from and wich way the request should go. Should I pass it to the JSON server? or should I pass it to the XML server?

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. The same holds for the requests converting from JSON to 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. And then pass the first one to the ServerThatUsesXML. And pass the second one to the 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. The code should look something like this:

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

Aucun commentaire:

Enregistrer un commentaire