1

I have a global boolean variable which I use to disable all trading in my financial trading system. I disable trading if there is any uncaught exception or a variety of other conditions (e.g. no money in account).

Should this variable be static or an instance variable? If its an instance I will need to add it to constructors of loads of classes...Not sure if its worth the hassle.

Thxs.

DD.
  • 21,498
  • 52
  • 157
  • 246
  • 5
    Whether it's static or not depends on your codebase, but in either case, this should be hidden behind an abstraction. E.g. `MyFinancialTradingSystem.stopTrading()` to stop trading, and `MyFinancialTradingSystem.canTrade()` to determine if trading is allowed. – Paul Grime Dec 30 '11 at 10:31
  • 2
    look at here http://stackoverflow.com/questions/7026507/why-are-static-variables-considered-evil – Hemant Metalia Dec 30 '11 at 10:32
  • 1
    If one account has no money do you really want to stop trading globally? – Peter Lawrey Dec 30 '11 at 10:37
  • @Peter that is not a point here..any way! – Amit Dec 30 '11 at 10:43
  • I only trade from one account.. – DD. Dec 30 '11 at 10:47
  • If you are only trading one account, why not turn off trading for that account, rather than globally? Then you don't need a global instance. – Peter Lawrey Dec 30 '11 at 11:06

6 Answers6

4

If it's an instance, then you probably want it to be a Singleton, and you'll provide a public static getter (or a factory, or DI if you care about testing).

If you access it from multiple threads, then it'd better be an AtomicBoolean in both cases.

milan
  • 11,872
  • 3
  • 42
  • 49
  • Not sure singleton and instance would give you any advantages over using just static. – DD. Dec 30 '11 at 13:58
  • it could give you encapsulation (hiding the value behind some methods). sure, you could make those methods static but then it's about testing. – milan Dec 30 '11 at 14:05
2

Throughout your entire career, the number of times that you will have a valid use for a global variable will be countable in the fingers of one hand. So, any given time you are faced with a "to global or not to global" decision, most chances (by far) are that the correct answer is NOT. As a matter of fact, unless you are writing operating system kernels and the like, the rule of thumb should be "do not, under any circumstances, make any variable whatsoever, anywhere, anytime, global."

Note that wrapping access to a global variable in a global (static) method is just fooling yourself: it is still just a global variable. Global methods are only okay if they are stateless.

The link provided by @HermantMetalia is a good read: Why are static variables considered evil.

In your case, what you need is probably some kind of "Manager" object, a reference to which you pass as a construction time parameter to all of your major logic objects, which, among other things, contains a property called "isTradingAllowed" or something like that, so that anyone interested in this piece of information can query it.

Community
  • 1
  • 1
Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
  • I dont really get the whole "static variables are hard to test"....surely I can initialize the variable at the start of my test and test its affects? How is that any different to setting up a mock? – DD. Dec 30 '11 at 13:17
  • I suppose you are referring to Jon Skeet's statement. Global state is hard to test because at any given moment it affects the behavior of your entire system, so testing it requires actually emulating your entire system. Which is, of course, impossible. It would be nice if testing a global variable was simply a matter of storing 5 in it and then immediately checking to see if it still holds 5. Instead, you have to run your entire system, see how the value 5 affects the system, see what values the system stores in the variable as it runs, and see how the system responds to those changing values. – Mike Nakis Dec 30 '11 at 13:28
  • Not sure what you mean by "emulating your entire system". Why cant you just set the variable at beginning of your test. As long as your tests don't run concurrently then why is that a problem? If each test passes then you have verified that every class that uses that variable behaves correctly. – DD. Dec 30 '11 at 13:57
  • 1
    This assumes a simplistic scenario where you can guarantee that the global variable is only written in one place and read in multiple places. But this is practically never the case, not even in your system, as you mention "a variety of conditions" under which GlobalDisableTrading may be set. So, it may change during the execution of some method. How do you emulate that? – Mike Nakis Dec 30 '11 at 14:30
  • Also, your example is very simplistic, because it involves a flag which only gets set, and then there is nothing to do until the program exits. Consider a more complicated scenario where the flag may also be rest. Or consider a scenario where it is not a flag, but an integer. And it may change at any time during the execution of the tested function. What then? – Mike Nakis Dec 30 '11 at 14:31
  • Also, the problem is usually not a single global variable, but a combination thereof. That's why Jon Skeet wrote about 'Global State' rather than just a 'Global Variable'. How do you test combinations of values of global variables which may change anytime, anyplace? – Mike Nakis Dec 30 '11 at 14:33
  • I dont really follow you...if I have a class that has a dependency on the public static boolean isTradingEnabled()...I can easily UNIT test the two scenarios when it is enabled and disabled and have complete certainty my unit test works. I don't see why I need to emulate how this gets set...I just need to check my classes dependent on this variable work. – DD. Jan 01 '12 at 19:02
  • Does your unit test of `BigTradingFunction()` check the scenario in which `isTradingEnabled()` starts returning `false` in the middle of `BigTradingFunction()`'s execution? (That is, after `BigTradingFunction()` has done plenty of work, but while it still has plenty of more work to do.) – Mike Nakis Jan 01 '12 at 19:24
  • Well at the moment its only read in one place...but even if it was read in two places you would have the same problem if you were using instance instead of static so either way you have the same issue. – DD. Jan 01 '12 at 21:59
  • No, you don't. Because if you had a manager providing this information, you would be able to substitute it with a special 'testing' instance of that manager, which would set the flag on the Nth time it is asked for the value of the flag, where N is incremented by 1 each time the test is repeated, so by repeating the test enough times you would cover all possible moments in time when the flag would be set. And this is just a tiny example of the flexibility you gain if you do not tie yourself with global variables. – Mike Nakis Jan 01 '12 at 22:16
  • The code will do something like if(Trading.Enabled()) executeTrade(); Why would I need to call that n times? The method above would be trivial to test with static variables...I dont understand why you wouldnt use static for this example. – DD. Jan 03 '12 at 00:23
