在 java 中以不同方式使用单一接口来建模系统的最佳方法
我有一个在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您需要做的是将传输层与有效负载分开。
网络上的两个请求均通过 HTTP,但有效负载不同,即,在一种情况下,它被包装在 SOAP 信封中,而在 REST 中,它被包装在纯 xml 数据中。
因此,对于更高级别的代码,您应该有一个仅发送消息的接口,封装在一个对象中。
该接口的实现将消息转换为 XML(通过 DOM 或 JAXB 等)。
然后,此 XML 被传递到传输层,通过 HTTP 发送或,将其封装在 SOAP 消息中,然后再传递到传输层。
传输层可以只是一个具体的类,简单如下:
因此用户可以将对象配置为使用 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:
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.
不确定解决方案是否需要那么复杂(假设我当然理解问题......):
TopLevelOperations
声明客户端可以使用的所有方法。以独立于协议的方式执行此操作,例如TopLevelOperations.doFoo()
,而不是TopLevelOperations.doFooOverSOAP()
TopLevel
实现为您的第一个版本适当使用 SOAP/REST 的接口。如果/当您想使用不同的传输/协议重新实现方法时,只需创建另一个实现
TopLevelOperations
的类 (TopLevelNew
)。然后将其注入客户端,而不是上面步骤 4 中的TopLevel
。决定使用哪种实现是应用程序级别的配置决策,而不是客户端必须知道的事情。
嗯。
[您可能还希望/需要使用一些辅助类来实现,例如根据@user384706的答案将内容与有效负载分开。但这是对上面的补充(即如何设计实现与如何为客户端保持接口一致)。]
Not sure the solution needs to be that complex (assuming I understand the problem of course...):
TopLevelOperations
declares all the methods a client can use. Do so in a protocol-independent way, e.g.TopLevelOperations.doFoo()
, notTopLevelOperations.doFooOverSOAP()
TopLevel
as your first version of the interface using SOAP/REST as appropriate.TopLevelOperations
when declaring references - never the implementing classIf / when you want to re-implement the methods using a different transport/protocol just create another class (
TopLevelNew
) that implementsTopLevelOperations
. Then inject it into clients instead ofTopLevel
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).]