[英]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
函数,例如accpetXML
和acceptJSON
并在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.