Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Getters and setters are often criticized as being not proper OO. On the other hand most OO code I've seen has extensive getters and setters.

When are getters and setters justified? Do you try to avoid using them? Are they overused in general?

If your favorite language has properties (mine does) then such things are also considered getters and setters for this question. They are same thing from an OO methodology perspective. They just have nicer syntax.

Sources for Getter/Setter Criticism (some taken from comments to give them better visibility):

To state the criticism simply: Getters and Setters allow you to manipulate the internal state of objects from outside of the object. This violates encapsulation. Only the object itself should care about its internal state.

And an example Procedural version of code.

struct Fridge
{
    int cheese;
}

void go_shopping(Fridge fridge)
{
     fridge.cheese += 5;
}

Mutator version of code:

class Fridge
{
     int cheese;

     void set_cheese(int _cheese) { cheese = _cheese; }
     int get_cheese() { return cheese; }
 }

void go_shopping(Fridge fridge)
{
     fridge.set_cheese(fridge.get_cheese() + 5);        
}

The getters and setters made the code much more complicated without affording proper encapsulation. Because the internal state is accessible to other objects we don't gain a whole lot by adding these getters and setters.

The question has been previously discussed on Stack Overflow:

share|improve this question
15  
Getters and setters are often criticized as being not proper OO - Citation, please. –  Robert Harvey Nov 26 '10 at 22:43
18  
3  
This is a SO question. –  Job Nov 26 '10 at 23:50
20  
@Job, why because it has code? It's a good question and reeks of holy war if taken seriously. –  Peter Turner Nov 26 '10 at 23:55
2  
+1 I was wondering exactly the same hing yesterday –  stijn Nov 27 '10 at 8:57

14 Answers 14

up vote 81 down vote accepted

Having getters and setters does not in itself break encapsulation. What does break encapsulation is having a getter and a setter for every data member (every field, in java lingo). That is one step away from making all data members public.

The point of encapsulation is not that you should not be able to know or to change the object's state from outside the object, but that you should have a reasonable policy for doing it.

Consider an example of a class Person. Let's say a person has a name, a social security number, and an age. Let's say that we do not allow people to ever change their names or social security numbers. However, the person's age should be incremented by 1 every year. In this case, you would provide a constructor that would initialize the name and the SSN to the given values, and which would initialize the age to 0. You would also provide a method incrementAge(), which would increase the age by 1. You would also provide getters for all three. No setters are required in this case.

In this design you allow the state of the object to be inspected from outside the class, and you allow it to be changed from outside the class. However, you do not allow the state to be changed arbitrarily. There is a policy, which effectively states that the name and the SSN cannot be changed at all, and that the age can be incremented by 1 year at a time.

Now let's say a person also has a salary. And people can change jobs at will, which means their salary will also change. To model this situation we have no other way but to provide a setSalary() method! Allowing the salary to be changed at will is a perfectly reasonable policy in this case.

By the way, in your example, I would give the class Fridge the putCheese() and takeCheese() methods, instead of get_cheese() and set_cheese(). Then you would still have encapsulation.

share|improve this answer
3  
Please don't take my Fridge example too seriously. :) A real fridge ought to be a container object, I'd expect it to know how to hold objects without worrying about what exactly they were. I.E. it would be like an ArrayList. As for what makes it a Fridge, let's say it serializes objects to disk when stored so that they will survive system failure. Ok. Enough taking my fridge example over seriously. –  Winston Ewert Nov 26 '10 at 23:40
4  
But shouldn't the fridge know the expiration dates, so that it can tell you that the cheese has gone bad and should be thrown out? :) Ok, we have to stop this! :) –  Dima Nov 27 '10 at 0:10
6  
Quite an interesting discussion of Fridge Logic you've got going on here... –  Mason Wheeler Nov 27 '10 at 6:27
18  
Haha, I'd like to see the ad for that: "It's a brand new kind of fridge: It throws things at you when trying to grab something that isn't there! This way you will only try that once! You worry about stuffing the fridge, and let the fridge worry about illegal behaviour!" –  gablin Nov 27 '10 at 9:13
3  
+1 This explanantion is better than any I found in books. –  Oliver Weiler Apr 11 '11 at 7:40

The basic reason for getters and setters in Java is very simple:

  • You can only specify methods, not fields, in an interface.

Hence, if you want to allow a field to pass across the interface, you will need a reader and a writer method. These are traditionally called getX and setX for the field x.

