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.

Possible Duplicate:
When are Getters and Setters Justified

In an Object oriented framework, one believes there must be strict encapsulation. Hence, internal variables are not to be exposed to outside applications.

But in many codebases, we see tons of get/set methods which essentially open a formal window to modify internal variables that were originally intended to be strictly prohibited. Isn't it a clear violation of encapsulation? How broadly such a practice is seen and what to do about it?

EDIT:

I have seen some discussions where there are two opinions in extreme: on one hand people believe that because get/set interface is used to modify any parameter, it does qualifies not be violating encapsulation. On the other hand, there are people who believe it is does violate.

Here is my point. Take a case of UDP server, with methods - get_URL(), set_URL(). The URL (to listen to) property is quite a parameter that application needs to be supplied and modified. However, in the same case, if the property like get_byte_buffer_length() and set_byte_buffer_length(), clearly points to values which are quite internal. Won't it imply that it does violate the encapsulation? In fact, even get_byte_buffer_length() which otherwise doesn't modify the object, still misses the point of encapsulation, because, certainly there is an App which knows i have an internal buffer! Tomorrow, if the internal buffer is replaced by something like a *packet_list* the method goes dysfunctional.

Is there a universal yes/no towards get set method? Is there any strong guideline that tell programmers (specially the junior ones) as to when does it violate encapsulation and when does it not?

share|improve this question
add comment

marked as duplicate by Caleb, KeesDijk, Péter Török, Yannis Rizos, Karl Bielefeldt Nov 21 '11 at 15:35

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

6 Answers

No.

Getters and setters don't violate encapsulation, they provide it. If you're using accessor methods, you are by definition not accessing an object's variables directly. You are instead using an interface that the object provides to manipulate some properties, and you don't care whether those properties are stored in ivars, stored in a dictionary, calculated from other values, etc. The implementor of the class in question remains free to change the way the class works without breaking existing client code so long as he or she maintains the interface.

Some say that if your interface consists of little more than a set of accessors for your instance variables, your class isn't doing enough to justify its existence, or you're not doing enough to hide the way the class works from external code. All that may be true, depending on the class, but it doesn't change the fact that access to the internal state (the ivars) is restricted to the class' own methods and therefore encapsulated.

There's obviously some disagreement in the comments below about what the term encapsulation means. I offer the following definition from the paper Encapsulation and Inheritance in Object-Oriented Programming Languages (pdf):

A module is encapsulated if clients are restricted by the definition of the programming language to access the module only via its defined external interface. Encapsulation thus assures designers that compatible changes can be made safely, which facilitates program evolution and maintenance. These benefits are especially important for large systems and long-lived data.

It's hard to argue that accessors don't qualify as "defined external interface" to a class. If you also take steps to prevent external direct access to a class' internal state (that is, make your ivars 'private'), then by the definition above you will have achieved encapsulation.

From a pragmatic viewpoint, though, things aren't exactly that simple. The very next paragraph in the paper goes on to say:

To maximize the advantages of encapsulation, one should minimize the exposure of implementation details in external interfaces. A programming language supports encapsulation to the degree that it allows minimal external interfaces to be defined and enforced.

Like any technique, encapsulation can be used well or not so well, and I think this is at the heart of most differences in opinion about what does or doesn't "break" encapsulation. If hiding the internal representation of data behind an external interface is good, then revealing only what is necessary for the class to do its job is better. A class which has a one-to-one correspondence between property accessors and ivars can properly be said to encapsulate its state, but it may not be using that encapsulation to best effect. I'd agree that if your code contains many classes in this situation, it's a good bet that the system is not as well designed as it could be.

How can you judge whether you're using encapsulation effectively? Continuing from the paper:

This support can be characterized by the kinds of changes that can safely be made to the implementation of a module. For example, one characteristic of an object-oriented language is whether it permits a designer to define a class such that its instance variables can be renamed without affecting clients.

