简体   繁体   English

GWT客户端和服务器的不同接口实现

[英]GWT different interface implementation for client and server

Assume that we've some interface my.gwt.shared.Facade in shared package of our GWT project (exists both server and client) and two implementation of it: class my.gwt.client.ClientFacadeImpl (exists only client) and class my.gwt.server.ServerFacadeImpl (exists only server). 假设我们在GWT项目的共享包中有一些接口my.gwt.shared.Facade (同时存在服务器和客户端),并且有两个实现: 类my.gwt.client.ClientFacadeImpl (仅存在客户端)和my类.gwt.server.ServerFacadeImpl (仅存在服务器)。

Is there any way to write a piece of code or annotation that substitute ClientFacadeImpl in client side and ServerFacadeImpl in server side? 有什么方法可以编写一段代码或注释来代替客户端的ClientFacadeImpl和服务器端的ServerFacadeImpl

Thanks all for the answers and discussion. 谢谢大家的回答和讨论。 I've found simple and elegant solution for my needs. 我找到了满足我需求的简单而优雅的解决方案。

So, I've interface my.gwt.shared.Facade and two classes: class my.gwt.client.ClientFacadeImpl and class my.gwt.server.ServerFacadeImpl . 因此,我已经连接了my.gwt.shared.Facade和两个类: my.gwt.client.ClientFacadeImpl my.gwt.server.ServerFacadeImpl类

interface Facade {
    Map<Boolean, Facade> FACADES = new HashMap<Boolean, Facade>();
}

Now, we should fill you FACADES interface. 现在,我们应该为您填充FACADES界面。 This is done like that: 这样做是这样的:

public class MyEntry implements EntryPoint {
static {
    Facade.FACADES.put(true, ClientFacadeImpl.INSTANCE); // client side
}

And

@Startup
@Singleton
public class Initializer {
    @PostConstruct
    private void init() {
        Facade.FACADES.put(false, ServerFacadeImpl.INSTANCE); // server side
        // other things
    }
}

Now, when I need to get appropriate Facade, I just write 现在,当我需要获取适当的Facade时,我只需编写

 Facade facade = Facade.FACADES.get(GWT.isClient());

Also in this case in map is only corresponding to server or client side implementation. 同样在这种情况下,map中的内容仅对应于服务器或客户端实施。

PS Goal of this question was to allow handling of some GwtEvents fired on client direclty on server and vice-versa. PS此问题的目标是允许处理一些在服务器上客户端不正确时触发的GwtEvent,反之亦然。 This solution removed large set of DTO (data transfer objects) and simplified code a lot. 此解决方案删除了​​大量DTO(数据传输对象)并简化了许多代码。

There's no answer to your question other than "it depends". 除了“视情况而定”以外,没有其他答案。 Or rather, of course there are ways of doing what you ask, but would you accept the tradeoffs? 或更确切地说,当然有很多方法可以解决您的问题,但是您会接受这种折衷吗?

Given that you tagged the question with dependency-injection, let's start with that. 假设您使用依赖项注入标记了问题,让我们开始吧。 If you use a DI tool with GWT, it's likely GIN (Dagger 2 would work, but it's still under development). 如果您在GWT中使用DI工具,则可能是GIN(Dagger 2可以使用,但仍在开发中)。 In that case, just use distinct modules for GIN client-side and Guice server-side that bind() the appropriate implementation. 在这种情况下,只需对GIN客户端和Guice服务器端使用不同的模块,这些模块bind()适当地实现。

For a few releases, GWT.create() can be made to work outside a GWT (client) environment (ie on the server side). 对于GWT.create()发行版,可以使GWT.create()在GWT(客户端)环境之外(即在服务器端)工作。 You have to register a ClassInstantiator on the ServerGwtBridge as an alternative to the rebind rules from gwt;xml files. 您必须在ServerGwtBridge上注册ClassInstantiator ,以替代gwt;xml文件中的重新绑定规则。 So you could have a <replace-with class="my.gwt.client.ClientFacadeImpl"> rule in your gwt.xml , and a ClassInstantiator returning a ServerFacadeImpl on the server side. 所以,你可以有一个<replace-with class="my.gwt.client.ClientFacadeImpl">规则在您的gwt.xmlClassInstantiator返回ServerFacadeImpl在服务器端。

Finally, you can also use a static factory and replace it with a client-side specific version by way of <super-source> . 最后,您还可以使用静态工厂,并通过<super-source>将其替换为客户端特定的版本。

A last one, but I'm unsure whether it'd work: you could use an if / else using GWT.isClient() , and annotate your ServerFacadeImpl with @GwtIncompatible to tell the GWT compiler that you know it's not client-compatible. 最后一个一个,但我不确定是否会工作:你可以使用if / else使用GWT.isClient()和注释你的ServerFacadeImpl@GwtIncompatible告诉GWT编译器,你知道这不是客户端兼容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM