14

Possible Duplicate:
Why do we need private variables?

I know that it's best practice to stay safe, and that we should always prevent others from directly accessing a class' properties. I hear this all the time from university professors, and I also see this all the time in a lot of source code released on the App Hub. In fact, professors say that they will actually take marks off for every variable that gets declared public.

Now, this leaves me always declaring variables as private. No matter what. Even if each of these variables were to have both a getter and a setter.

But here's the problem: it's tedious work. I tend to quickly lose interest in a project every time I need to have a variable in a class that could have simply been declared public instead of private with a getter and a setter.

So my question is, do I really need to declare all my variables private? Or could I declare some variables public whenever they require both a getter and a setter?

Sal Rahman
  • 1,544
  • 1
  • 12
  • 22
  • 6
    There are reasons to do so in e.g. Java. There is absolutely no reason to in e.g. Python. This is (one minor) part of why I use the latter... –  Mar 13 '11 at 08:29
  • In a language like Java where you don't have syntactical support for creating simple accessors there are cases where a public variable makes sense. Sometimes you just know that it will never be more than a simple field. – Ed S. Mar 13 '11 at 08:49
  • 3
    Use `lombok.Data` or other annotations from [it](http://projectlombok.org) to generate the accessors for you without changing the source code. – maaartinus Mar 13 '11 at 14:28
  • 1
    @maartins Big +1 for lombok in Java. I used to be in the same boat of "I hate getters" until I found out I can just type `@Data` and be done with it – TheLQ Mar 13 '11 at 16:53
  • 2
    The answer is completely language-dependent, and also dependent on the clients of the class. – kevin cline Feb 08 '12 at 17:32
  • If you are loosing interest in a project because of tedious work you better find another profession. A large chunk of real development is tedious. Not just getter/setters/properties. But all kinds of things like coding conventions etc. – ElGringoGrande Apr 11 '12 at 13:19
  • You didn't say what language you're using. The answer to this question depends on the language. Some languages have ways to make this sort of thing easier. For instance, C# has auto-properties, which don't need a private backing variable, and code snippets, which make it easier to quickly create code even if it's repetitive. – Kyralessa Apr 11 '12 at 13:48
  • -1: *I tend to quickly lose interest in a project every time I need to have a variable in a class that could have simply been declared public...*: Give me a break! – Jim G. Apr 12 '12 at 04:33

10 Answers10

28

In general yes, I and many others make exceptions for DTO's see this short blogpost by uncle Bob Martin.

If all you are doing is making private variables and using getters and setters you might want to think about why you are doing this ? There are a lot of people who say that getters and setters are evil, see this article or this article by Alan Holub. From that article:

Summing up

Let's pull everything together: You shouldn't use accessor methods (getters and setters) unless absolutely necessary because these methods expose information about how a class is implemented and as a consequence make your code harder to maintain. Sometimes get/set methods are unavoidable, but an experienced OO designer could probably eliminate 99 percent of the accessors currently in your code without much difficulty.

Getter/setter methods often make their way in code because the coder was thinking procedurally. The best way to break out of that procedural mindset is to think in terms of a conversation between objects that have well-defined responsibilities. Cunningham's CRC card approach is a great way to get started.

KeesDijk
  • 8,918
  • 4
  • 35
  • 41
  • 10
    Exactly. The first question should not be "how do I give access to these variables" but "*why* am I giving access to these variables?" – Dave DuPlantis Aug 03 '11 at 20:17
  • Dave u are right. And Kees the example with Uncle Bob is exciting ;-) I would allways declare variables private and let them be accessable by Properties. Its part of a good coding to do that. – Smokefoot Feb 08 '12 at 17:11
20

Proffessors saying "ALWAYS do this or that" in regard to programming should be fired, or go back to school themselves. In programming there is never one single best way to do something, it all depends on the particular application.

Example for your case: suppose you have a class representing a simple configuration structure with 10 fields, but no actual functionality, so no methods except a constructor maybe. All members can be read/written. Personally I would prefer

class MyConfig
{
public:
  int a;
  int b;
  int c;
  int d;
  int e;
};

much, much more than the next one, which also adds no extra functionality over the original..

class MyConfig
{
public:
  int GetA() const{ return a; }
  void SetA( int i ){ a = i; }
  int GetB() const{ return b; }
  void SetB( int i ){ b = i; }
//you get the point.. 
private:
  int a;
  int b;
  int c;
  int d;
  int e;
};
stijn
  • 4,108
  • 1
  • 25
  • 31
  • I found your answer to be refreshing. It just took a whole load of weight off my chest. Thanks! – Sal Rahman Mar 13 '11 at 09:00
  • 29
    You fail to mention the main reason sane persons write getters/setters: For validation or other more complex logic on getting/setting, and for future-proofness in case you need to add some of this. –  Mar 13 '11 at 09:13
  • 2
    @delnan indeed, but KeesDijk's answer already pointed to that information so I saw no need to repeat it @Thorbjørn MyConfig is just a simple sample of a class of which all members have as requirement they need to be read from *and* written to within the application, hence needing both getters and setters. Or, if no validation/whatever required, are suitable candidates for making them public and omitting the getters/setters. – stijn Mar 13 '11 at 10:11
  • 2
    @stjin: But if you're condemning X, you should at least mention that there are legimitmate use cases (assmuning there are, of course). Your answer as-is, on its own, is barely better than "you must always write getter/setters", as it implies getters/setter have no reason to exist. Also, the validity of a `struct`-like class is questionable from a pure OOP perspective. –  Mar 13 '11 at 10:20
  • well I admit you're right, should have made it more clear.. I also realize the example is not very well chosen. – stijn Mar 13 '11 at 11:32
  • I agree with @delnan. But, the thing is, I just want quickly write one little variable, then quickly test my program. If everything works fine, then I will refactor the code to have it's respective getters and setters. – Sal Rahman Mar 14 '11 at 07:11
  • Another reason for getter/setter pairs is for unit tests to inject dependencies. Granted, that does not mean that you blindly autogenerate them for every property. – Michael K Feb 08 '12 at 14:27
  • 4
    Don't be so hard on the professors. There are valid educational reasons for enforcing rules that are almost always valid. I'd consider "never make variables public, except if the class/struct is a bundle of related data with no behavior" a good rule. Once the student is experienced enough, he or she will know why the rules are there and when to break them. – David Thornley Feb 08 '12 at 14:54
  • This example is a great illustration of how to not do OOP. It completely kicks [Tell Don't Ask](http://pragprog.com/articles/tell-dont-ask) in the teeth. – back2dos Feb 08 '12 at 15:24
  • @back2dos the question is not about Tell Dont Ask nor about 'Good' OOP. It's about whether all variables should always be private and the core of the answer is no. No the example isn't chosen particularly well but that's obviously not the interest of the OP. – stijn Feb 08 '12 at 15:50
  • 5
    @stijn: This question is *all about* OOP. Asking this question outside the context of OOP is pointless. Your answer comes down to "No, not all fields must have accessors. Look at how this piece of bad code becomes even worse when I add them." Your example is *extremely* bad to start with in a question tagged "best-practices". – back2dos Feb 08 '12 at 16:31
  • I would add a constructor to set the fields instead of setters to solve the issue. We should always avoid the tumble weed pattern which does not enforce the client to construct a valid full object. – java_mouse Apr 11 '12 at 13:45
  • 1
    @back2dos: Not everything should behave as an object. A method to find both the minimum and maximum values within some portion of a `double[]` may take only slightly longer to execute than a method to compute either one of those things, so if code will need both values having a method to compute both in one pass may be helpful. Such a method should, semantically, return an aggregate rather than an object, but Java doesn't have aggregate types; the closest it can come is an object which behaves like an aggregate. IMHO, types which are coded to satisfy code's need for an aggregate... – supercat Dec 31 '14 at 06:00
  • ...shouldn't try to behave like an "object", but rather have fields, each of which represents nothing more nor less than "the last thing stored in this field". All responsibility for the content of the fields should lie with the code which returns the object. – supercat Dec 31 '14 at 06:01
  • @supercat good point. Haven't looked at this question for a while, but now I just realize that what you describe, and what the class in my answer does, i.e. just provide some kind of group of public data fields, is basically already builtin in lots of languages: `tuple` (or even the specialized case for 2 values, `pair`), or in case of Python even `namedtuple`. Especially the latter is semantically and functionally pretty much exactly the same as the class in the answer. This just again shows there's definitely a need for such types. – stijn Dec 31 '14 at 08:59
  • @supercat: Tuples (which I think is a more common name for what you speak of) are *immutable*, which makes guarantees about the integrity of a tuple invariant, thus actually giving the code that creates the compound value the means to statically enforce the responsibility you speak of. The same cannot be said for an object with a bunch of public fields. Notice how even .NET tuples are actually defined with readonly properties for just that reason. So: the use case you are describing has nothing to do with *this* answer and it actually drives home the point contended in the question. – back2dos Dec 31 '14 at 10:09
  • 1
    @back2dos: Mutable aggregates are less common, and have different usage patterns from immutable tuples, but they can be advantageous in some situations. For example, a `MutableMinMaxHolder` with exposed fields `Minimum` and `Maximum` may be usefully employed with a method which, if passed a `MutableMinMaxHolder` along with an array, starting index, count, will update its `Minimum` and `Maximum` fields according to the indicated array elements. If code wishes to find the global minimum and maximum values for a number of distinct array segments, creating one `MutableMinMaxHolder` and... – supercat Jan 01 '15 at 18:58
  • ...passing it to a method which updates it according to array contents may be cleaner and more efficient than having every min/max query operation generate a new tuple for the minimum and maximum, and having to either give each method call the tuple from the previous one, or examine the min/max objects afterward to find the global minimum and maximum. The key point would be that the `MutableMinMaxHolder` would be defined as a mutable container which holds two numbers; any "behaviors" related to those numbers would be entirely the product of client code. – supercat Jan 01 '15 at 19:02
  • 1
    Note that array types in Java and .NET are effectively mutable aggregates which may be assigned arbitrary fixed sizes at instantiation. IMHO Java and .NET should *also* have included immutable array types, but I see no reason to consider a mutable aggregate with a hardcoded size and named members to be any "worse" than arrays, which seem to be non-controversial. – supercat Jan 01 '15 at 19:05
  • @supercat: Blanket statements about efficiency are weak arguments. If there is a hard performance requirement, that can **demonstrably** be met only by adding mutability, then ok. FYI, a modern JIT will be able to stack allocate tuples where it matters. Immutability only makes this kind of optimization easier. Still, my original point is that the example code is very poor to start with. You are not contradicting that. You are also not giving any reason why the mutable records you speak of shouldn't have accessors rather than public fields. Most importantly: we're going quite a bit off topic ;) – back2dos Jan 02 '15 at 11:08
  • @back2dos: The issue isn't just one of performance. Semantically, I think "update a minmax-aggregate to take additional data into account" is cleaner than "assign to this minmax-tuple variable a tuple which reflects a pre-existing tuple along with some additional data". Further, using accessors creates ambiguity about what `mm.setMin(12.0); mm.setMax(10.0);` will do. By contrast, the effect of `mm.min=12.0; mm.max=10.0;` is unambiguous. – supercat Jan 03 '15 at 17:37
  • @back2dos: An aggregate should be designed such that atomically reading out the visible state of an instance whose identity-hash value has never been read, copying that state to a new instance, and replacing *all* references to the original with references to the new instance, would not alter the state of the universe in any observable fashion. There's nothing wrong with aggregates offering "utility" methods, but such methods should simply provide convenient way of doing things which could be done just as well without them. Any abstractly-defined "behavior" should be in client code. – supercat Jan 03 '15 at 17:52
  • @supercat: For somebody who has a point to make, you are writing an awful lot. You haven't yet said anything that is relevant to my criticism to this answer. Or to the question. This question was asked in a C# context, where setters are syntactically transparent. Your semantic comparison is a false dichotomy. You are confounding collections and tuples. You open a side topic on atomicity, which you get for free with immutability, which really only undermines my stance. And so on and so forth. Please stick to this answer and my remarks to it. Because this is going nowhere. – back2dos Jan 04 '15 at 14:57
10

There is a very good reason to use getters and setters in Java instead of having public fields.

The reason is because you should always code to interfaces, and interfaces do not allow specifying fields but only methods.

  • 4
    To quote the accepted answer: "Professors saying "ALWAYS do this or that" in regard to programming should be fired, or go back to school themselves." – Ant Mar 13 '11 at 10:31
  • 3
    @Ant, 1) good I'm not a professor, 2) please note the word "should". Java programmers not knowing why they should be coding to interfaces, are in my opinion unexperienced. –  Mar 13 '11 at 16:05
  • 2
    Stressing *should* makes no difference to the sentence; if you'd said "should *usually*" that'd be different. Java programmers *always* doing things, regardless of the situation, is why the language has such a bad reputation for being a cesspool of bloated crapware. – Ant Mar 13 '11 at 22:35
  • 1
    @Ant, you wouldn't happen to be an inexperienced Java progammer? –  Mar 13 '11 at 22:50
  • [Getters and setters do not always indicate proper object orientation](http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html). Though that very much depends on the language. – mario Mar 14 '11 at 02:14
3

As you put it yourself:

But here's the problem: it's tedious work.[emphasis mine] I tend to quickly loose interest in a project every time I need to have a variable in a class that could have simply been declared public instead of private with a getter and a setter.

