When to use an object instance variable versus passing an argument to the method - variables

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.

Related

Is it a good practice to have instance variables which can be derived (computed) from other instance variables?

I'm new to Object Oriented Programming. I'm working on an application, which takes 2 URLs, fetches their source codes and parses them, and shows results based on some metrics. I'm planning to create a class, make all the metrics it's instance variables, then create 2 instances of this class (1 for each URL), pass the url in the constructor at object initialization and then initialize all the instance variables based on some computation inside the constructor itself. The values of some of the instance variables may depend on the values of other instance variables. Is it a good programming practice to do it the way I'm planning to?
This should be fine, as long as you initialize them in the correct order in your constructor. It's not good practice to calculate instance variable values at declaration, but doing so in the constructor should be no problem.
I would at least separate the construction of the object and the initialization, the latter being fetching the source code and calculating the metrics. Fetching is slow and may fail due to external circumstances. Calculation may fail due to unexpected format/content. You would want the setup to be quick and sure to succeed. You could then do the risky stuff by calling a method and if anything fails you will at least have access to the history/state through the already created object. It would make your object more versatile.

Are the instance variables the new global variables?

lately I'm having the feeling that instances variables have the same problems of global variables, I googled about this and found this old article that more or less describes the potential problem i'm seeing.
What good practices do you use to avoid that the same problems of global variables affect instance variables or class variables?
Classes are much smaller than global structure so the impact of an instance variable is much smaller. By keeping small class sizes and adhering closely to the single responsibility principle, much of the downside of a global variable is averted. If the instance variable is created from a passed in parameter then I often make that parameter required in the constructor making the dependency explicit. Also the instance variable is encapsulated well, never being directly modified outside of the instance's methods making it very easy to determine where the instance variable is modified. Finally the instance variable must make sense to the class as a whole or must be private.
Instance variables are only accessible within a specific class. So to prevent instance variables being used too widely, keep classes small. If a class grows large, decide if parts of it that can be refactored into another, smaller class, that the original class uses.
Nor Instance variables nor global variables nor any kind of variable have "problems"... They are all tools. The problem is that sometimes a lot of programmers choose to use the "wrong tool". You have to think carefully what your choices mean, so you can make the right choice.
Using a global variable for something, like CurrentUserName... Means that you are saying that he CurrentUserName is something universally know. And that "there can be only one" CurrentUserName at each time. And that will probably be false if you ever want to allow to users to be logged at the same time (unless you get really lucky, and both users have the same name)...
A realted wrong use with instance variables is if you put the e-mail address of a User as an instance variable, and you then realize that each user can have multiple e-mail addresses.
I'd also give an example with inheritance, because I think it'll make it more clear:
A related problem with inheritance is for example if you are modeling the typical Student, Teacher problem, and you try making Student a subclass of Person and Teacher a subclass of Person. And then you realize that some persons might be both...
Student inheriting from Person is a static relationship that can't be changed at runtime. And Student and Teachers aren't static relationships... A person can be neither, and then start being a student, and then start being a teacher, and then stop being both, and yet it'll always be the same person, and that model can't handle that....
Coming back to the user, the user is "associated" with multiple e-mails account... If you put an instance variable you are stating that he is just "associated" with a single e-mail account, and you are contradicting your problem domain, and that's why you'll have problem...
The same applies if you say there is just a globally known current user name....
The problem in all cases is that you have a problem domain, and you are modeling it wrong... You have to make your program, and your model, behave similar to the problem domain.... If you don't do it, you'll have problems, whichever tool you choose to solve your problem.
BTW: I also think that User having a list of e-mail address is wrong, but that's for an entirely different set of motives. I'd actually use a
class ContactInformation
{
User contact;
EMailAddress email;
}
and remember that objects don't "own" nor "have" other objects... That's an implementation decision... Objects just "know" other objects...

Should ecapsulated objects be public or private?