1

I'd put it in a static field. But prefer to make it an AtomicBoolean to prevent threading issues :-)

public class TradeMaster {
    private static final AtomicBoolean TRADING_ALLOWED = new AtomicBoolean(true);

    public static void stopTrading() {
       TRADING_ALLOWED.set(false);
    }

    public static boolean isTradingAllowed() {
       return TRADING_ALLOWED.get();
    }
}
Hiery Nomus
  • 17,429
  • 2
  • 41
  • 37
  • +1: Something to allow trading would be useful as well. I would log the thread and stack trace at the point trading is disabled so you can get an idea of why trading stopped. – Peter Lawrey Dec 30 '11 at 10:37
  • -1: spoon feeding should be avoided. Let the user learn by their own. The motive should be to increase the programmers ability to understand instead of increasing the reputation by giving sweet answers.. – Amit Dec 30 '11 at 10:38
0

Static Pros: No need to pass references to instance to every class which will be using this

Static Cons: May lead to difficult in testing - I think it should be fairly easy to test a static variable if you set the state of the variable before and after the test (assuming the tests are not running concurrently).

Conclusion: I think the choice here depends on what your view of testing static variables is...For this simple case of one variable managing the state I really cant see the problem with using static. On the otherhand...its not really that hard to pass an instance to the constructors of the dependent classes so you dont really have any downside when using the instance approach.

DD.
  • 21,498
  • 52
  • 157
  • 246
-1
  1. It should be static since it will be shared by all the instances of this class.
  2. It should be static since you dont want to have a separate variable for all the objects.

Given that I would suggest that you read some good resources for static variable usage they work like charm unless you mess them..

Amit
  • 13,134
  • 17
  • 77
  • 148
  • A lot of resources suggest to avoid using static variables/methods as it leads to problems with unit testing. – DD. Dec 30 '11 at 11:53
  • Ya, that is the problem in programming so many things are 'not recommended', well if I suggest having a constant in your constants file or having an interface with this single public variable many would down vote as these are also not a recommended solution. Everything depends on your project requirements and the way you perceive the design of your project. In your case i strongly feel the solution provided by @Paul Grime in one of the comments will be the best solution.. rest is your choice.. – Amit Dec 30 '11 at 12:01
  • Amit...thats not very helpful. I'm looking for an objective look at the pros/cons of each approach. Paul Grime doesnt comment on whether static or instance is better here which is the whole point of my question. – DD. Dec 30 '11 at 13:13
  • If u have a close look on @Paul Grime's comment you will find that he is talking about "static" variables... He says `"E.g. MyFinancialTradingSystem.stopTrading() to stop trading, and MyFinancialTradingSystem.canTrade() to determine if trading is allowed."`, by convention he is calling the static methods of MyFinancialTradingSystem class... read the name and the naming style. – Amit Jan 02 '12 at 05:09
  • 1
    @Dear DownVoter.... please dare to comment...so that I can also learn something from you. – Amit Jan 02 '12 at 05:10
  • pls explain how grimes comments represents a solution to my question. He just said that make sure you use methods to set the variable and gave an example of the static case. That doesn't answer my question which is better. – DD. Jan 03 '12 at 00:11
  • Also do you have to be so condescending in your answers? – DD. Jan 03 '12 at 00:12
  • is it to suggest you to read some resources and increase knowledge ? – Amit Jan 04 '12 at 13:31
-1

If you want to make a variable constant for the class irrespective of how many instances are creted then use static method. But if the variable may change depending on the use by different instance of class then use instance variable.

Example

*

Here is an example that might clarify the situation. Imagine that you are creating a game based on the movie 101 Dalmations. As part of that project, you create a Dalmation class to handle animating the various Dalmations. The class would need instance (non-static) variables to keep track of data that is specific to each Dalmation: what its name is, how many spots it has, etc..

*

But you also need to be able to keep track of how many Dalmations have been created so you don't go over 101. That can't be an instance variable because it has to be independent of specific Dalmations. For example, if you haven't created any Dalmations, then this variable has to be able to store zero. Only static variables exist before objects are created. That is what static variables are for - data that applies to something that is beyond the scope of a specific instance of the class.

Sunil Kumar Sahoo
  • 53,011
  • 55
  • 178
  • 243