You are getting around the tedious work by trying to argue it's necessity out of existence, rather than making it less tedious, which basically means working around the problem instead of solving it. To solve it:

Use the right tools and use them right

If creating plain accessors is too much work, then your current toolset needs improvement.
In fact, any time there is some tedious work, your toolset needs improvement.

For many languages, there's some sort of syntactic sugar available to create accessors or you can use preprocessors for that and most IDEs provide code snippets/code generators. In fact in any decent IDE it is a matter of one keystroke to convert a public field into a private one with accessors.

I could provide a rather lengthy explanation on why using public fields completely violates OOP. At the same time, OOP is not the ultimate truth and it is sometimes better to consciously choose an alternative, if you know what you're doing and the circumstances are right. So yes, there are cases where using plain public fields is ok.
This however is no such case, because you are not making this decision based on any sort of technical constraints, but only because your workflow needs optimization.

back2dos
  • 29,980
  • 3
  • 73
  • 114
  • Given a type which holds nothing but public fields, it is very easy to look at the data structure and know how it will behave. In .net, that is especially true of the data structure is a `struct` and the only heap references contained therein either refer to immutable objects, or else are used semantically to hold the identity of objects rather than their properties. Value-types which mutate `this` in any context other than property setters can cause problems, but since compilers no longer allow stupid code like `SomeList[4].X=6;` value types with exposed fields are safe and useful. – supercat Jul 13 '12 at 21:33
  • @supercat: What's your point exactly? – back2dos Jul 15 '12 at 13:10
  • If a member is declared as a public field, such declaration says that a read or write that member does not now, and will not ever, do anything other than change that member. If one is using an IDE which auto-generates verbose source code for getters/setters, someone using the object would have to look closely at the source code to be certain the getters/setters don't do anything other than read/write the field. Even if one is using a language with "auto-generated" properties, users of the class wouldn't know whether future versions of the class might do something beyond read/write the field. – supercat Jul 16 '12 at 14:59
  • A type like `Rectangle`, which has four exposed fields, poses no mysteries regarding fundamental semantics. If it didn't expose any fields, one would have to examine the code for the type to find out whether e.g. changing the `X` coordinate of a `Rectangle` would leave the width constant, or change the width so as to keep the right edge constant. – supercat Jul 16 '12 at 15:06
  • @supercat: If you make any assumption about how the property X is read/written, then you're breaching the abstraction barrier and thus violating encapsulation. You blur your separation of concerns, and throw your modularity overboard. This is fine, if you want to operate on structs/records in a procedural or functional manner, but it goes totally against OOP, which is all I said. This might be a good choice, but my point was, this is not the choice being made here. The choice here was giving in to laziness or not. – back2dos Jul 16 '12 at 16:04
  • In cases where wrapping something in a property would add value, one shouldn't refrain from doing so merely because of laziness. On the other hand, the advantages of structs with exposed fields as data containers go far beyond the reduction in the number of keystrokes necessary to create them. Exposed-field structs advertise their semantics very clearly and concisely, reducing not only the effort of writing code, but also of reading it (at least by anyone competent enough to know what a struct is). Classes with exposed fields can be a bit murkier, since .net doesn't offer any form of... – supercat Jul 16 '12 at 16:49
  • ...non-promiscuous object reference. It's unfortunate that neither C# nor VB.net offers any means of declaratively creating a named immutable class with named properties, without having to write imperative code for both the constructor and the property getters; even if one had keystroke macros to create such code with minimal effort, someone looking at such code would have to read through every property getter to know be sure the class would behave like an ordinary immutable data holder. – supercat Jul 16 '12 at 16:53
  • Perhaps I should have been clearer: sometimes it is useful to have utility types which are fully describable in at most a few sentences, e.g. "`MutableHolder` is a class type which holds a single exposed mutable field of type `T` named `Value`. It has both a default constructor and one which accepts a parameter of type `T` with which it preloads `Value`." Most types should not have their guts so exposed, but such exposure is good for utility types of that style. A program's "object-orientedness" should not be in the utility "holder" types, but in their consumers. – supercat Jul 17 '12 at 14:54
