Is “pass by reference” bad design?
Not in general. You need to understand your specific scenario and ask yourself what a function does. And you need to define your coding style properly, especially if you are coding for others (distributing libraries).
Pass by reference is usually in place when your function returns multiple outputs. It is often a good idea to return a ResultContainer
object which contains all the information your function returns. Take the following C# example:
bool isTokenValid(string token, out string username)
VS
AuthenticationResult isTokenValid(string token)
class AuthenticationResult {
public bool AuthenticationResult;
public string Username;
}
The difference is that the method with reference (in this case out
put) parameter clearly highlights that it can be used only to validate a token or optionally to extract user information. So even if you are obliged to pass a parameter you may trash it if you don't need it. The second example is more code-verbose.
Of course the second design is preferrable if you have such a method
bool doSomething(object a, ref object b, ref object c, ref object d, ... ref object z);
Because you would wrap all them into a container.
Let me now clarify: in Java and C#, non-primitive types are always passed as cloned reference. It means that object
s are not cloned themselves but only the reference to them gets cloned to the stack, and then you can't expect to be pointing to a totally different object after return. Instead you always expect the state of the object to be modified by the method. Otherwise you just clone()
the object and voilà.
So here comes the trick: MutableInteger
, or better the Holder
pattern, is the solution to passing primitive values by reference.
It is currently used by CORBA idl2java
compilers when your IDL has a reference parameter.
In your specific case I can't answer you about the good or bad design because the method you shown is too generic. So think about it. Just as an input, if I had some kind of post-processing function applied to multimedia information, even like encryption, I would use reference passing. To me, the following looks a good design
encrypt(x);
VS
x = encrypt(x);