0

For what I know, encapsulation is useful because:

  1. if you use directly an attribute and change its type in a static typed language you have to change all the code that uses the class. On the contrary, if you have declared getters and setters for that attribute you have not to do this
  2. it hides the internal functioning of your class, useful if, for example, you're offering an API
  3. it avoids that another class that inherits your class will overwrite attributes or methods

My considerations about dynamic typed, interpreted programming language are:

  1. since the types are dynamic there's no need to encapsulate your class for this reason
  2. you can see the code of an interpreted language, so I think there's not a way to really hide your API
  3. this could be a problem when this is unintended, but my opinion is that it should be better to make attention to unintended overwriting instead of limiting by default this possibility. Python is a good example: if you declare for example, the name of an attribute or method starting it with a double underscore, you can declare it also in a inherited class, but they are threated as two distinct variables even if they have the same name (thank you delnan)

a method name that starts with a "_" character raises a warning if overwritten by a method of an inheriting class.

Am I missing something important?

15
  • 2
    Encapsulation is a very broad term that covers much more than only getters and setters. I think you are extremely underestimating how useful it can be.
    – Asaf
    CommentedMay 31, 2013 at 13:27
  • This is unrelated to the question, but your Python example in 3. confuses me. I've never heard of such a feature in past, present or future versions. A leading _ is a convention and nothing special. A leading __ (double underscore) invokes name mangling, but that doesn't cause a warning when overriding, it's just a hack that makes accidental overwriting much less likely by incorporating the class name into the attribute name.
    – user7043
    CommentedMay 31, 2013 at 14:28
  • @Asaf: I know only getters and setters, can you give me an example?CommentedMay 31, 2013 at 14:31
  • @delnan: excuse me, you're right. I've read it somewhere, but it's wrong, since the single underscore attributes and methods are simply not imported by from mypackage import *. On the contrary methods and attributes that start with a double underscore are in a sort of "class namespace". Read stackoverflow.com/questions/70528/… and docs.python.org/3/tutorial/classes.htmlCommentedMay 31, 2013 at 14:45
  • The question is very badly written and logically flawed.CommentedMay 31, 2013 at 14:46

2 Answers 2

21

Yes, you are missing something.

Encapsulation is often described with metaphors of "hiding" or acting "defensive", as if client programmers were your enemy and you had to act stealthily and sneakily to defend yourself against their evil intentions. That is sometimes helpful; for instance, if you program extremely popular frameworks that have to maintain compatibility across a huge number of situations and versions, you start to think of your users as ignorant barbarians whose only intent in life is to cause you trouble with their unreasonable demands of "But it used to work!" or "But I can see that it's an array internally! Why, why, why won't you let me access the elements directly??"

However, the normal case is that the layer using your code is programmed by the same person as your own layer: yourself. Therefore point is not actually to hide information from other routines and their creators, but to free its caller from having to understand it. The trick is to make it possible to write higher-up routines without knowing about the details. The cognitive delusion that if you created something yourself, you are obviously going to understand everything it does is extremely common and extremely strong; large parts of software engineering are dedicated to mitigating the consequences of this error of thought. If you program a subroutine, but you need to know how it works internally in order to use it properly, then you might as well not have a subroutine, because the mental effort necessary isn't actually reduced: the code looks clean and modular, but actually isn't.

This is why we separate big amounts of code into small partitions: because a small amount of code is easier to understand than a large amount, and crucially, two properly decoupled small bits of code are easier to understand than one bit twice the size, because interdependencies within the larger bit add cognitive effort. If we don't avoid that extra effort, sooner or later it will exceed our capability to understand the entire system, and it soon becomes unmaintainable.

5
  • About the first part: okay, but if I've written my framework with a interpreted language, the client programmer can see and change the code, so (s)he can turn an attribute or method from private to public, no? About the second part, I'm not sure if I've understood what you mean, can you give me an example?CommentedMay 31, 2013 at 15:03
  • 3
    The client programmer can always get to your code. In Java, they can use reflection to make private things public. In C, they can disassemble the machine opcodes to find out what you actually did. The point is not to prevent people from getting at the details of your work. The point is to enable them to do their work without having to.CommentedMay 31, 2013 at 15:05
  • But this can't be done simply documenting the class? I mean, if I simply write do not touch this ^^ (or I start my identifier with an underscore as Pythonists do), it's not more simple that making the attribute private?CommentedMay 31, 2013 at 15:33
  • 2
    I'm afraid I haven't gotten through. Knowing that a field exists and that you should not touch it is worse than not knowing about the field - if only because it makes reasoning about the entire class harder. We think "Oh, it's OK, I can just ignore that field then", but we can't - not without draining a tiny bit of mental energy. I've been programming for 20 years, so I ought to know better, but even I catch myself thinking, "Oh well, I'll just ignore that bit of information..." even though I really should know better. This is why it's better not to entice people to delude themselves.CommentedMay 31, 2013 at 15:43
  • It's all about minimizing complexity of interactions. 1+CommentedJun 2, 2013 at 1:12
2

You are forgetting two things.

First, encapsulation is first and foremost about keeping the amount of coupling between your modules low in a structured way, i.o.w., keeping your code modular. Proper encapsulation separates interfaces from implementations, and being able to change internal workings without touching the interface goes much further than simple getters/setters, and covers more than just return types. Take, for example, a rectangle. There are two possible representations: (left, top, right, bottom), or (left, top, width, height). Neither is better, but either may be more suitable for certain situations. If you make getters/setters for all six properties (left, right, top, bottom, width, height), you can change the internal representation in 5 minutes, without touching any other code.

A more important reason, though, is that encapsulation limits the scope of fields and methods. This means that when you want to change a private field, you only have to take its containing class into account; if it's public, you have to check the entire codebase for possible regressions. By extension, reasoning about properly encapsulated code is easier than code where everything is openly accessible from anywhere.

5
  • I don't understand your example... I can do what you described without the need of making attributes private and using setters. I can make public them all and the result is the same. About the second part, read my 3th comment to the Kilian Foth's answer.CommentedMay 31, 2013 at 15:58
  • @LucasMalor: You can put validation logic in a setter and, e.g., throw an exception each time an attempt is made to set an attribute to an invalid value. Making the attribute public allows any piece of code that gets hold of an object of that class to set the attribute to an invalid value.
    – Giorgio
    CommentedMay 31, 2013 at 18:45
  • @Giorgio: +1, I think this is a very good reason to use encapsulation, in particular if the language has weak typing :)CommentedMay 31, 2013 at 19:14
  • @LucasMalor: In my example, once you have decided to use width and height, and you expose them publicly, you can't easily remove them in favor of a left/right/top/bottom implementation (unless the language has getter/setter syntax that is identical to field access syntax, such as C#).
    – tdammers
    CommentedJun 1, 2013 at 6:13
  • Ok, now I've understood what you mean. Can you update your answer using your last comment, and citing also Giorgio's comment? :)CommentedJun 1, 2013 at 8:08

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.