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.

I'm trying to understand if JavaBeans is a good example of encapsulation. In my view, it's not as usually all the internal state is exposed through getters and setters.

A simple example is

public class Test {
    private List<String> names = new ArrayList<String>();

    public List<String> getNames() {
        return names;
    }

    public void setNames(List<String> names) {
        this.names = names;
    }
}

This follows the JavaBeans standard but it leaks the implementation. For example a user could call test.getNames().clear().

Am I missing something?

share|improve this question
    
I prefer to write objects that perform services, messengers to carry data and not expose data at all - or as infrequently as possible. –  Terry Gardner Oct 27 '11 at 14:14

4 Answers 4

up vote 8 down vote accepted

Encapsulation is an overloaded expression, so let's define it first. According to Wikipedia encapsulation refers to two concepts:

In a programming language encapsulation is used to refer to one of two related but distinct notions, and sometimes to the combination thereof:

  1. A language mechanism for restricting access to some of the object's components.

  2. A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.

I would say that your typical JavaBeans class fulfills the second definition but almost never the first, so I guess the JavaBeans standard is not a good example of that particular notion of encapsulation.


Maybe slightly off topic, but explaining why something that starts with class in your code is not necessarily always a class in the more abstract sense. I found a nice definition of class and data structure in Clean Code. Unfortunately I don't have the book here, so I need to recite from the top of my head:

  • A class encapsulates its state, only offering sensible methods and exposing state only where it is necessary.
  • A data structure fully exposes its state, not trying to hide anything from the outside world

A class implemented according to the JavaBeans standard would be a data structure according to the definition above. That maybe explains why it is a class in code but actually not a class that fulfills encapsulation.

share|improve this answer
1  
You have a point there, but there's something in me that doesn't fully agree because I think that Data Structures were part of procedural languages, where logic and data are separated. But in OO these two should be together. I can't think of many scenarios where an object that only contains data (DTOs are one example). –  Augusto Oct 26 '11 at 9:43
2  
@Augusto: the problem is that a lot of people write procedural code in object-oriented languages, because on a low level it's easier and requires less thinking. the JavaBeans standard was originally developed in the context of Swing, and tends to be used much better there (Swing components are often well-desigend JavaBeans). The DTO antipattern bastardization emerged in the context of the old entity EJBs to work around flaws of that technology. Unfortunately, it has spread like wildfire. –  Michael Borgwardt Oct 27 '11 at 9:28

You're right. This is not a good example, and in fact code checkers like e.g. FindBugs will explicitly flag this ("Object exposes implementation by returning a reference to mutable field"). It's not quite as bad as public fields - a getter/setter implementation might one day be replaced by an implementation that does more logic than now, e.g. validation, logging etc., and then clients would receive the benefit of that without being recompiled, but even that won't stop people from relying on the semantics of getNames() being mutable.

A simple, good example of encapsulation is Collections.sort(). Decades of accumulated knowledge about performance and time/space trade-offs, sophisticated algorithms that the majority of programmers ould probably get subtly wrong if they had to write them themselves... and it's all yours for the price of one method call! Strive to emulate sort(), not getNames() in your code.

share|improve this answer

usually all the internal state is exposed through getters and setters.

That may be the most common case, but usually the point of encapsulation is "provide a public interface behind which we can change things as needed" rather than "protect the implementation details like they were your firstborn sitting on a potty made of solid gold".

If it turns out the internal state has to be protected against manipulation, you can easily change the getter to return a defensive copy or a read-only wrapper.

And note that the real point of the JavaBeans standard is that the getter and setter don't necessarily access a private field - they can just as well convert to and from a field in a different format, you can have only a getter for a derived read-only property, or whatever you can imagine.

So I#d say that actually yes, the Java Beans standard is a good example for encapsulation, even though your typical JavaBean may not be.

share|improve this answer
    
You're very right about this. I think your answer touches the point that JavaBeans should encapsulate the internal state, but most implementations or tools do not do this. I think @sebastiangeiger has a point too, that JavaBeans are usually used as data structures rather than objects. –  Augusto Oct 27 '11 at 9:11

JavaBeans do not have any business being mentioned in the context of object oriented concepts such as encapsulation.

Encapsulation refers to the containment of functionality behind an api - in object oriented languages, the api is typically provided by a class through its public members. Encapsulation allows you to easily re-use functionality without causing undo binding because, again, the functionality is accessed through an api - never directly.

As someone mentioned above, an object by definition is when data and the code that operate on it are in the same class. In 99.9% of the cases I have seen JavaBeans being used (which unfortunately is everywhere), they do not contain any functionality other than setters and getters. Setters and getters are not application level functionality - i.e. you aren't going to cause an invoice to be saved by calling a setter or a getter, therefore beans are not objects.

Beans are structs, which are data only structures used in structured and procedural programming. They were state of the art in the late 80's, early 90's, using just about every language available at the time, the most popular being C.

Using beans will make your programs much larger and far less flexible than, for example, using collections in appropriate places. Everyone I discuss this with scoffs at this notion, but if I am not mistaken, compiled java classes, under the hood, are basically collections of collections. These collections are what reflection trolls through to get you information about the class. They are what the runtime looks through to find the correct method to run for a given class.

A bean is, without a doubt, about as automation unfriendly as you can get - they are utterly inflexible, and will grow your code base far beyond the functionality it contains.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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