GWT+Java:全局变量、单例和令人头疼的问题

发布于 2024-09-16 00:04:50 字数 1151 浏览 1 评论 0原文

这是我的项目:

我正在构建一个中央界面/仪表板来呈现多个产品版本的多种测试类型的测试数据。我们在我们的大型产品上使用 TestNG,虽然没有编写足够的测试,但这是另一个主题的讨论。目录结构如下所示:

Filesystem/productVersion+testType/uniqueDateAndBuildID/testng-results.xml

该 results.xml 文件包含带有子测试标签的标签,这些标签对应于文件系统目录,然后是包含实际测试用例结果的 xml 文件(通过、失败等) XML 解析和文件系统遍历都很好且可靠。

控制流程: 客户端访问主页-->服务器打开属性文件 -->服务器检查 Web 服务器属性(Websphere 或 Tomcat,如果我在本地工作) -->服务器基于此设置一堆常量。常量包括:根文件系统目录、文件系统分隔符(翻译)、“类似类型(在不同平台上基本相同的测试)”以及要附加到的基本 URL。 -->然后,服务器会进一步读取属性文件并完成所有 XML 处理。结果使用 ObjectOutputStream 缓存在内存中以及文件系统中。 -->大量结果列表被发送回客户端以进行 UI 处理/显示。

这就是我遇到问题的地方:我无法在客户端上访问那些全局变量(包含/设置在 Globals 类中...我知道很糟糕:-/ ),即使它们位于共享文件夹中。如果您想知道为什么我不能再次加载属性,那是因为客户端是 GWT 化的 Javascript,不包含 File()。因此,我的下一个想法是,在阅读了一些上层 Java 知识后,也许可以使用 Globals 单例对象并将其传回……但这似乎即使不是不可能,也同样糟糕。 这里的建议会很棒。

这整个事情是非常紧密耦合的,这是我之前的 Java 教育还没有真正理解的。由于这只是开发人员检查的内部门户,因此实际测试我的代码似乎没有多大意义。只要它正确显示、正确记录并优雅地处理错误,对吧?总而言之,它的课程数小于 15,所以我想这并不是什么大不了的事。我应该重构以清理所有内容并使其“更好的 Java”,注释所有内容以清楚地描述控制流,还是因为它很小而不要太担心?我知道将来在设计之前要多考虑一些事情,但我真的不知道从一开始就接触过的大量更高的 Java 原则。

编辑经过一番思考后,想出了一个可能的解决方法。我不是只传回结果列表,而是传回一些包含全局“标头”对象的其他自定义列表实现,怎么样?我可以保留状态。

So here's my project:

I am building a central interface/dashboard to present the test data for several test types of multiple product versions. We're using TestNG on our massive product, and while not enough tests are being written, that's a discussion for another topic. Here's what the directory structure looks like:

Filesystem/productVersion+testType/uniqueDateAndBuildID/testng-results.xml

That results.xml file contains tags with child test tags, which correspond to a filesystem directory and then xml files containing actual test case results (pass, fail, etc)
The XML parsing and filesystem traversal is all well and good/reliable.