I'm a little unclear as to how far to take the idea in making all members within a class private and make public methods to handle mutations. Primitive types are not the issue, it's encapsulated object that I am unclear about. The benefit of making object members private is the ability to hide methods that do not apply to the context of class being built. The downside is that you have to provide public methods to pass parameters to the underlying object (more methods, more work). On the otherside, if you want to have all methods and properties exposed for the underlying object, couldn't you just make the object public? What are the dangers in having objects exposed this way?
For example, I would find it useful to have everything from a vector, or Array List, exposed. The only downside I can think of is that public members could potentially assigned a type that its not via implicit casting (or something to that affect). Would a volitile designation reduce the potential for problems?
Just a side note: I understand that true enapsulation implies that members are private.
What are the dangers in having objects exposed this way?
Changing the type of those objects would require changing the interface to the class. With private objects + public getters/setters, you'd only have to modify the code in the getters and setters, assuming you want to keep the things being returned the same.
Note that this is why properties are useful in languages such as Python, which technically doesn't have private class members, only obscured ones at most.
The problem with making instance variables public is that you can never change your mind later, and make them private, without breaking existing code that relies on directly public access to those instance vars. Some examples:
You decide to later make your class thread-safe by synchronizing all access to instance vars, or maybe by using a ThreadLocal to create a new copy of the value for each thread. Can't do it if any thread can directly access the variables.
Using your example of a vector or array list - at some point, you realize that there is a security flaw in your code because those classes are mutable, so somebody else can replace the contents of the list. If this were only available via an accessor method, you could easily solve the problem by making an immutable copy of the list upon request, but you can't do that with a public variable.
You realize later that one of your instance vars is redundant and can be derived based on other variables. Once again, easy if you're using accessors, impossible with public variables.
I think that it boils down to a practical point - if you know that you're the only one who will be using this code, and it pains you to write accessors (every IDE will do it for you automatically), and you don't mind changing your own code later if you decide to break the API, then go for it. But if other people will be using your class, or if you would like to make it easier to refactor later for your own use, stick with accessors.
Object oriented design is just a guideline. Think about it from the perspective of the person who will be using your class. Balance OOD with making it intuitive and easy to use.
You could run into issues depending on the language you are using and how it treats return statements or assignment operators. In some cases it may give you a reference, or values in other cases.
For example, say you have a PrimeCalculator class that figures out prime numbers, then you have another class that does something with those prime numbers.
public PrimeCalculator calculatorObject = new PrimeCalculator();
Vector<int> primeNumbers = calculatorObject.PrimeNumbersVector;
/* do something complicated here */
primeNumbers.clear(); // free up some memory
When you use this stuff later, possibly in another class, you don't want the overhead of calculating the numbers again so you use the same calculatorObject.
Vector<int> primes = calculatorObject.PrimeNumbersVector;
int tenthPrime = primes.elementAt(9);
It may not exactly be clear at this point whether primes and primeNumbers reference the same Vector. If they do, trying to get the tenth prime from primes would throw an error.
You can do it this way if you're careful and understand what exactly is happening in your situation, but you have a smaller margin of error using functions to return a value rather than assigning the variable directly.
Well you can check the post :
first this
then this
This should solve your confusion . It solved mine ! Thanks to Nicol Bolas.
Also read the comments below the accepted answer (also notice the link given in the second last comment by me ( in the first post) )
Also visit the wikipedia post

Is it better for class data to be passed internally or accessed directly?

Example:
// access fields directly
private void doThis()
{
return doSomeWork(this.data);
}
// receive data as an argument
private void doThis(data)
{
return doSomeWork(data);
}
The first option is coupled to the value in this.data while the second option avoids this coupling. I feel like the second option is always better. It promotes loose coupling WITHIN the class. Accessing global class data willy-nilly throughout just seems like a bad idea. Obviously this class data needs to be accessed directly at some point. However, if accesses, to this global class data can be eliminated by parameter passing, it seems that this is always preferable.
The second example has the advantage of working with any data of the proper type, whereas the first is bound to working with the just class data. Even if you don't NEED the additional flexibility, it seems nice to leave it as an option.
I just don't see any advantage in accessing member data directly from private methods as in the first example. Whats the best practice here? I've referenced code complete, but was not able to find anything on this particular issue.
if the data is part of the object's state, private/protected is just fine. option 1 - good.
i noticed some developers like to create private/protected vars just to pass parameters between methods in a class so that they dun have to pass them in the method call. they are not really to store the model/state of an object. ...then, option 1 - NOT good.
Why option 1 not good in this case...
expose only as much as you need (var scoping). so, pass the data in. do not create a private/protected var just to pass data between 2 methods.
private methods that figures out everything internally makes it very easy to understand. keep it this way, unless its unavoidable.
private/protected vars make it harder to refactor as your method is not 'self encompassing', it depends on external vars that might be used elsewhere.
my 2 cents! :-)
In class global data are not a problem IMHO. Classes are used to couple state, behaviour and identity. So such a coupling is not a problem. The argument suggests, that you can call that method with data from other objects, even of other classes and I think that should be more considered than coupling inside class.
They are both instance methods, therefore #1 makes more sense unless you have a situation involving threads (but depending on the language and scenario, even then you can simply lock/mark the data method as syncronized - my Java knowledge is rusty).
The second technique is more reminiscent of procedural programming.

Parameter vs. Member variables

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.