I have a few questions regarding the use of class fields and local variables.
When should a variable be declared as a field or a local variable? Of course, it's pretty obvious that if a variable only lives in the scope of a block or a function, a variable should only be local.
What if, after refactoring a function, the large function gets split up into
several private functions-- Would this be enough of a reason to
promote a local variable into a field? How about readability?
Would it be better to pass around the local variables among the private functions?
Instead of promoting into a field, would it be viable to extract a class among functions that use the same local variables?
Anything you could expound on related topics to this would be nice as well.
Declare a variable as a field when it represents the *state* of the instance.
A large function that's been split up isn't enough reason to promote local variables into fields. The impact on readability and maintainability is too significant:
programmers will always have to reason whether the fields are part of the state or are they just some temporary calculation helpers;
much, much harder to maintain thread-safety since the same fields are used for any concurrent method invocations.
passing the variables from one inner method to another helps:
independently understanding the exact functionality of the method;
re-use the inner methods;
unit-test the inner methods.
Yes, pass around the local variables.
In case there are just too much such variables, it's typical to group them in a convenient helper class, that functions as a struct. It increases readability and eases the usage.
Related
I'm curious as to know if these are the same thing.
I understand a global variable is a variable present outside a function which can be used my any function and a local variable is a variable which can only be used in and by a particular function.
What is global state? What is local state? Are they just terms used to describe the effects of using global/local variables?
Also what is the difference between global and local states and how can they affect a program?
Thank you.
Basically you are assuming correctly. The set of all global variables is known as the global environment or global state. It is a way of affecting the execution of code, hidden from sight - and should be avoided, except in special circumstances (see below). It becomes a nightmare really fast.
Local state is the opposite and is preferable. Use local variables to have complete control over your local state. It makes it easier to read your code, change it, and much easier to find errors in it. Also you do not affect other parts of your code.
It boils down to a matter of having much more control over your code, when you use encapsulation of your variables, functions/methods, and so on.
Globals can be useful, e.g. when your code needs to run in different environments (e.g. dev/staging/integration/production). Configurations are usually global. Other than that -> use locals.
Hope that helps
Ok, 2nd attempt at writing a Stack Overflow Question, so forgive me if this seems familiar.
I am rewriting an Excel Macro that was built over a 2 1/2 year period, frankenstein style (added to piecemeal). One of the things I need to do is load the data into an array once and only once for data accuracy and speed. For my skill level I am going to stick with the Array methodology.
My two approaches are:
Use Global dimmed dynamic Arrays
Dim the dynamic arrays in my Main procedure and pass them to the called procedures
So, what is Stack Overflow's take on the Pros vs Cons of these two methods?
Thanks,
Craig...
First, to answer the question you specifically didn't ask: Set up a custom class and load the data in that. Seriously, you'll thank me later.
OK, on to your question. I start by limiting the scope as much as possible. That means that I'm passing variables between procedures. When all your variables have the most restrictive scope possible, you run into the fewest problems down the line.
Once a variable passes two levels deep (calling procedure to 1st tier, 1st tier to 2nd tier), then I start taking a critical look at my structure. Usually (but not always) if all three procedures are in the same module, I'll create a module-level variable (use the Private keyword instead of Dim). If you separate your modules correctly (not arbitrarily) you can have module-level variables without much risk.
There are some variables that are always global right from the start: the variable that holds the app name and app version; the top-level class module that should never lose scope as long as the app is running; the constants (I know they're not variables) that hold things like commandbar names. I know I want these global, so they start that way.
I'm going to go out on a limb and say that module-level variables never migrate to global variables. Global variables start out that way because of their nature. If using a module-level variable seems cumbersome, it's probably because I've split a module up for no good reason or I need to rethink my whole framework.
That's not to say I've never cheated and used a global when I shouldn't have. We've all done it and you shouldn't lose any sleep if you do it too.
So to properly book-end this post: I quit using arrays unless I'm forced to. I use custom classes because
ActiveCell.Value = Invoice.LocalSalesTaxAmount
is so much nicer to debug than
ActiveCell.Value = aInvoice(35,2)
Just in case you think you need more skill to work with custom classes - so did I. I bit the bullet and so can anyone else.
You need to be careful with globals in Excel VBA, because if your application hits any kind of bug, and does some kind of soft reset (but the app still functions), then the globals will have been erased.
I had to give up on globals, since I don't write perfect apps.
I've recently been working with someone else's code and I realized that this individual has a very different philosophy regarding private variables and method parameters than I do. I generally feel that private variables should only be used in a case when:
The variable needs to be stored for recall later.
The data stored in the variable is used globally in the class.
When the variable needs to be globally manipulated (something decidedly different from the need to read the variable by every class method).
When it will make programming substantially easier. (Admittedly vague, but one has to be in many circumstances to avoid painting oneself into a corner).
(I admit, that many of the above are slightly repetitive, but they each seem different enough to merit such treatment... )
It just seems that this is the most efficient means of preventing changing a variable by accident. It also seems like following these standards will allow for the eventual manipulation of external references (if the class is eventually modified), thus leaving you with further options in the future. Is this simply a style issue (like one true bracket or Hungarian naming conventions), or do I have justification in this belief? Is there actually a best practice in this case?
edit
I think this needs to be corrected. I used "globally" above where I actually meant, "globally by instance methods" not "globally accessible by anything, anywhere".
edit2
An example was asked for:
class foo
{
private $_my_private_variable;
public function __constructor__()
{
}
public function useFoo( $variable )
{
// This is the line I am wondering about,
// there does not seem to be a need for storing it.
$this->_my_private_variable = $variable;
$this->_doSometing();
}
private function _doSomething()
{
/*
do something with $this->_my_private_variable.
*/
// This is the only place _my_private_variable is used.
echo $this->_my_private_variable;
}
}
This is the way I would have done it:
class foo
{
public function __constructor__()
{
}
public function useFoo( $variable )
{
$this->_doSometing( $variable );
}
private function _doSomething( $passed_variable )
{
/*
do something with the parameter.
*/
echo $passed_variable;
}
}
In general, class members should represent state of the class object.
They are not temporary locations for method parameters (that's what method parameters are for).
I claim that it isn't a style issue but rather a readability/maintainability issue. One variable should have one use, and one use only. “Recycling” variables for different purposes just because they happen to require the same type doesn't make any sense.
From your description it sounds as if the other person's code you worked on does exactly this, since all other uses are basically covered by your list. Put simply, it uses private member variables to act as temporaries depending on situation. Am I right to assume this? If so, the code is horrible.
The smaller the lexical scope and lifetime of any given variable, the less possiblity of erroneous use and the better for resource disposal.
Having a member variable implies that it will be holding state that needs to be held between method calls. If the value doesn't need to live between calls it has no reason to exist outside of the scope of a single call, and thus (if it exists at all) should be a variable within the method itself.
Style is always a hard one, once you develop one you can get stuck in a bit of a rut and it can be difficult to see why what you do may not be the best way.
You should only create variables when and where they are needed, and dispose of them when you are done. If the class doesn't need a class level variable to function, then it just doesn't need one. Creating variables where you don't need them is very bad practice.
Class members should be any of the following:
A dependency of a class
A variable that represents the state of the class
A method of the class
I think the answer is straightforward if you are familiar with C++ destructors. All member variables should be assigned a way to be destructed while function parameters are not. So that's why member variables are usually the states or dependicies of an object having some kind of relation regarding their lifecycle.
I'm not sure there is a stated best-practice for using globally scoped variables versus always passing as method parameters. (By "private variables", I'm assuming you mean globally scoped variables.)
Using a globally scoped variable is the only way to implement properties in .NET (even automatic properties ultimately use a globally scoped variable, just not one you have to declare yourself).
There is a line of arguement for always using method parameters because it makes it completely clear where the value is coming from. I don't think it really helps prevent the method from making changes to the underlying value and it can, in my opinion, make things more difficult to read at times.
I would disagree with implementing it for global access or to make programming easier. By exposing these globally without filtering of any kind make it more difficult to determine access in the future.
Since object properties are meant to hold state, as stated by the others, my policy is to have all of them private by default unless I have a good reason to expose them.
It's much easier to make them public later on, if you have to, simply by writing a getter method for example (which i also don't have to think about right at the beginning of writing a class). But reeling in a public property later on may require a huge amount of code to be re-written.
I like to keep it flexible while not having to think about this more than needed.
I noticed by looking at sample code from Apple, that they tend to design methods that receive structures instead of multiple parameters. Why is that? As far as ease of use, I personally prefer the latter, but as far as performance goes, is there one better choice than the other?
[pencil drawPoint:Point3Make(20,40,60)]
[pencil drawPointAtX:20 Y:50 Z:60]
Don't muddle this question with concerns of performance. Don't make premature optimizations (until you know you have a problem) and when thinking about performance hot spots in your code, its almost always in areas dealing with I/O (eg, database, files). So, separate your question on message passing style with performance. You want to make the best design decision first, then optimize for performance only if needed.
With that being said, Apple does not recommend or prefer passing multiple parameters vs a structure/object. Generalizing this outside of the scope of Objective-C, use individuals parameters or objects when it makes sense in the particular scenario. In other words, there isn't a black and white answer that you can follow. Instead, use the following guidelines when deciding:
Pass objects/structures when it makes sense for the method to understand many/all members of the object
Pass objects/structures when you want to validate some rules on the relationship between the various members of the object. This allows you to ensure the consumer of your method constructs a valid object prior to calling your method (thus eliminating the need of the method to validate these conditions).
Pass individual arguments when it is clear the method makes sense and only needs certain elements rather than the entire object
Using a variation on your example, a paint method that takes two coordinates (X and Y) would benefit from taking a Point object rather than two variables, X and Y.
A method retrieveOrderByIdAndName would best be designed by taking the single id and name parameter rather than some container object.
Now, if there was some method to retrieve orders by many different criterion, it would make more send to create a retrieveOrderByCriteria and pass it some criteria structure.
If you are passing the same set of parameters around it is useful to pass them in a structure because they belong together semantically.
The performance hit is probably negligible for such a simple structure as 3 points. Use the readable/reusable solution and then profile your code if you think it is slow :)
How do you decide between passing arguments to a method versus simply declaring them as object instance variables that are visible to all of the object's methods?
I prefer keeping instance variables in a list at the end of the Class, but this list gets longer as my program grows. I figure if a variable is passed often enough it should just be visible to all methods that need it, but then I wonder, "if everything is public there will be no need for passing anything at all!"
Since you're referring to instance variables, I'm assuming that you're working in an object-oriented language. To some degree, when to use instance variables, how to define their scope, and when to use local variables is subjective, but there are a couple of rules of thumb you can follow whenever creating your classes.
Instance variables are typically considered to be attributes of a class. Think of these as adjectives of the object that will be created from your class. If your instance data can be used to help describe the object, then it's probably safe to bet it's a good choice for instance data.
Local variables are used within the scope of methods to help them complete their work. Usually, a method should have a purpose of getting some data, returning some data, and/or proccessing/running an algorithm on some data. Sometimes, it helps to think of local variables as ways of helping a method get from beginning to end.
Instance variable scope is not just for security, but for encapsulation, as well. Don't assume that the "goal should be to keep all variables private." In cases of inheritance, making variables as protected is usually a good alternative. Rather than marking all instance data public, you create getters/setters for those that need to be accessed to the outside world. Don't make them all available - only the ones you need. This will come throughout the development lifecycle - it's hard to guess from the get go.
When it comes to passing data around a class, it's difficult to say what you're doing is good practice without seeing some code . Sometimes, operating directly on the instance data is fine; other times, it's not. In my opinion, this is something that comes with experience - you'll develop some intuition as your object-oriented thinking skills improve.
Mainly this depends on the lifetime of the data you store in the variable. If the data is only used during a computation, pass it as a parameter.
If the data is bound to the lifetime of the object use an instance variable.
When your list of variables gets too long, maybe it's a good point to think about refactoring some parts of the class into a new class.
In my opinion, instance variables are only necessary when the data will be used across calls.
Here's an example:
myCircle = myDrawing.drawCircle(center, radius);
Now lets imaging the myDrawing class uses 15 helper functions to create the myCircle object and each of those functions will need the center and the radius. They should still not be set as instance variables of the myDrawing class. Because they will never be needed again.
On the other hand, the myCircle class will need to store both the center and radius as instance variables.
myCircle.move(newCenter);
myCircle.resize(newRadius);
In order for the myCircle object to know what it's radius and center are when these new calls are made, they need to be stored as instance variables, not just passed to the functions that need them.
So basically, instance variables are a way to save the "state" of an object. If a variable is not necessary to know the state of an object, then it shouldn't be an instance variable.
And as for making everything public. It might make your life easier in the moment. But it will come back to haunt you. Pease don't.
IMHO:
If the variable forms part of the state of the instance, then it should be an instance variable - classinstance HAS-A instancevariable.
If I found myself passing something repeatedly into an instance's methods, or I found that I had a large number of instance variables I'd probably try and look at my design in case I'd missed something or made a bad abstraction somewhere.
Hope it helps
Of course it is easy to keep one big list of public variables in the class. But even intuitively, you can tell that this is not the way to go.
Define each variable right before you are going to use it. If a variable supports the function of a specific method, use it only in the scope of the method.
Also think about security, a public class variable is susceptible to unwanted changes from "outside" code. Your main goal should be to keep all variables private, and any variable which is not, should have a very good reason to be so.
About passing parameters all they way up the stack, this can get ugly very fast. A rule of thumb is to keep your method signatures clean and elegant. If you see many methods using the same data, decide either if it's important enough to be a class member, and if it's not, refactor your code to have it make more sense.
It boils down to common sense. Think exactly where and why you are declaring each new variable, what it's function should be, and from there make a decision regarding which scope it should live in.