share|improve this answer
18  
That is a language limitation. The real question is whether we should be allowing other objects to manipulate that state. –  Winston Ewert Nov 26 '10 at 23:05
2  
@Peter Turner, clearly nothing prevents a language from having interfaces that include properties. Under the covers that may well be implemented as getter/setter but it would be easy enough to add support to interface definitions for properties. –  Winston Ewert Nov 26 '10 at 23:54
2  
@Winston, you will eventually need to allow classes to pass information back and forth between each other to actually get work done. What would you suggest instead? –  user1249 Nov 27 '10 at 6:38
3  
An object is supposed to provide a higher level interface to it innards. Getters and Setters tend to be a low level interface. For example, suppose you have a class that implements a binary tree. You could have functions like GetLeft(), GetRight(), GetValue(), and GetKey() in order to navigate the tree. But that is the completely wrong approach. Your binary tree class should provide operations like Find, Insert, Delete. –  Winston Ewert Nov 27 '10 at 14:51
3  
To take another example, consider a tetris piece. The tetris piece has some internal state like block_type, rotation, position. You could have getters like GetBlockType(), GetRotation(), GetPosition(). But you really shouldn't. What you should have is a GetSquares() method which returns a list of all of the squares occupied by this piece. You also shouldn't have stuff like SetPosition() or SetRotation(). Instead, you should have operations like MoveLeft(), MoveRight(), Rotate(), Fall(). –  Winston Ewert Nov 27 '10 at 14:55

As a general rule, getters and setters are a bad idea. If a field isn't logically part of the interface and you make it private, that's fine. If it is logically part of the interface and you make it public, that's fine. But if you make it private and then turn around and make it effectively public again by providing a getter and setter, you're back to where you started except your code is now more verbose and obfuscated.

Obviously, there are exceptions. In Java, you might need to use interfaces. The Java standard library has backward compatibility requirements so extreme as to outweigh normal measures of code quality. It's even possible that you may actually be dealing with the legendary but rare case where there's a good chance you may later replace a stored field with on the fly calculation without otherwise breaking the interface. But these are exceptions. Getters and setters are an anti-pattern that needs special justification.

share|improve this answer
2  
A getter and setter mean that the attribute, not the field, is part of the interface. Suppose getBirthDate() and SetBirthDate() take "yyyy/mm/dd" but the field stored is the number of days since 01/01/1000. You can change that to 01/01/0001 and the getter and setter will keep the interface the same. Especially because 'public' means publically trashable, variables should never be public; always use a setter to validate the incoming value, update any related fields, convert as needed, etc. Try to use a getter in case the internal storage changes. –  Andy Canfield Oct 4 '11 at 7:35

From http://www.adam-bien.com/roller/abien/entry/encapsulation_violation_with_getters_and

JavaBean style:

connection.setUser("dukie");
connection.setPwd("duke");
connection.initialize();

OO-style:

connection.connect("dukie","duke");

Well, clearly I prefer the latter approach; it doesn't bleed implementation details, it's simpler and more concise, and all of the needed information is included with the method call, so it's easier to get it right. I also prefer setting private members using parameters in the constructor, whenever possible.

Your question is, when is a getter/setter justified? Perhaps when a mode change is needed, or you need to interrogate an object for some information.

myObject.GetStatus();
myObject.SomeCapabilitySwitch = true;

In thinking about it, when I first started coding in C#, I wrote a lot of code in the Javabeans style illustrated above. But as I gained experience in the language, I began doing more setting of members in the constructor, and using methods that looked more like the above OO style.

share|improve this answer
3  
Why is the "give all arguments as parameters" OO-style? –  user1249 Nov 27 '10 at 6:39
2  
While your "OO-style" is fine for 2 or 3 options, I would prefer JavaBean style once you get above that. Having 20 overloaded methods for every possible combination of parameters just looks terrible –  TheLQ Nov 27 '10 at 19:38
1  
@TheLQ: C# 4.0 makes this easier by allowing optional and named parameters in constructor and method calls. –  Robert Harvey Nov 27 '10 at 22:40
2  
@TheLQ That's what Builder with fluent syntax is for, see e.g. Guava's MapMaker. –  maaartinus Aug 6 '11 at 16:35
    
I've recently been looking into chained functions like those used in jQuery for cases where there are more than 5 options. I'm not sure how well it fits into OO programming though... –  Ivan Oct 3 '11 at 15:58

whether field is accesible directly or via method is not realy important.

Class invariants (usefull ones) is important. And to preserve them, we sometimes need to not be able to change something from outside. Eg. if we have class Square with separete width and height, changing one of them makes it become something else than square. So we need method changeSide If it was Rectangle, we could have setters/public field. But setter than would test whether its greater than zero would be better.

And in concrete languages (eg. java) are reasons why we need those methods (interfaces). And another reason for method is compatibility (source and binary). So its easier to add them then think whether public field would suffice.

btw. I like to use simple immutable value holding classes with public final fields.

share|improve this answer

You may want to change your internals to whatever while keeping the interfaces the same. If your interfaces don't vary, them you code won't break. You still can change your internals as you wish.

share|improve this answer

My approach is this -

When I expect to diddle with the data later on, a getter/setter is justified. Also, if change is happening, I often push the data into a getter/setter.

If it's a POD structure, I leave the slots available.

On a more abstract level, the question is "who manages the data", and that depends on the project.

share|improve this answer

Firstly there are broadly two types of objects which i will comment on, value and service types.

Service types should never have setters, whatever dependencies they require should not be gettable. THe best way to pass dependencies is via a constructor or factory that way all instances are fully formed from the beginning, plain and simple.

Value types should also be immutable, on the oher hand there are times when this is not practical such as an ORM, or some other mapping such as from a widget to an object. All other value types that get passed around the system from one layer or part to another should be immutable and should not have setters.

share|improve this answer

If using getters and setters feels complicated, the problem might be the language, not the concept itself.

Here's the code from the second example written in Ruby:

class Fridge
  attr_accessor :cheese
end

def go_shopping fridge
  fridge.cheese += 5
end

Notice it looks a lot like the first example in Java? When getters and setters are treated as first class citizens, they're not a chore to use, and the added flexibility can sometimes be a real boon - for example, we could decide to return a default value for cheese on a new fridge:

class Fridge
  attr_accessor :cheese

  def cheese
    @cheese || 0
  end
end

Of course there will be many variables that shouldn't be exposed publicly at all. Needlessly exposing internal variables will make your code worse, but you can hardly blame that on getters and setters.

share|improve this answer

A Getter/Setter is justified just like any other public method is justified. The justification is mainly because we want to provide an interface to the outside world that defines how our class interacts with other classes. We do this mainly because we want to reduce coupling between separate entities. Reduce coupling is a good thing for many reasons:

  • I can use from my current code the same class interface although meantime that class added new methods (but preserved the old interface)
  • Can change the internal representation of a class without affecting it's consumers
  • Reduce the chance of bugs: if you make your internal data private you can know for sure that external code won't mess with your internal data
share|improve this answer

If getters and setters violate encapsulation and true OO than I'm seriously in trouble.

I always felt an object represents what ever best comes to mind you need it to function as.

I just finished writing a program that generates Mazes in Java, I have class that represents "Maze Squares". I have data in this class that represents coordinates, walls and booleans ect.

I have to have some way to change/manipulate/access this data! What do I do without getters and setters? Java doesn't use properties and setting all my data that is local to this class to public is DEFINITELY a violation of encapsulation and OO.

share|improve this answer
5  
Here is the question: If you made all those fields public, and stopped using the getters and setters how would your code be different? –  Winston Ewert Nov 27 '10 at 15:10
    
In theory, its not. Why even make a class at that point? Same argument could be made with anything. But the post below mine seems to have said it more elegantly. (Getters and setters are a way to safely hand a value to an object, or retrieve a value from that object.) The post goes on.. –  Bryan Harrington Nov 27 '10 at 15:14
2  
I'd point out: that poster eventually agreed with me and posted another answer to that effect. Essentially, using getters and setters is the same as manipulating the data directly. You don't really gain OOness by doing that. In order to be OO you ought to provide a higher level interface to the data. –  Winston Ewert Nov 27 '10 at 15:29
3  
I think the best way of describing it would be to say that you should design your interfaces from the outside in, not the inside out. The interface your object provides should be dictated by how the object is used not how it is implemented. So don't write getters and allow external object to interpret the data. Find out what question they need answered, and write a method that answers that question. Don't allow external objects to modify state by a setter, find out what kind of manipulations they need to perform and write methods that do that. –  Winston Ewert Nov 27 '10 at 15:31
1  
In some cases, Getters and Setters are the best method. Sometimes they are the best interface you can provide. However, in many cases they are not. In many cases, you are just leaking implementation details into other classes. –  Winston Ewert Nov 27 '10 at 15:32

Consider a Size class which encapsulates width and height. I can eliminate setters by using the constructor but how does that help me draw a rectangle with Size? Width and height are not internal data to the class; they're shared data that must be available to the consumers of Size.

