views:

72

answers:

2

I have a generic question about scope and encapsulation. Take two scenarios:

Scenario 1:

// a global application level constant
public static const IS_DEMO_MODE:Boolean = false;   

... // somewhere deep in the codebase

private function _myFunction():void
{
    if (IS_DEMO_MODE == true) {
      // If Demo Mode do not allow this function to complete
      return;    
    }
    else {
       // Function behaves normally
       // Code ...
    }

}

Scenario 2:

// a global application level constant
public static const IS_DEMO_MODE:Boolean = false;   

... // somewhere deep in the codebase

 // call the function and pass in the constant
_myFunction(IS_DEMO_MODE);


private function _myFunction(isDemoMode:Boolean):void
{
    if (isDemoMode == true) {
      // If Demo Mode do not allow this function to complete
      return;    
    }
    else {
       // Function behaves normally
       // Code ...
    }

}

Functionally speaking these two code snippets do the same exact same thing. I am trying to understand the finer points of coding style and why one way might be preferred over the other? It seems that scenario 2 is better from an encapsulation point of view. But scenario 1 is more foolproof in that the boolean that is in the conditional comes from one place only, the global constant. You don't have to worry about a function call that while correctly receiving a parameter could pass in the wrong value. But scenario 2 seems worthwhile because you remove the dependency of the constant and can have the function behave more dynamically. Any thoughts on this? Are there any other trade offs I am over looking?

Same concept and question applied to objects and classes as well. But I just present the example in terms of a function for simplicity of the code example.

+1  A: 

2 would be preferred if you wanted the same compilation unit to be linked against both versions (especially as a shared library in a globally fixed path), or if you ran multiple instances in the same process. Otherwise, if you're in a situation where rebuilding everything from source is no obstacle, #1 is better.

Some things really are global. Global constants are not dangerous at all.

wrang-wrang
+1  A: 

In the second approach you can make _myFunction live in a separate module, with no dependency from the global one -- so it's easier to test, easier to reuse, and helps you control your dependency graph, which often becomes a serious problem in large codebases. If you insert dependencies you could easily avoid, you're only making the dependency-graph problem worse, and very few potential benefits could ever possibly pay for THAT.

Indeed, to gain this kind of advantages, a great dependency pattern is to explicitly INJECT object that would otherwise create (generally undesirable and undesired) dependencies between modules -- see here for a start. As a fanatic of testing, loose coupling, and reuse, I'm gradually becoming a fanatic of dependency injection too, so I wouldn't DREAM of accessing a global constant where passing it as an argument is an obvious alternative...;-).

Alex Martelli
Thanks for the response Alex. This makes sense.
Gordon Potter