Quote:Original post by stonemetal
Sloppy code is sloppy code. Globals show a lack of thought and discipline.
Sloppy code is sloppy code. Variables beginning with the letter "Q" show a lack of thought and discipline.
Quote:Original post by stonemetal
Sloppy code is sloppy code. Globals show a lack of thought and discipline.
Quote:Original post by Noods
and I am wondering if the overhead of accessor functions would be worth it.
Quote:Original post by SneftelQuote:Original post by stonemetal
refactor your code till they are no longer necessary.
Erm, really? Can you give an example of how declaring hInstance as a global variable, for instance, would cause problems that would be solved by refactoring to remove the global?
Quote:Original post by SneftelQuote:Original post by stonemetal
refactor your code till they are no longer necessary.
Erm, really? Can you give an example of how declaring hInstance as a global variable, for instance, would cause problems that would be solved by refactoring to remove the global?
Quote:Original post by stonemetal
It doesn't really matter if it causes problems or not /.../
Quote:Original post by stonemetal
/.../ sloppy code is sloppy code.
Quote:Original post by stonemetal
Globals show a lack of thought and discipline.
Quote:Original post by mikeman
For example, if you suddenly got garbage in some table X, and you wanted to investigate the source of the trouble, the whole program would be suspect, because the whole program has access to the connection. But if you refactor and pass the connection only to the code that needs it, then the 'suspects' would be limited and debugging and maintenance would be easier.
Quote:Original post by ToohrVykQuote:Original post by mikeman
For example, if you suddenly got garbage in some table X, and you wanted to investigate the source of the trouble, the whole program would be suspect, because the whole program has access to the connection. But if you refactor and pass the connection only to the code that needs it, then the 'suspects' would be limited and debugging and maintenance would be easier.
You are advocating for global state here. See, if you have sloppy global state (that is, without any kind of restriction on who uses what part of that state) then you are bound to get into trouble because you can never know who can change a given piece.
Quote:Original post by mikeman
Can you explain that a little? How am I advocating *for* global state when I say that, in this example, you can refactor and give access to the connection only to the modules that need it? Isn't that a restriction on who uses what part of the state? Or do you mean something else? How would that problem be solved without 'global state'?
Quote:Original post by ToohrVykQuote:Original post by mikeman
Can you explain that a little? How am I advocating *for* global state when I say that, in this example, you can refactor and give access to the connection only to the modules that need it? Isn't that a restriction on who uses what part of the state? Or do you mean something else? How would that problem be solved without 'global state'?
Sure.
When you provide a value as a function argument, you allow any function within that function's call tree to manipulate and store references to that value. In an object-oriented program and with the existence of polymorphism, if you pass a value as an argument to a function of any object, then that value is potentially available to the entire graph of objects containing that object. Of course, it's probably going to be only a small part of that graph, but since the exact nature, contents and layout of the graph are determined at runtime, reasoning about them at compile-time (and even when debugging) is hard. So, the bottom line is that you can't know without great effort who is manipulating that piece of state you just passed as an argument.
On the other hand, if pieces of state are never passed around as arguments but instead encapsulated as globals in a module, then determining who can alter a piece of global state is pretty simple: only the direct or indirect callers of global functions of that module can manipulate the state. And since the graph of modules is fully defined at compile time (and can be fully documented, along with all dependencies) the analysis is even easier.
In short, if I ask you, "can this piece of code alter value X?", you'll have an easier time if the program follows a procedural module-based design. So, if you're looking for control and knowledge over who can change state, procedural modules with global states are superior to object-oriented designs.
Quote:Original post by mikemanThis has been solved a long time ago by functional programming: if values cannot be changed, then "who can change this value?" is an easy question. Of course, you don't have to go all the way to immutable values, but you can still go some distance.
Ok, got it. Thanks. So if I want to use object-oriented approach but still want to easily analyze 'who uses what', what is my best bet? Use a hybrid approach organizing my classes into modules? Or is there no good solution to this problem using OO?