3

I have read posts on this, so I'm aware about how static variables should be avoided, they are not object oriented, they're like globals etc.

But here's my question, hopefully it's not a repeat: I have some private class variables that many methods use and passing around would be tedious. The class I'm talking about is my main program, so the only instance of it will be the instance that the JVM creates.

In this case does it make any difference if these variables are static or not ? (Perhaps if a user opens my application multiple times and I make the variables static, they would share the variables and mix each other up?)

I'd like to use statics because want to access these variables from inside enums. Thanks

Here's the code for the enum part:

enum Buttons {

    OPEN_BUTTON("Open file...",false),
    CHANGE_FONT_BUTTON("Change font",false),
    DECOR_BUTTON("Decor font",true),
    EDITOR_BUTTON("Open editor",false),
    ALPHABET_BUTTON("Open alphabet browser",false),
    CTEST_BUTTON("Start consonant test",false),
    TESTTYPE_BUTTON("Select test type...",false),
    TEST_BUTTON("Start word test",false),
    QUIT_BUTTON("Quit", false);

    private ButtonBase button;

    Buttons(String title, boolean toggle) {
        if (toggle) button = ToggleButtonBuilder.create().prefWidth(200).prefHeight(35).text(title).build();
        else button = ButtonBuilder.create().prefWidth(200).prefHeight(35).text(title).build();}

    void onClick(EventHandler<MouseEvent> eh) {button.setOnMouseClicked(eh);}
    ButtonBase getBase() {return button;}
    boolean toggled() { return ((ToggleButton)button).isSelected();  }
    void setToggle(boolean on) {((ToggleButton) button).setSelected(on); }
    void enable() {button.setDisable(false);}
    void disable() {button.setDisable(true);}
    void setText(String text) { button.setText(text);}
    void clicked() {

// this is where i'd like to have the event handlers...

JavaMonkey22
  • 861
  • 11
  • 20
  • How will your enums need to access a non-constant program variable? This seems an unusual design? My gut tells me that you shouldn't be doing this. By "main program" if you mean the class with the main method, well that method should be short as possible and only serve to create objects and get them up and running and that's it. – Hovercraft Full Of Eels Mar 08 '13 at 23:14
  • I'm using JavaFx and I'm making my Buttons into an enum, and I'd like to add the ActionEvent (click) handler inside the enum, so it's all neatly in one place. The handlers need to access the class variables. – JavaMonkey22 Mar 08 '13 at 23:18
  • 2
    Then the answer is easy: This smells of bad design. The enums should be for constants not for GUI components. Simply don't do this. – Hovercraft Full Of Eels Mar 08 '13 at 23:19
  • sorry mistakenly tried to insert code – JavaMonkey22 Mar 08 '13 at 23:19
  • insert code as an edit to your main question, not as a comment. – Hovercraft Full Of Eels Mar 08 '13 at 23:24

3 Answers3

4

You state:

I'm using JavaFx and I'm making my Buttons into an enum, and I'd like to add the ActionEvent (click) handler inside the enum, so it's all neatly in one place. The handlers need to access the class variables.

This is not a good design, is not a reason for static variables, and also a mis-use of enums. You're tossing out all benefit of OOP with this design and so I urge you to just not do this. Note that if/when you update or modify your code, you will often change your GUI components, and enums should (almost) never change. They should represent the unchanging bedrock of your logic. They should not be used for objects whose state changes as your buttons currently do.

I would also recommend against singleton pattern here as there is no need to use this for GUI components (and in fact singletons are quite similar to enums). Why not simply create a View class?

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Could you be more specific Why is this not a good design? It has major benefits for me, now I can refer to my buttons like OPEN_BUTTON.disable(), instead of something like openButton.setDisabled(true) because I added a convenience method to the enum. Before I had my buttons in an array because I have a lot so I was referring to them like buttons[1], etc, which made my code unreadable. I also keep adding new buttons and changing them around, so this makes that much easier. I have several convenience methods in the enum, the above is a simple example, but I have some complex ones as well. – JavaMonkey22 Mar 08 '13 at 23:26
  • @JavaMonkey22: why not simply make a GUI View class? What is difficult about altering the state of your View components from your Control? Why do you need enum for this? You look to be trying to use enums to make global variables, and that's not what they're for. – Hovercraft Full Of Eels Mar 08 '13 at 23:28
  • @JavaMonkey22: does JavaFx not allow MVC pattern? – Hovercraft Full Of Eels Mar 08 '13 at 23:34
  • This answer is just criticism without much justification. Can we see an example of the View class? – Kev Mar 08 '13 at 23:35
  • @JavaMonkey22 - will JavaFx not allow you to have `class MyFancyButton extends NormalButton` in order to add `.disable()` as a method? – Stephen P Mar 09 '13 at 00:03
  • @Stephen P You're right, the same thing could be done with a class. In fact an enum is a class, right? So it's the same thing, but here I have the instantiation in the same place as the methods, if I create a separate class I have to instantiate elsewhere, that's what I like about this design, that everything is in one place. If I create a view class, I have to create instances and assign the event handlers away from the class, this makes my code less readble. This way I know where to find everything, so besides rules of thumb, is there any objective reason why this is bad design ? – JavaMonkey22 Mar 09 '13 at 00:13
  • 1
    @JavaMonkey22 You could do the same "instantiation in the same place as the methods" without abusing an enum by having statics in your `MyFancyButton` class, but I still wouldn't. The buttons belong to something else; e.g. a Window or Dialog, a toolbar, etc. and maybe a single event handler can be invoked by a button and a menu and a three-finger-swipe to the upper-right, or even a change in the detected temperature. A single button could (potentially) be added to more than one UI widget also. Separate your concerns; that's why Hovercraft's suggestion of a GUI View class makes sense. – Stephen P Mar 09 '13 at 00:30
  • @Stephen P - Thanks I understand as a rule of thumb this is abusing enums but in this particular case I still don't understand why this is bad - I have yet to hear any specific disadvantage to this that applies to me. I will NOT be using these buttons elsewhere. The enum has made my code much shorter because in my click handler I can do a switch on the enum (i.e. which button was pressed), whereas if I had a class I would not be able to switch the static Button fields, making the code more verbose. So this is working for me with real benefits. – JavaMonkey22 Mar 09 '13 at 18:25
2

If you find you're passing teh same data around a lot then it seems to me like that data may have a certain amount of correlation - perhaps by encapsulating that data into some kind of value object you wouldnt need to use effectively global data?

pauljwilliams
  • 19,079
  • 3
  • 51
  • 79
  • Thanks, this is true, I refactored my code to lower the use of statics, I found I was using some of the statics in only 2 classes, so now I'm passing them and this has made the code better. – JavaMonkey22 Mar 24 '13 at 23:52
-1

Within a single classloader, static fields are always shared. To explicitly scope data to threads, you'd want to use a facility like ThreadLocal.

Link

So if you use statics with ThreadLocal, you won't have a problem with multiple instances of your app.

Community
  • 1
  • 1
Kev
  • 2,656
  • 3
  • 39
  • 63