I like this test because it provides a simple guideline that corresponds directly to the reason we value encapsulation in the first place. It also makes clear the idea that the benefit gained from encapsulation is a continuous value, not a binary one. We shouldn't lose sight of the fact that the paper describes encapsulation as a language feature, but I think it's safe to apply the test to specific code to help us decide how well that code uses the encapsulation provided by the language.

Example 1: Applying the "What kind of changes can safely be made?" test to the example in the OP's question, it seems likely that the code probably doesn't make good use of encapsulation. It may be technically true that the get_byte_buffer_length() and set_byte_buffer_length() methods encapsulate some internal state, but if the "byte buffer" is an implementation detail rather than an important external property of the UDP server, the buffer shouldn't be exposed at all. The very fact that it is exposed limits the ways in which the UDP server can be modified.

Example 2: It's often said that inheritance breaks encapsulation because subclasses typically (depending on the language) have direct access to the parent class' internal state. Despite this, programmers can take advantage of encapsulation by using accessors (sometimes private accessors) to access state from a parent class instead of using the ivar itself.

When in doubt, a programmer should ask him or herself: Will my code break if the parent class changes? and Will subclasses of this class break if I change X?

share|improve this answer
9  
Getters provide access to an object's state. By definition they break encapsulation... albeit in a controlled/mediated manner. Setters are even worse. –  Frank Shearar Nov 21 '11 at 8:17
6  
@Frank Shearar: "Getters provide access to an object's state." They do this in a way that is known to provider. And actually if you don't have access to provider's code, how do you know that getters/setters expose actual state? –  Den Nov 21 '11 at 10:15
4  
@Frank -- so if I have a "customer" object "getZipCode" would break encapsulation? Objects are there to perform useful function, if the functional requirement to to provide a ZIP code then a "get" method is the only way to do it. If the functional requirement is to allow the caller to set the ZIP code how else would you implement this other than a "set" method? –  James Anderson Nov 21 '11 at 10:30
3  
@James: "Tell, don't ask." But my point is that getters are not a means of encapsulation, since they expose state. –  Frank Shearar Nov 21 '11 at 10:34
5  
@FrankShearar Accessors turn ivars into properties. I might write a Color class with setters for red, green, and blue. Maybe I have ivars for red, green, and blue, or maybe I don't -- perhaps my class uses a CMYB or HSV color model internally. The client never knows or cares, because the actual state of a Color object is hidden behind an interface. If you don't think that's the definition of encapsulation, I'd be curious to know what you think encapsulation is. –  Caleb Nov 21 '11 at 13:24
show 14 more comments

They can be: As noted in other answers getters/setters by definition provide some encapsulation of the field within the object. There are some pitfalls however. The pseudo code below for instance allows client code to mess about with the internals of the objects of type Foo, because the list 'bars' is a mutable object, so client can do anything to - like clearing it or adding new stuff to. This in my view is a clear violation of encapsulation.

class Foo
{
    private List bars = new List();

    public List GetBars() 
    {
        return bars;
    }
}

To alleviate this either don't provide the getter for bars at all or have it return a readonly copy of the list:

class Foo
{
    private List bars = new List();

    public List GetBars() 
    {
        return bars.AsReadOnly();
    }
}

This problem is not specific to lists, but can turn up with any mutable complex type returned from a getter.

share|improve this answer
add comment

I generally try to avoid public setters - if data needs to be provided to an object it ought to go in via method parameters or the constructor. By setting a property externally you are potentially undermining the integrity of that object.

Encapsulation is more about the semantics of the public API that the object exposes...

Take a simple class with a Name property:

public class Foo
{
    public String Name { get; set; }
}

I would prefer to write this as (given this is a very simple example):

public class Foo
{
    public String Name { get; private set; }

    public void Rename(String name)
    {
        this.Name = name;
    }
}

The goal here is that you're not directly modifying the state of the object from the outside... you're invoking some piece of behaviour, and it's that behaviour which has an observable effect on the objects internal state.

This pattern can be enhanced further with immutability:

public class Foo
{
    // Clone constructor...
    private Foo(foo prototype) { ... }

    public String Name { get; private set; }

