Java——这是好的编程习惯吗?
只是想知道以下内容是否被认为是良好的编程实践? 我喜欢让我的个人源文件尽可能简洁和整洁,但我想知道更有经验的程序员会怎么想。 我特别喜欢 Settings.java 类的想法,它将我所有的“Magic Numbers”保存在一个地方。 有人对我如何改进有任何建议吗?
快乐编码:-)
class ApplicationLauncher
{
public static void main(String[] args)
{
SwingApplication mySwingApplication = new SwingApplication();
}
}
//////////////
import javax.swing.*;
public class SwingApplication extends JFrame
{
public SwingApplication()
{
JFrame myJFrame = new JFrame();
myJFrame.setSize(Settings.frameWidth, Settings.frameHeight);
myJFrame.setVisible(true);
}
}
//////////////
class Settings
{
static int frameWidth = 100;
static int frameHeight = 200;
}
Just wondering if the following is considered to be good programming practice or not? I like to keep my individual source files as concise and uncluttered as possible, but I'm wondering what more experienced coders would think of it. I especially like the idea of the Settings.java class to keep all of my "Magic Numbers" in the one place. Has anyone any suggestions as to how I might improve on things?
Happy coding :-)
class ApplicationLauncher
{
public static void main(String[] args)
{
SwingApplication mySwingApplication = new SwingApplication();
}
}
//////////////
import javax.swing.*;
public class SwingApplication extends JFrame
{
public SwingApplication()
{
JFrame myJFrame = new JFrame();
myJFrame.setSize(Settings.frameWidth, Settings.frameHeight);
myJFrame.setVisible(true);
}
}
//////////////
class Settings
{
static int frameWidth = 100;
static int frameHeight = 200;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
拥有一个设置类并没有什么问题; 但是,在您的示例中,这些设置在它们适用的框架方面相当模糊,它们也不是实际设置,而是严格属于 SwingApplication 类的默认值。
我们无法控制的另一件事是 Swing 中的构造函数调用如何级联到程序的消息泵循环中。
对我来说,永远不会返回(除非框架关闭)并且不仅仅初始化对象的构造函数从来没有意义。
There's nothing wrong with having a settings class; however, in your example the settings are rather ambigious in terms of what frame they apply to, neither are they actual settings, but rather default values that strictly belong in the SwingApplication class.
Another thing which we don't have much control over is how the constructor call in Swing cascades into the program's message pump loop.
To me it has never made sense with a constructor that never returns (unless the frame is closed) and does more than initialize an object.
使用带有幻数的特殊类作为静态成员是一种很好的 Java 实践。
随着程序的增长,可以使用多个设置类,每个设置类都有描述性名称。
Having special classes with magic numbers as static members is a good Java practice.
As programs grow, multiple settings classes, each with descriptive names, can be used.
有些人喜欢将所有这些东西、幻数等分组到一个又大又难看的 XML 文件中,该文件将在运行时读取(并理解)。 您的方法显然适合小型项目(例如一般课程作业),但请考虑一下从 XML 文件获取这些设置的明显优势:您无需重新编译源代码即可反映对设置所做的更改:)
Some like to group all of this stuff, the magic numbers etc... in a big and ugly XML file which will be read (and made sense of) at runtime. Your approach is obviously okay for a small project (e.g. general coursework) but think about the obvious advantage of getting these Settings from an XML file: you will not need to recompile your source code in order to reflect changes made to your settings :)
您正在使用一些人所说的“可怕的常量接口反模式”,尽管常量通常位于导入的接口中。 我对此没有任何问题,特别是自从静态导入出现以来,但也许有人会告诉我们可怕的罪恶。 其中之一似乎是“这不是接口的用途”。
更值得关注的是,您应该在线程中启动 GUI:
You are using what some folks call the "dreaded constants interface antipattern", though usually the constants are in an interface that is imported. I don't have a problem with it, especially since the advent of static imports, but perhaps someone will fill us in on the terrible evils. One of them seems to be "that is not what interfaces are for".
Of more concern is that you should be starting your GUI in a thread:
正如其他人所说,这是非常好的做法,但是您可以采取一些措施来改进代码:
Settings
类提供一个私有的无参数构造函数。 这使得实例化变得不可能,并且使其作为常量存储库的意图更加清晰。final
(不可变)以及static
。LIKE_THIS
而不是likeThis
。import static Settings.FRAME_WIDTH;
以便能够直接使用FRAME_WIDTH
,而不必编写设置.FRAME_WIDTH
。这最终会得到:
As others have said, this is perfectly good practice, but there are some things you can do to improve the code:
Settings
class a private no-argument constructor. This makes it impossible to instantiate and makes its intent as a repository of constants clearer.final
(immutable) as well asstatic
.LIKE_THIS
rather thanlikeThis
.import static Settings.FRAME_WIDTH;
in your classes to be able to useFRAME_WIDTH
directly instead of having to writeSettings.FRAME_WIDTH
.This ends you up with:
马克很好地掩盖了这一点。 此外,通过这种方式,您将来可以轻松地将某些设置转移到实际的用户首选项中,以便他们可以自定义程序的不同部分。 由于您的所有设置都已隔离到各自的类中,因此您只需付出最少的努力即可。
Macker covered it well. In addition, doing it this way will allow you to, in the future, move some of the settings easily into actual user preferences so they can customize different parts of the program. Since all your settings are already isolated into their own classes, this will require a minimal amount of effort on your part.
我认为只要设置不太可能更改并且您记录了设置之间的关系,这可能是一个很好的做法。 如果这些可能会改变,那么配置文件和/或命令行参数更有意义,因为它们不需要重新编译。
I think that can be a good practice as long as the settings are unlikely to change and you document the relationship between the settings. If these are likely to change then config files and/or command line arguments make more sense, since they don't require recompilation.
如果你打算对你的幻数使用静态,如果你想让它们不改变的话,请确保它们也是最终的。
If you are going to use statics for your magic numbers, make sure they're also final, if you mean for them not to change.
可变静态是一个非常糟糕的主意。 坚持“从上面进行参数化”。
直接问了,但是示例代码还有其他问题。 您扩展了
JFrame
(一种不好的做法),但随后忽略了它并创建了另一个要实际使用的JFrame
。 此外,您还需要包含样板文件,以便始终访问 AWT 事件调度线程 (EDT) 上的 Swing 组件。Mutable statics are a really bad idea. Stick with "Parameterisation from Above".
It was directly asked, but the example code has other problems. You have extended
JFrame
(a bad practice), but then ignored that and created anotherJFrame
to actually use. Also you need to include the boilerplate to always access Swing components on the AWT Event Dispatch Thread (EDT).您可能需要研究 JSR 296 (Swing 应用程序框架) 来处理 GUI 设置/启动/特性。
You might want to look into JSR 296 (Swing Application Framework) for dealing with your GUI settings/launching/properties.
另一种不需要静态导入的解决方案是创建一个包含字段、getter 和 setter 的完整“ApplicationSettings”类,并将此类的实例传递给需要参数的类的构造函数。 这允许您保留一个配置对象,例如,如果您想在用户调整窗口大小时保存新大小,则可以轻松保留或修改该配置对象。
Another solution, which does not require static imports, would be to create a complete "ApplicationSettings" class with fields, getters and setters, and pass an instance of this class to the constructor of the class that needs the parameters. This allows you to keep a configuration object which can easily be persisted or modified if you want to save the new size if the user resizes the window, for example.