0

After going through SO questions, I learnt that,

Encapsulation is about protecting invariants and hiding implementation details.

Abstraction has to do with separating interface from implementation.

From class room java training, I learnt that, Encapsulation has following advantages,

Why encapsulation is your friend?

[1] The implementation is independent of the functionality. A programmer who has the documentation of the interface can implement a new version of the module or ADT independently. A new, better implementation can replace an old one.

[2] Encapsulation prevents Doug from writing applications that corrupt a module’s internal data. In real-world programming, encapsulation reduces debugging time. A lot.

[3] ADTs can guarantee that their invariants are preserved.

[4] Teamwork. Once you’ve rigorously defined interfaces between modules, each programmer can independently implement a module without having access to the other modules. A large, complex programming project can be broken up into dozens of pieces.

[5] Documentation and maintainability. By defining an unambiguous interface, you make it easier for other programmers to fix bugs that arise years after you’ve left the company. Many bugs are a result of unforeseen interactions between modules. If there’s a clear specification of each interface and each module’s behavior, bugs are easier to trace.

[6] When your Project doesn’t work, it will be easier to figure out which teammate to blame.

Question 1:

Wrt Point1(above) says, "A new, better implementation can replace an old one.". This is the goal of abstraction but not encapsulation. Am I correct?

Question 2:

Wrt Point 4(above), How Encapsulation help programmer to independently implement module without having access to other modules? How does parallel implementation of modules has anything to do with Encapsulation? Because Encapsulation is about protecting in-variants. This answer also supports my argument

Community
  • 1
  • 1
