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

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,968
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,168
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.

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
  • 30,140
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
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,491
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
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,413
-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,659
Pierre
  • 31