Flow of control:
Client accesses main page --> server opens properties file --> server checks for web server property (either Websphere or Tomcat, if I'm working locally) --> server sets bunch of constants based on that. Constants include: root filesystem directory, filesystem separator (translation), "like types (basically same tests on different platforms)", and a base URL to append onto. --> server then reads properties file some more and does all of its XML processing. Results are cached in memory as well as to the filesystem using ObjectOutputStream. --> A big list of results is sent back to the client to do the UI processing/display.

Here's where I run into a problem: I can't access those Global variables (contained/set in a Globals class...bad I know :-/ ) back on the client, even though they're in the shared folder. If you're wondering why I can't just load the properties again, it's because the client is GWT-ified Javascript which doesn't include File(). So my next thought, having done a little bit of upper level Java reading was to maybe use a Globals singleton object and pass that back too..but it seems like that's just as bad if not impossible. Suggestions here would be great.

This whole thing is pretty tightly coupled, something my previous Java education hadn't really gotten into yet. And since this is just an internal portal for devs to check, there doesn't seem to be much of a point in actually testing my code. As long as it displays correctly, logs properly, and handles errors gracefully, right? All in all it's <15 classes, so it's not really a big big deal I guess. Should I refactor to clean it all up and make it "better Java", comment everything to clearly delineate flow of control, or not worry too much about it because it's small? I know in the future to think more about things before I design them, but I really didn't know a large amount of the higher Java principles I've been exposed to since starting.

edit after doing a bit of thinking, came up with a possible workaround. What about, instead of passing back only a list of results, I passed back some other custom list implementation that included a globals 'header' object? I could preserve state.

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

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

发布评论

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

评论(3

心作怪 2024-09-23 00:04:50

一个简单的解决方案是 字典类:

提供动态字符串查找
中定义的键/值字符串对
模块的主机 HTML 页面。每一个都独一无二
Dictionary 的实例绑定到
驻留的命名 JavaScript 对象
在主机的全局命名空间中
页面的窗口对象。界限
JavaScript 对象直接用作
关联数组。

您只需要向您的主机 HTML 页面添加一些动态内容 - 让服务器以 JavaScript 对象的形式打印从属性文件中读取的值:

var GlobalProperties = {
  property1: "value1",
  property2: "value2"
};

然后,在代码中使用 Dictionary 来读取这些值:

Dictionary globalProperties = Dictionary.getDictionary("GlobalProperties");
String property1 = globalProperties.get("property1");

PS:如果您是寻找关于如何减少代码耦合的好主意/建议 ->更具可测试性,我推荐 Misko Hevery 的博客。他有很多有趣的帖子,比如为什么单身人士通常不好 (全局状态,而不是模式本身)。但最重要的是 - 它有很棒的编写可测试代码的指南(内部使用的一些指南在谷歌)。

A simple solution would be the Dictionary class:

Provides dynamic string lookup of
key/value string pairs defined in a
module's host HTML page. Each unique
instance of Dictionary is bound to a
named JavaScript object that resides
in the global namespace of the host
page's window object. The bound
JavaScript object is used directly as
an associative array.

You just need to add some dynamic content to your host HTML page - make the server print the values read from the properties file in the form of a JavaScript object:

var GlobalProperties = {
  property1: "value1",
  property2: "value2"
};

Then, use Dictionary in your code to read those values:

Dictionary globalProperties = Dictionary.getDictionary("GlobalProperties");
String property1 = globalProperties.get("property1");

PS: If you are looking for good ideas/advices on how to make your code less coupled -> more testable, I'd recommend Misko Hevery's blog. He's got many interesting posts, like why singletons are usually bad (global state, not the pattern itself). But most importantly - it has the awesome guide to writing testable code (some guidelines used internally in Google).

爱殇璃 2024-09-23 00:04:50

您可以使用带有 HashMap 的简单对象(认为是 GWT-RPC 调用)来传递这些全局变量,或者只是将此 Hashmap 包含在您首先检索到的结果中(沿着“发送回的大结果列表”)客户端进行 UI 处理/显示。”)

You could pass those Global variables using a simple object with a HashMap thought a GWT-RPC call or just include this Hashmap with the result you already retrieve in the first place (along the "big list of results [that] is sent back to the client to do the UI processing/display.")

诗笺 2024-09-23 00:04:50

您无法从已编译的 javascript 访问服务器端单例。

基本上你有两个选择。您可以在客户端代码中创建一个可序列化的类来表示全局变量,或者传递全局变量对象,但这是一个相当低效的解决方案。

最简单的方法是在可序列化对象中使用 HashMap,您可以通过 RPC 调用来检索该对象:

public class GwtGlobalVariables implements Serializable {
    private HashMap<String, String> map = new HashMap<String, String>();

    public void put(// a  delegate put method of choice

    public void setMap() // a getter / setter for the map if you need it
}

确保该类位于 GWT 模块的源文件夹中,即与也许是你的切入点。

用所需的值填写映射,通过 rpc 传递它,然后将其包含在客户端代码中。

You can't access serverside singletons from the compiled javascript.

You have two options basically. You can make a Serializable class in the client code, that represents the global variables, or pass your global variables object, but this is a rather inefficient solution.

The simplest is to use a HashMap<String, String> in a serializable object, which you can retrieve with an RPC call:

public class GwtGlobalVariables implements Serializable {
    private HashMap<String, String> map = new HashMap<String, String>();

    public void put(// a  delegate put method of choice

    public void setMap() // a getter / setter for the map if you need it
}

Ensure the class is within a GWT module's source folders, i.e. in the same place as your entry point maybe.

Fill the map out with the values needed, pass it through rpc and you have it in your client side code.

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