我正在设计一个Java桌面应用程序,它有一个标签式界面(如浏览器中的标签页)。
MainWindow
类创建选项卡式窗口,加载其他具有每个选项卡代码的SWT类,例如Tab1Composite
,Tab2Composite
。还有一些类处理工具栏菜单的操作,因此依赖MainWindow
进行本地化(捆绑),在标签之间切换等等。
到目前为止,我一直在构造函数中将MainWindow
实例传递给其他类。这似乎是“良好实践”,但我不禁注意到,如果我将所有必要的变量和方法静态化,我的代码会变得多么简单。
关于我应该使用哪种方法的想法?
答案 0 :(得分:4)
“良好实践”是指编写可以理解,重用和扩展的代码。有时快速和肮脏更有意义,但代码通常比我们预期的更长,更难,并且即使它不这样做也是正确的做法。
您的主窗口是一个很好的概念。它是许多地方所需的一组数据。将其传递到“通过9个中间层”的必要性看起来很尴尬,但它明确表示这些9层方法的每个,被认为是一个有凝聚力的整体,确实需要 MainWindow中的信息。使用全局变量可以隐藏这种需求,并且是任何试图维护或增强代码的人都会玩的一种恶作剧。
但是,MainWindow还会创建窗口和标签页。这个不需要传递,所以我创建了另一个用来传递信息的类。这简化了事情。我们未来的维护人员(可能是您)正在查看从第4层到第5层的呼叫,不再需要解决为什么第5层需要创建选项卡的原因。制作几个这样的类可能是有意义的,以尽量减少不需要的信息量。
下一步是要注意实际使用此信息的对象不了解或关心MainWindow。他们可能会在完全不同的程序中使用它们,或者它们可能会在此程序中以不同的方式使用。 他们获得的信息可能不是来自MainWindow。他们想要的不是类实例,而是接口实例。切换到接口,您的代码变得更简单,更灵活。
最好不要把这一切都搞得一团糟。我的观点并不是你现在应该做很多工作。相反,如果您的项目继续顺利,您需要牢记您的方向。
(请注意,公共字段和静态方法 不能与Java接口一起使用!避免使用它们。)
答案 1 :(得分:2)
如果您不想创建MainWindow类的任何实例,那么我会将共享成员设为静态。但是,不能从静态上下文引用非静态成员,因此如果在现在静态方法中使用其他非静态方法和变量,它们也必须是静态的。
基本上你会为它们分配一个固定的内存位置,所以只是静态地引用它们并不错。但是,我总是设法避免让事情变得静止。如果您发现必须使很多成员静态,请重新考虑您的计划结构。
尽量避免做任何静态的事情(除了常量)。从“工作”中分离GUI是正确的做法。将您的程序视为树,并对其进行构造,使得创建的对象无需在树中调用其上方的内容。当然,这并不总是可行,但它使测试,扩展和调试更容易(在大多数情况下)。
答案 2 :(得分:2)
这实际上取决于你想要如何制作你的节目。我想说,如果你打算制作一个以上的MainWindow,那么让它静态可能不是一个好主意。否则,我不完全确定使MainWindow静态的缺点是什么。 (除了能够从MainWindow中引用静态变量和方法之外。)
另一方面,您可以使用MainWindow类中的接口封装选项卡,以允许多个MainWindow类,而不会产生混淆。如果标签严重依赖于MainWindow,这对我来说似乎是最好的。 (我相信这与mort的答案类似。)
对我而言,“良好实践”应该意味着“良好的编程”,因此如果您的代码似乎更好地使用静态引用,那么使用它。只要确保保留备用计划以防出现问题。
然后,Java不是我的首选语言,所以我可能会有一些概念混乱。
答案 3 :(得分:1)
您可以将MainWindow定义为单身。
答案 4 :(得分:1)
我只做了一点GUI工作,但我一直在考虑这个问题。我认为正确的方法是首先确保你的表示类(小部件/组件)和它们背后的逻辑之间有一个清晰的分离,主要是使用回调接口,让你在各层之间来回交换消息。对于大型应用程序,我使用DI框架来管理后台的“逻辑”对象。然后所需要的只是一些框架代码 - 可能已经存在一个我不知道的框架 - 这使得您的演示文稿对象可以轻松地与您的DI容器管理的bean连接。不惜一切代价避免任何静电。除非你根本不关心测试,否则这是错误的应用程序。
答案 5 :(得分:0)
本地化问题的一种不同方法是从根面板或框架开始,然后递归遍历所有组件。因此,只有可以导致本地更改的UI组件才需要引用根面板或框架。
答案 6 :(得分:0)
对我而言,将父对象传递给子对象是非常糟糕的,如果它是一个swing组件,那么它永远不应该完成。
答案 7 :(得分:0)