Objects consist of behaviors and state - or attributes. If there is no exposed state then only behaviors are public.

Without state, how would you sort a collection of objects? How would you search for a specific instance of an object? If you only use constructors, what happens when your object has a long list of attributes?

No method parameter should ever be consumed without validation. Therefore it is laziness to write:

setMyField(int myField){
    this.myField = myField;
}

If you do write it that way then you have at least prepared for using the setter for validation; it's better than a public field - but just barely. But at least you have a consistent public interface that you can come back and put in validation rules without breaking the code of your customers.

Getters, setters, properties, mutators, call them what you will, but they're necessary.

share|improve this answer

I'd hope that anything that the IDE developed by the company that develops your programming language auto generates doesn't violate the "Principles of Object Orientation".

That being said, any time you've got a public scoped variable, use a getter and a setter and you're golden. Seems to me to be the necessary element of the extremely object oriented principle of encapsulation - even if it just looks like a lot of junky code.

The reason to use them is that the proper encapsulation may yet take place and so long as you've abstracted away the layer that lets the person monkeying with your object feel your object, you can take that object away without him even knowing right?

Suffice it to say, a house divided cannot stand, one of the tenants of OO isn't going to turn on itself and you can't serve both encapsulation and premature optimization.

share|improve this answer
    
BTW. Favorite Language = Delphi –  Peter Turner Nov 26 '10 at 23:22
4  
and what exactly did I gain by adding lots of code to call setFoo() and getFoo() everytime I deal with the variable? –  Winston Ewert Nov 26 '10 at 23:29
7  
Here is the thing, I don't think you get encapsulation. You are still manipulating the state of the object from other places. You are just doing it more verbosely. To gain encapsulation, you need to centralize manipulation of values in the class that owns that value. Anything else is just procedural code in OO clothing. (Nothing necessarily wrong with that, but it is what it is). –  Winston Ewert Nov 26 '10 at 23:58
1  
The advantage of encapsulation is that all the logic related to particular values is in one place (more or less). I don't get that with getters and setters. Hence, I don't think I get a lot of benefit for them. –  Winston Ewert Nov 26 '10 at 23:59
2  
I'm certainly not a fan of verbosity. But my objection is really people who make their variables private and then call getters and setters on them freely ending up with pretty much no difference. If you want to use getters/setters within your class that's fine. The question is why? The primary benefit I'm aware of there is that you can do some validation on the data to catch errors earlier. This is less helpful when all the code manipulating the data is in the same place. But it can still be helpful. Ideally, you have a language that supports properties and can avoid the verbosity. –  Winston Ewert Nov 27 '10 at 1:12

I thought we would have more usual answers here?

Getters and setters are in general extremely OOP (anyone saying anything else are wrong, simple as that).

Though you need to remember to not over engineer, never make an getter or setter that isn't needed. Any information that you aren't going to use by another class you shouldn't have any getter or setter for.

Though, the reason why you don't make fields public and instead have getters and setters are mostly:

  • It's not possible to make proper tests by using fields. Getters/setters are much better in that regard.

  • It's impossible to properly use fields in a real time programming setting. Synchronized getters/setters is the way to go.

  • The interface topic (already explained so I won't).

  • It's easier to use when properly reusing the system.

  • It's much harder to know which classes that's using your class and what will break if you change a field than a getter/setter.

Therefor the only time you use a public field instead of an getter/setter is when you don't make an official project but instead just doing it for fun and can't bother with the getter/setters.

share|improve this answer
2  
+1 for testability. Shocked that nobody mentioned it earlier. Another useful feature of properties is debugging them. (much easier to insert a breakpoint in the code than require hardware/memory breakpoints for fields). –  Mark H Nov 27 '10 at 18:29
7  
The objection to getters and setters is that they are often used to follow the letter of OOP law while ignoring the spirit and intent. OOP says that you shouldn't allow other objects to muck with your internals. If you define getters and setters that let you do that anyways, you end up violating OOP. –  Winston Ewert Nov 27 '10 at 19:23
5  
I'll agree that there are many benefits of getters and setters over simple public fields. However, I'm not clear how testing is better with them. Could you explain? –  Winston Ewert Nov 27 '10 at 19:24
2  
@Skarion: I don't agree with your answer. You seem to be presenting two alternatives: either using getters/setters or making fields public. But there is a third option: using neither getters/setters nor exposing fields! Why would you need to test for the state of an internal field? Shouldn't you be testing your object's public API? –  Andres F. Nov 21 '11 at 15:31

protected by World Engineer Nov 22 '13 at 21:55

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.