简体   繁体   English

Java - 这是一个很好的编程实践吗?

[英]Java - Is This Good Programming Practice?

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. 我特别喜欢Settings.java类的想法,将我的所有“魔数”保存在一个地方。 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;
}

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. 但是,在您的示例中,设置在它们应用的框架方面相当暧昧,它们既不是实际设置,而是严格属于SwingApplication类的默认值。

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. 另一件我们无法控制的事情是构造函数如何调用Swing级联到程序的消息泵循环中。

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. 对我来说,永远不会有一个永不返回的构造函数(除非框架被关闭)并且不仅仅是初始化一个对象。

Having special classes with magic numbers as static members is a good Java practice. 将魔术数字作为静态成员的特殊类是一种很好的Java实践。

As programs grow, multiple settings classes, each with descriptive names, can be used. 随着程序的增长,可以使用多个设置类,每个类都具有描述性名称。

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. 有些人喜欢将所有这些东西,魔术数字等组合在一个大而丑陋的XML文件中,该文件将在运行时被读取(并且有意义)。 Your approach is obviously okay for a small project (eg 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 :) 您的方法显然适用于小型项目(例如一般课程),但考虑从XML文件获取这些设置的明显优势:您不需要重新编译源代码以反映对您的设置所做的更改:)

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: 更值得关注的是你应该在一个线程中启动你的GUI:

    //Schedule a job for the event-dispatching thread: creating
    //and showing this application's GUI.
    SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame myJFrame = new JFrame();
                myJFrame.setSize(Settings.frameWidth, Settings.frameHeight);
                myJFrame.setVisible(true);
            }
        });

As others have said, this is perfectly good practice, but there are some things you can do to improve the code: 正如其他人所说,这是一个非常好的做法,但是你可以做一些改进代码的事情:

  • Give the Settings class a private no-argument constructor. Settings类提供一个私有的无参数构造函数。 This makes it impossible to instantiate and makes its intent as a repository of constants clearer. 这使得无法实例化并使其作为常量存储库的意图更加清晰。
  • The settings should be final (immutable) as well as static . 设置应该是final (不可变的)以及static
  • Typically, constants in Java are written LIKE_THIS rather than likeThis . 通常,Java中的常量是LIKE_THIS而不是likeThis
  • If you're using Java 1.5 or greater, you can use import static Settings.FRAME_WIDTH; 如果您使用的是Java 1.5或更高版本,则可以使用import static Settings.FRAME_WIDTH; in your classes to be able to use FRAME_WIDTH directly instead of having to write Settings.FRAME_WIDTH . 在您的类中,可以直接使用FRAME_WIDTH ,而不必编写Settings.FRAME_WIDTH

This ends you up with: 这样就结束了:

class Settings
{
    /** Do not instantiate! */
    private Settings() {}

    static final int FRAME_WIDTH = 100;

    static final int FRAME_HEIGHT = 200;
}

Macker covered it well. Macker很好地覆盖了它。 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. 如果这些可能会改变,那么配置文件和/或命令行参数更有意义,因为它们不需要重新编译。

如果你打算使用静力学作为你的幻数,请确保它们也是最终的,如果你的意思是他们不要改变。

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 another JFrame to actually use. 你已经扩展了JFrame (一个不好的做法),但后来忽略了它并创建了另一个实际使用的JFrame Also you need to include the boilerplate to always access Swing components on the AWT Event Dispatch Thread (EDT). 此外,您还需要包含样板文件以始终访问AWT事件调度线程(EDT)上的Swing组件。

您可能需要查看JSR 296( Swing应用程序框架 )来处理GUI设置/启动/属性。

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. 另一个不需要静态导入的解决方案是创建一个包含字段,getter和setter的完整“ApplicationSettings”类,并将此类的实例传递给需要参数的类的构造函数。 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. 例如,如果要在用户调整窗口大小时保存新大小,则可以保留一个可以轻松保留或修改的配置对象。

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

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