overexchange
  • 15,768
  • 30
  • 152
  • 347
  • 1
    "interface" is the contract between components. Each side only has to work to the contract without needing to know about the details of the implementation, thus the developers can work in parallel as they don't need to know about each others, possibly incomplete implementations. – Peter Lawrey Aug 02 '15 at 08:29
  • @PeterLawrey But your point has something to do with *Abstraction* but not *Encapsulation*.Because *Abstraction* has to do with separating interface(`java.util.List` or `java.util.AbstractList`) from implementation(`java.util.ArrayList`). – overexchange Aug 02 '15 at 08:39
  • 1
    The key feature for encapsulation is shared contract designed to hide implementation details. Abstraction makes this easier but is not required. – Peter Lawrey Aug 02 '15 at 08:42
  • 1
    Encapsulation is hiding implementation details. Abstraction is defining common behaviour for multiple implementations. They are related but encapsulation doesn't require abstraction. e.g. `class A { private int _x; public long getX() { return _x; } }` I have used encapsulation as you can't see how I actually implemented `getX` but there is no abstraction. – Peter Lawrey Aug 02 '15 at 08:48
  • 1
    Using collections as an example, ArrayList.ensureCapacity(n) encapsulates the implementation of this method, you don't need to know how it is implemented, but it doesn't override a method in an interfaces, i.e. there is no abstraction involved. – Peter Lawrey Aug 02 '15 at 08:50
  • 1
    @PeterLawrey So, method `add` & `remove` from `java.util.ArrayList` is an example of *abstraction* **&** *Encapsulation*. It is *Abstraction* **&** *Encapsulation*, because `add` & `remove` are overridden from interface `java.util.AbstractList` as well as hide implementation details respectively. Is my understanding correct? – overexchange Aug 03 '15 at 04:25
  • Correct. I am trying to think of an example of abstraction which breaks encapsulation. ... you could argue this is partially true of Map.putIfAbsent() as the Java doc for the interface includes the implementation. – Peter Lawrey Aug 03 '15 at 17:18
  • @PeterLawrey Please read this [answer](http://stackoverflow.com/a/14252265/3317808) which discuss similar topic. This answer does not support the argument that encapsulation supports parallel implementation. – overexchange Aug 23 '15 at 12:10
  • The way I read it, it does support this view. It notes that parallel development is a side effect and how it becomes more important as the project gets larger. – Peter Lawrey Aug 23 '15 at 12:13
  • @PeterLawrey I think this point, *Encapsulation, conceptually, exists for writing better, safer, less error-prone code.* would suffice to avoid confusion by reading that answer. It is not relevant, what side effect is, It is important to know what the primary purpose of Encapsulation: as the answer says: "*It doesn't exist, primarily, to facilitate teams working together on code*". So, the discussion made by berkeley class room training is baseless. – overexchange Aug 23 '15 at 12:15
  • If you are starting from an abstract, academic view I agree. If you are starting from a practical view the problem is; how to you scale a project as it gets more complex and you have more developers? One of the way is to; make sure you make good use of encapsulation because it helps write better safer, less error prone code. – Peter Lawrey Aug 23 '15 at 12:19
  • @PeterLawrey Team of one developer must also follow encapsulation, as you said encapsulation has something to do with writing less error prone code. We write less error prone code by fixing and following invariants. – overexchange Aug 23 '15 at 12:20
  • Encapsulation comes with an overhead. Why pay the overhead if it has little benefit? It is good practice to do in places, but many one person development projects have very poor encapsulation and yet are successful. – Peter Lawrey Aug 23 '15 at 12:23
  • @PeterLawrey Please go thru my [query](http://programmers.stackexchange.com/questions/293260/encapsulation-vs-performance-trade-off-in-a-lockable-linked-list) on fixing the breakage of encapsulation. You have a complete code to access. Nothing academic here. – overexchange Aug 23 '15 at 12:27
  • Can you discuss how it relates to your assertion that "It doesn't exist, primarily, to facilitate teams working together on code" How are the members of your team working on this class together? – Peter Lawrey Aug 23 '15 at 13:46

2 Answers2

0

(1) Interface should be interpreted broadly; because it has some specific technical meanings, I tend to prefer the term contract (from "design by contract") to mean the same thing. It's the formal specification of how to interact with a particular module (or kind of module). An excellent example is the Collections API; a List is most often an ArrayList, but it can be a LinkedList, an ImmutableList, or something more exotic like a lazy-load database proxy. I almost never care in my code which specific type it is; I just interact with the List interface.

(2) If actual Java interfaces (or the equivalent) are used, it's very easy to create mock or scaffold versions of a component to be used while it's under development. For example, I just implemented a system that sends e-mail. While I was getting the rest of the system ready to actually issue the orders to send, I used a fake mail service that just wrote log messages pretending to send the mail. That way, I could test that the parts of my system that were supposed to invoke the mail service worked correctly independently of actually sending mail.

On a much larger scale, I use Spring MVC to handle the Web tier of my applications. Spring MVC interacts with the Servlet API to interface with a servlet container, which is essentially the Web server itself. The Spring team doesn't need to know anything else about the server; several different servlet containers (Tomcat, Jetty, Undertow, WebLogic) have been written by different teams, but since everyone is using a common interface, they don't have to do any further coordination of their development efforts.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
  • fake mail service using java stubs? – overexchange Aug 02 '15 at 08:25
  • @overexchange The action is faked (or "mocked"); it's not a fake mail service as there is no service. See [Dependency Injection](https://github.com/castleproject/Windsor/blob/master/docs/services-and-components.md) for a 'practical' outcome of Encapsulation - the encapsulation allows the separation of Components and Services. – user2864740 Aug 02 '15 at 08:26
  • My `MailService` interface has a `send` method. The *real* service sends mail. The *fake* service just writes a log message saying "I would send this message to this person here." In a larger project, I could be working on my part of the application that needs to send mail while someone else actually got the sending part working. – chrylis -cautiouslyoptimistic- Aug 02 '15 at 08:26
  • *Point 1 in your answer*, You said, *I just interact with the List interface.* This is nothing but *abstraction*. Where is *encapsulation* here? *Point 2 in your answer* that is something to do with testing aspect by writing java stubs(for ex: log msgs) in java world. – overexchange Aug 02 '15 at 08:29
  • @overexchange Abstraction and encapsulation here are essentially the same thing. *Because* `List` is abstracted, I don't interact with the internal state of the implementation at all. `ArrayList` uses arrays and index counters; `LinkedList` uses nodes. I don't care, and I never see them. All I see is what `List` shows me. If the developers want to rework the internals somehow, my code won't care. – chrylis -cautiouslyoptimistic- Aug 02 '15 at 08:31
  • Using interfaces certainly helps with testing as well, but in my case we were actually running the software and interacting with it using the mocked service. The line between "testing" and verifying that it works in the real world is quite blurry. – chrylis -cautiouslyoptimistic- Aug 02 '15 at 08:33
  • verifying that it works, can also be done using java stubs. It all depends on how intelligently one mocks the real world. You are minimizing the difference between *abstraction* and *encapsulation*, which is not true. this is one [answer](http://stackoverflow.com/a/25029526/3317808). – overexchange Aug 02 '15 at 08:34
  • @overexchange I disagree. It is *pointless to mock what is being tested*. The real world (a Component) is not mocked. A Service is mocked. The mocked Service is a lie; the input and output and interactions are known/crafted, just as with other test data. – user2864740 Aug 02 '15 at 08:37
  • I am minimizing the difference between abstraction and encapsulation because the Java interface does both at once, and (for that reason) it's the standard tool in the JVM ecosystem. – chrylis -cautiouslyoptimistic- Aug 02 '15 at 08:49
0

To answer this question, we must clarify what we mean by "abstraction" and "encapsulation".

Wikipedia defines abstraction as follows:

Abstraction in its main sense is a conceptual process by which general rules and concepts are derived from the usage and classification of specific examples, literal ("real" or "concrete") signifiers, first principles, or other methods. "An abstraction" is the product of this process—a concept that acts as a super-categorical noun for all subordinate concepts, and connects any related concepts as a group, field, or category.

and for mathematics:

Abstraction in mathematics is the process of extracting the underlying essence of a mathematical concept, removing any dependence on real world objects with which it might originally have been connected, and generalizing it so that it has wider applications or matching among other abstract descriptions of equivalent phenomena

and computer science:

In computer science, abstraction is a technique for managing complexity of computer systems. It works by establishing a level of complexity on which a person interacts with the system, suppressing the more complex details below the current level.

In summary, abstraction is the process of generalization, and abstractions are the results of this process.

By generalizing something, we make it more widely applicable (reusable). For instance, if I have a method to sort persons, and a method to sort cats, I may generalize a method to sort anything that can be pairwise compared. This method has numerous applications. It is a useful abstraction.

By generalizing something, we treat an entire group of things the same, and no longer care which concrete thing we are thinking about. In the example above, I have abstracted over the kinds of objects to be sorted, and abstracted away their internal representation.

Abstraction is therefore closely related to the concept of information hiding, which Wikipedia defines as follows:

In computer science, information hiding is the principle of segregation of the design decisions in a computer program that are most likely to change, thus protecting other parts of the program from extensive modification if the design decision is changed. The protection involves providing a stable interface which protects the remainder of the program from the implementation (the details that are most likely to change).

Written another way, information hiding is the ability to prevent certain aspects of a class or software component from being accessible to its clients, using either programming language features (like private variables) or an explicit exporting policy.

That is, information hiding is a way to enforce abstractions. We don't just permit our callers to think in an abstraction, we force them to, by hiding the knowledge of the concrete things they should not think about.

With that, we can finally talk about encapsulation, which Wikipedia defines as follows:

Encapsulation is the packing of data and functions into a single component. The features of encapsulation are supported using classes in most object-oriented programming languages, although other alternatives also exist. It allows selective hiding of properties and methods in an object by building an impenetrable wall to protect the code from accidental corruption.

That is, encapsulation is a kind of information hiding (we hide fields or methods).


With that theory in mind, on to your questions:

Wrt Point1(above) says, "A new, better implementation can replace an old one.". This is the goal of abstraction but not encapsulation. Am I correct?

Since encapsulation can be used to enforce abstractions, it can promote their use, and can therefore contribute to reaping their benefit. In fact, this is the purpose of encapsulation.

However, you are correct that encapsulation without abstraction does not promote implementation exchange. Such encapsulation has failed to achieve its purpose; it has been misused.

That is, the article you quote tacitly assumes that encapsulation has been used correctly.

How Encapsulation help programmer to independently implement module without having access to other modules? How this parallel implementation of modules has anything to do with Encapsulation? Because Encapsulation is about protecting in-variants.

If invariants are protected through encapsulation, calling code may not need not be aware of this invariant. If so, the invariant has been abstracted away, the development of calling code is not affected by this invariant, i.e. the other module may be developed independent of that invariant.

Community
  • 1
  • 1
meriton
  • 68,356
  • 14
  • 108
  • 175