    public Foo Rename(String name)
    {
        return new Foo(this)
        {
            Name = name
        };
    }
}
share|improve this answer
3  
+1. The word Integrity is the key! –  Dipan Mehta Nov 21 '11 at 11:31
1  
It's not clear what the difference between allowing someone to call Rename and allowing someone to call a setter on Name is. And you've still got a getter, which the question proposes may also be a violation of encapsulation. –  Random832 Nov 21 '11 at 15:12
    
@Random832 agreed this contrived example does not clearly show the benefit. The difference is in semantics. A method called Rename clearly denotes behaviour. Going back to the basics of OOP, "an object comprises state and behaviour". Behaviour being what you can poke, and state being what you can peek. Get/set properties blur this boundary somewhat. –  MattDavey Nov 21 '11 at 15:25
    
The other advantage of course is that in many languages a setter can't return a value, which would mean my example with immitability wouldn't work.. –  MattDavey Nov 21 '11 at 15:30
    
Well, right, but replacing the first rename method with the second would silently break calling code. Replacing a setter with a method would at least noisily break calling code. –  Random832 Nov 21 '11 at 15:48
show 1 more comment

They can be! The example you provide seems to be a good example where they are. Such methods provide access on a very low level of abstraction, and don't encapsulate the user of the class from the details. That does not mean that a class like this is wrong or bad, it depends on the intended usage.

The Server in your example would IMO be much better take a buffer policy (at construction with a reasonable default, like dynamic buffer) so that it can answer read or send requests without the user caring or even knowing about the details of the buffer management if sHe doesn't want to.

share|improve this answer
add comment

Suppose you have a 'Complex' class. It has four getters: real, imaginary, magnitude, and angle. Clearly, in any reasonable representation, two of these functions simply return the value of a private member variable. What encapsulation means is that it doesn't matter which two of these methods is "simple" and which one does a calculation.

(one could imagine a mutable complex class that also has setters for these. Again, clearly two of them simply directly set a private member variable.)

share|improve this answer
add comment

In my opinion, as long as you allow the property to change from within your class code and using your class code, you are not violating encapsulation.

If you want to prevent change, there are ways to prevent change either at design time (using access modifiers, readonly specification) or at run-time (using business rules).

One of the advantages of using set/get pair is to provide a point in your code to control what happens after/before reading/setting a data value.

we see tons of get/set methods which essentially open a formal window to modify internal variables that were originally intended to be strictly prohibited.

Regarding internal variables (I assume you are taking about fields as in C#), those are always recommended to be declared private whether the property is public, read-only, or otherwise.

This link may add further help: Using a SetProperty method to prevent accidental changes to a property

Edit-1

After reading your edit to the original question

Based on your example, the problem is not with get/set per-se. I think that the implementation of properties that depend on external source of data leads to the dependency problem you are describing. To have a more 'pure' property definition, you should send a message to the object owning this data and let the method return the desired value, then use Set/Get to continue processing.

Encapsulation definition (as in Encpc.Def-About.Com does not imply that the data of a class must all be created in the class or by the class alone. It is OK (and in fact desirable) for classes to communicate or collaborate. This way, you limit the complexity of a class and encourage sharing of code that already exists.

Edit-2

This in response to the first comment for the message. Reading Martin Fowler in this article Getters Eradicator says:

"I have a lot of sympathy with this motivation, but I fear that just telling people to avoid getters is a rather blunt tool. There are too many times when objects do need to collaborate by exchanging data, which leads to genuine needs for getters."

the article is very related to the subject and may answer your question.

share|improve this answer
    
I think you are focusing too much on how to restrict the modification of internal variables. The real issue is that having "tons of get/set methods" not only breaks encapsulation but is also a form of high coupling. Even when having just getters! Why on Earth do your classes have "tons of getters"? What is their main responsibility? It seems like it could easily lead to an anemic domain model, with other parts of the system using your getters to do the actual work! Seems contrary to OOP... –  Andres F. Nov 21 '11 at 15:19
    
Thanks for your comment, I have add a link under Edit-2, that may be of help. –  Emmad Kareem Nov 21 '11 at 18:16
add comment

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