3

Java, differently from other languages like Ruby, differentiate between direct access to a property and acces to a property through accessors/mutators. Good object-oriented practice says that you should, whenever possible, hide the internal state of an object from the outside. Meaning, the internal representation of the data should not be directly manipulated by external objects. The reason is that you could apply some logic to the value before the action is taked (ie: validate it, cleanup a string, format the return, ...). The problem is that most of people think that "POJO"s should be "as clean as possible", and end up implementing these validations/formattings/cleanup elsewhere, leaving the POJOs dumb and tedious to write.

That said, I recently came accross a library called "lombok", which allows me to write just the properties and it'll generate the getters/setters on-the-fly. If I need to do some extra logic in any accessor/mutator, I just do the actual implementation for it and lombok will ignore that specific method.

jpkroehling
  • 186
  • 3
1

Exposing members whether as public fields or through simple getter and setters goes against the original ideas of OO.

If you are modelling values and not objects there might be reason to model them as values.

Puristically speaking objects are about behaviour any member variable is an implementation detail and no value is part of the behaviour. So if you wish to do puristic OO every time you want to create a setter or getter, you should ask your self questions about your design seeing that the need for getters and setters (when not talking about values as oppossed to objects) is a smell that you are not modelling what the system does (behaviour) but what it is (data). A paradigm that focuses on the separation of these concepts is DCI

Rune FS
  • 314
  • 2
  • 9
  • Smalltalk is **not** "the original ideas of OO." Remember, the original OO language was Simula, not Smalltalk. Smalltalk took the basic concepts of Simula and mixed a bunch of weird, overly-complicated stuff into it until they had something that hardly looked like real OOP at all anymore. There's a reason why the all major OO languages today use the Simula model. (Except for Objective-C, which nobody uses unless Apple's forcing them to, of course.) – Mason Wheeler Feb 08 '12 at 18:49
  • @Mason I wasn't referring to the Smalltalk part but to the Alan Kay part and he sure was part instrumental to the original ideas of OO. It was he, after all, that coined the term – Rune FS Feb 08 '12 at 19:15
0

The point with getters/setters vs. public variables is separation of concerns. Internal variables are an implementation detail of a class and thus should not be seen from outside.

