在 java 中以不同方式使用单一接口来建模系统的最佳方法

发布于 2024-11-06 21:12:48 字数 399 浏览 0 评论 0原文

我有一个在 TopLevel 内部实现接口的类,

class TopLevel implements TopLevelOperations

操作以两种不同的方式实现。因此,TopLevelOperations 中的某些操作需要作为 SOAP 客户端调用进行调用,而另一些操作则需要作为 Restful 调用进行调用。

对此进行建模的最佳方法是什么?创建另外两个接口 SOAPOperations 和 RESTOperations 来分别指定 Restful 和 SOAP 的职责是什么?然后在内部使用另外两个类来实现这些接口?动机是我可能有一天想用其他方法替换 SOAP。

更好的方法吗?

编辑:我也不希望不同的客户端代码像现在一样在 TopLevel 中混杂在一起。

I have a class that implements an interface

class TopLevel implements TopLevelOperations

inside TopLevel the operations are implemented in 2 different ways. So some of the operations in TopLevelOperations need to be called as SOAP client calls and some as restful calls.

What would be the best way to model this? Create additional two interfaces SOAPOperations and RESTOperations to specify what is the responsibility of restful and SOAP respectively ? Then use two other classes internally that implement those interfaces? The motivation is that I may one day want to swap out SOAP for some other approach.

Better way?

Edit: I also don't want different client code jumbled together in TopLevel as it currently is.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

酸甜透明夹心 2024-11-13 21:12:48

您需要做的是将传输层与有效负载分开。
网络上的两个请求均通过 HTTP,但有效负载不同,即,在一种情况下,它被包装在 SOAP 信封中,而在 REST 中,它被包装在纯 xml 数据中。
因此,对于更高级别的代码,您应该有一个仅发送消息的接口,封装在一个对象中。
该接口的实现将消息转换为 XML(通过 DOM 或 JAXB 等)。
然后,此 XML 被传递到传输层,通过 HTTP 发送,将其封装在 SOAP 消息中,然后再传递到传输层。
传输层可以只是一个具体的类,简单如下:

public class HttpClient{

      public String sendMsg(String xml){
       //Use some HTTP client to send message and return the response.
      //The input could be SOAP or plain xml app data
      //The output could be SOAP or plain xml app data
      }
    }

因此用户可以将对象配置为使用 SOAP 或不使用。
应用程序代码只知道发送消息的接口。
在您的实现中,由于 XML 转换和 HTTP 传输层是分离的,您可以交换实现或添加新的实现。

What you need to do is separate the transport layer from the payload.
Both requests over the network are over HTTP but the payload is different, i.e. it is wrapped in a SOAP envelope in one case and pure xml data in REST.
So for the higher lever code you should have an interface that just sends a message, encapsulated in an object.
The implementation of this interface converts the message to XML (via DOM or JAXB etc).
Then this XML is passed to a transport layer to be send over HTTP or wrapped in a SOAP message before passing it to the transport layer.
The transport layer can be just a concrete class that is as simple as:

public class HttpClient{

      public String sendMsg(String xml){
       //Use some HTTP client to send message and return the response.
      //The input could be SOAP or plain xml app data
      //The output could be SOAP or plain xml app data
      }
    }

So the user configures your objects to use SOAP or not.
The application code is only aware of the interface to send message.
In your implementation, because of the separation of XML transformation and HTTP transport layers you can swap implementations or add new ones.

荒路情人 2024-11-13 21:12:48

不确定解决方案是否需要那么复杂(假设我当然理解问题......):

  1. 确保 TopLevelOperations 声明客户端可以使用的所有方法。以独立于协议的方式执行此操作,例如 TopLevelOperations.doFoo(),而不是 TopLevelOperations.doFooOverSOAP()
  2. TopLevel 实现为您的第一个版本适当使用 SOAP/REST 的接口。
  3. 确保客户端在声明引用时仅引用 TopLevelOperations - 切勿引用实现类
  4. 使用适合您的应用程序的任何机制将适当的实现注入客户端(依赖注入/工厂/...)。

如果/当您想使用不同的传输/协议重新实现方法时,只需创建另一个实现 TopLevelOperations 的类 (TopLevelNew)。然后将其注入客户端,而不是上面步骤 4 中的 TopLevel

决定使用哪种实现是应用程序级别的配置决策,而不是客户端必须知道的事情。

嗯。

[您可能还希望/需要使用一些辅助类来实现,例如根据@user384706的答案将内容与有效负载分开。但这是对上面的补充(即如何设计实现与如何为客户端保持接口一致)。]

Not sure the solution needs to be that complex (assuming I understand the problem of course...):

  1. Make sure TopLevelOperations declares all the methods a client can use. Do so in a protocol-independent way, e.g. TopLevelOperations.doFoo(), not TopLevelOperations.doFooOverSOAP()
  2. Implement TopLevel as your first version of the interface using SOAP/REST as appropriate.
  3. Ensure clients only ever reference TopLevelOperations when declaring references - never the implementing class
  4. Use whatever mechanism is appropriate for your app to inject the appropriate implementation into the clients (Dependency Injection / Factory / ...).

If / when you want to re-implement the methods using a different transport/protocol just create another class (TopLevelNew) that implements TopLevelOperations. Then inject it into clients instead of TopLevel in step 4 above.

Deciding which implementation to use is then an application-level configuration decision, not something the clients have to be aware of.

hth.

[You may also want/need to use some helpers classes for the implementation, e.g. separating content from payload as per @user384706's answer. But that's complementary to above (i.e. how to design the implementation vs. how to keep interface consistent for clients).]

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文