Why do we need private variables?

  • Why do we need private variables in classes?

    Every book on programming I've read says this is a private variable, this is how you define it but stops there.

    The wording of these explanations always seemed to me like we really have a crisis of trust in our profession. The explanations always sounded like other programmers are out to mess up our code. Yet, there are many programming languages that do not have private variables.

    1. What do private variables help prevent?

    2. How do you decide if a particular property should be private or not? If by default every field SHOULD be private then why are there public data members in a class?

    3. Under what circumstances should a variable be made public?

    Your question sounds very language-agnostic, but you have tagged it as java and c++. If you are interested in perspectives from outside those two languages, you should probably say so.

    For the record, creating a private method doesn't increase "security". Other parts of your application can still access private members using reflection.

    I had a similar question when I saw implementation-agnostic classes being used.

    The usage and difference of private and public variables, and why we have them, can only be understood in the context of general Object-oriented principles. It cannot be understood separately. You probably need to look at it from that perspective, things may get clearer.

    @James - This is not language-agnostic: private variables don't exist in Objective-C for instance.

    Something to consider when reading the answers below: Source code is documentation. When you see `private foo`, you know that the author of the code did not _intend_ for `foo` to be used from other compilation units, and when you see `public foo` you know the opposite.

    If you catch anyone using a seatbelt in their car, you should take their driving license away, since obviously they don't trust their own abilities to drive.

    @mouviciel: In practice, Objective-C has private class members. You just declare them in the implementation file, not in the header. You can even declare a property readonly in the header file, and readwrite in the implementation.

  • tdammers

    tdammers Correct answer

    9 years ago

    It's not so much a matter of trust, but rather one of managing complexity.

    A public member can be accessed from outside the class, which for practical considerations means "potentially anywhere". If something goes wrong with a public field, the culprit can be anywhere, and so in order to track down the bug, you may have to look at quite a lot of code.

    A private member, by contrast, can only be accessed from inside the same class, so if something goes wrong with that, there is usually only one source file to look at. If you have a million lines of code in your project, but your classes are kept small, this can reduce your bug tracking effort by a factor of 1000.

    Another advantage is related to the concept of 'coupling'. A public member m of a class A that is used by another class B introduces a dependency: if you change m in A, you also have to check usages of m in B. Worse yet, nothing in class A tells you where m is being used, so again you have to search through the entire codebase; if it's a library you're writing, you even have to make sure code outside your project doesn't break because of your change. In practice, libraries tend to stick with their original method signatures as long as possible, no matter how painful, and then introduce a block of breaking changes with a major version update. With private members, by contrast, you can exclude dependencies right away - they can't be accessed from outside, so all dependencies are contained inside the class.

    In this context, "other programmers" include your future and past selves. Chances are you know now that you shouldn't do this thing X with your variable Y, but you're bound to have forgotten three months down the road when a customer urgently needs you to implement some feature, and you wonder why doing X breaks Y in obscure ways.

    So, as to when you should make things private: I'd say make everything private by default, and then expose only those parts that absolutely have to be public. The more you can make private, the better.

    +1 for getting at the heart of the issue, though I've personally found my code easier to maintain when I stopped going through hoops just to ensure that a frequently used variable stays private. Sure an error may come up in the future, but it's 60 less lines of code to sift through, and less variables and functions to boot ;)

    The holy grail of modern computing is keeping complexity down.

    I never realized it was used for managing complexity because in every case I've ever seen them used it was for security. Which is super funny because those same occasions used serializable classes which means there's no such thing as protection. Simply serialize, munge the data, and deserialize.

    I always like to say that part of debugging is not just driving directly towards "what went wrong," but taking the roundabout process of figuring out "what didn't go wrong," and focusing my investigation on what is left. If I can get the compiler to assist me with tools like private variables to define "what cannot possibly have occurred," that saves me a load of time. Only in the rare cases where I prove that what did go wrong cannot have occurred do I have to dig into the more frightening assumptions, like perhaps a buffer overrun overwriting my private data.

    @WayneWerner What do you mean, "security"? I don't think I ever saw an example of a variable being private for "security" :/ Can you provide an example? Like this answer states, keeping internal state private is all about managing complexity and reducing the probability of bugs, and this is how it's explained everywhere.

    Exactly that. When people hear "information hiding", they think that they should use private variables for things like encryption keys, database credentials, etc.

    So then, are one line getters and setters like `return this.name` and `this.name = name` worthwhile? If you have a bug, I don't see how having such methods brings you closer to finding the bug versus if `name` was public.

    So then, I suppose tutorials using `nuclear_codes` as an example of a private variable are being misleading.

    @AdamZerner see "Tell, don't ask" (https://martinfowler.com/bliki/TellDontAsk.html) about having getters/setters in the first place - but otherwise yes, because you should be free to change the internal representation of the value anytime you wish. As always, there are exceptions... (e.g. DTOs)

    "Why do we need privates?" is almost the same question as "Why are globals bad?" Both are great questions to really understand. If another module wants to reach in a touch this one perfect thing that gets him what he wants, that's perfect! But it starts turning into a spaghetti mess that's extremely hard to follow and hard to troubleshoot bugs. Hacks are applied to fix complex bugs. After multiple layers of hacks, trying to figure out how a variable got set to a particular value can become almost impossible. The reasons described above answer why globals are bad as well - complexity, coupling.

    Globals would also imply not having different object-instances of the same class. So actually, why-not-globals is a slightly different question that why-use-privates.

    We want to express code-logic in a way that reduces complexity. If we can look at code and say: this data can only be touched from this small scope, it is way easier to reason about the logic (to ensure correctness and troubleshoot bugs). We are basically setting up restricted-scope rules and telling the compiler to enforce them so we don't even need to think about the possibility of other code affecting these privates. Then we explicitly publish as public only what minimally should be public. And only pass the instance handle to places it should be used from.

    Even in my college teachers teach that with c++ you can make banking application because it provides security and with c you cannot as it does not provide security.

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM