簡體   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