What should be visible from outside is the properties that are handled by the class, and these properties may not have a one-to-one matching with internal variables.

For instance a class may handle a 'temperature' property. An internal variable may be linked to this temperature but users should make no assumption of what represent the value stored in that variable: °C, °F, °K, or even, depending on the sensor, raw measure expressed in: mm, V...

Getters and setters should apply to properties, not internal variables, thus allowing calibration or conversion functions to be included.

That way, class internals may change without updating its interface and all other components depending on that class.

mouviciel
  • 15,473
  • 1
  • 37
  • 64
0

After reading some answers my first point would be that in this context I do not believe should is the same as saying must which is not the same as saying have to, I think you are perhaps over emphasizing always.

  • should implies there this is a generalized consensus that this is a better or more appropriate approach
    • you should always declare your members private
  • must implies that this is the way it is done
    • you must always declare your members private
  • have to implies no other option
    • you have to always declare your members private

Indeed in all three examples (particularly given the circumstance from which this question derived) one would and IMO should (though neither must or have to) query any statement put to them, this is how you program the best computer of all. For example if someone was to say you should always do something despite the fact you know that this time doing so would be detrimental would you do it without questioning their rational?

I imagine in this case your tutor (quite probably for ease) has surmised to you, a better practice which indeed I (and perhaps many others) would agree with. The question I feel should never be why make a member private but in fact the inverse as to why make it public, taking as an example facebook, people clearly like to publicize information about themselves but, even then, maybe just my friends can see this, my family can see that, and you who I don't know can't see anything.

Bringing this back to OOP and in particular Java, one of the main reasons for getters and setters is IMO (and I may be wrong) a case of good semantic practice, you obj.getState() and obj.setState() as opposed to obj.state and obj.state = 'foo', in both cases I would argue the process of doing so is imperative. I'd like to think object orientation is not solely about breaking away from this paradigm but among others encapsulating data and function into a reusable component. If we didn't hide anything do we just end up with some namespace for storing data and methods?

Another key point I believe boils down to overriding, classes inheriting from a super class containing public variables is now stuck with a public variable which to me sounds as though this could lead to a decrease in re-usability. By using getters and setters you have provided a way for sub-classes to override access to your variables, maybe add that bit of validation you never bothered with.

As for it being tedious regarding writing getters and setters this is really null and void as I think most IDE's will do much of this for you (and as I have just found lombok which looks pretty cool and reminds me of @property etc in objective-c)

In short yes you should always use private members unless you have a good reason not to (DTO's would be, to some extent, a reasonable exception)

T I
  • 121
  • 4
  • I also believe other benefits of always using private variables would be when refactoring some fundamental logic that needs to be applied everywhere (you only have to update your getters and setters), and quite possibly benefit concurrency though I am not sure about these two – T I Feb 08 '12 at 16:22
0

Always is a very strong word, and I would avoid it. If its just a matter of the typing thats what keyboard macros are for. Write a small script that will take a java source fill find all the public vars convert them to private and write the getters and setters for you.

I find that it is always a good idea to automate the boring and boiler plate parts of the job. It improves code quality because the dull stuff is done by the computer.

Just remember the following:

  1. Source code is just data

  2. Programs manipulate data

  3. Write a program to manipulate your data in useful ways!

Good luck!

Zachary K
  • 10,433
  • 2
  • 37
  • 55
-2

The reason why you always have to implement getters and setters is because everybody tells you to (sane people call that a Dogma). In the 10 years I program Java, probably 99 percent of the properties I used are publicly available through getters and setters, so in practice they ARE public. We facilitate the exception, instead of the rule.

Michael K
  • 15,539
  • 9
  • 61
  • 93
Pierre
  • 31
  • 1
  • 6
    Hi Pierre could you please tone it down a bit? There is some valuable insight in your answer, but we would prefer all posts to be written in a more... professional tone. – yannis Feb 08 '12 at 14:07
  • 4
    it's a shame that the true parts in this answers is hidden behind slanter and profanity – Rune FS Feb 08 '12 at 14:10