Search code examples
javaoopencapsulation

Why Encapsulation is called data hiding, if its not hiding the data?


What is the difference between following two class in terms of data hiding(encapsulation).

In below example , I can access the value of member by making it public.

Eg: 1

public class App {
   public int b = 10;

public static void main(String[] args) {
    System.out.println(new App().b);
 }
}

In below example, I can access the value of member by using getter method.

Eg : 2

class DataHiding 
   {

    private int b;

    public DataHiding() {
    }

    public int getB() {
        return b;
    }

    public void setB(int b) {
        this.b = b;
    }

    }

In both the above examples, I can access the value of member. Why Eg : 2, is called data hiding (encapsulation) ? If its not hiding the data.

Why Eg : 1 is not called encapsulated ?


Solution

  • What is it about

    As you tagged this question with both and object oriented programming , I suppose you are implicitly thinking about Java Beans. Nevertheless this is a question quite common across languages, take the wikipedia page on this matter :

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

    • A language mechanism for restricting access to some of the object's components.
    • A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.

    Some programming language researchers and academics use the first meaning alone or in combination with the second as a distinguishing feature of object-oriented programming, while other programming languages which provide lexical closures view encapsulation as a feature of the language orthogonal to object orientation.

    The second definition is motivated by the fact that in many OOP languages hiding of components is not automatic or can be overridden; thus, information hiding is defined as a separate notion by those who prefer the second definition.

    So encapsulation is not really about hiding data or information it about enclosing pieces of data in a language component (a class in Java). A Java Beans encapsulate data.

    That being said, while encapsulation is one of the main feature of object oriented programming paradigm, at some point in the history of language design it was seen as not enough to help design better software.

    History

    One key practice to achieve better software design is decoupling, and encapsulation helps on that matter. Yet a cluster of data was not enough to help achieve this goal, other efforts in OOP pioneering were made in different language at that time, I believe SIMULA is the earliest language to introduce some kind of visibility keywords among other concepts like a class. Yet the idea of information hiding really appears later in 1972 with data that is only relevant to the component that uses it to achieve greater decoupling.

    But back to the topic.

    Answers to your questions

    1. In this case data is encapsulated and public

      This is commonly known as a global variable and it is usually regarded as a bad programming practice, because this may lead to coupling and other kind of bugs

    2. Data is encapsulated and public (through method accessors)

      This class is usually referred to as a Java Bean, these are an abomination if used in any other than what they were designed for.

      These object were designed to fulfill a single role and that is quite specific is according to the specification

      2.1 What is a Bean? Let's start with an initial definition and then refine it:

      “A Java Bean is a reusable software component that can be manipulated visually in a builder tool.”

      Why is it an abomination nowadays ? Because people, framework vendors usually misuse them. The specification is not enough clear about that, yet there's some statement in this regard :

      So for example it makes sense to provide the JDBC database access API as a class library rather than as a bean, because JDBC is essentially a programmatic API and not something that can be directly presented for visual manipulation.

      I'd rather quote Joshua Bloch (more in this question and answer) :

      "The JavaBeans pattern has serious disadvantages." - Joshua Bloch, Effective Java

    Related points

    As explained above one key practice to achieve better software is decoupling. Coupling has been one of the oldest battlefront of software engineers. Encapsulation, information hiding have a lot to do with the following practices to help decoupling for numerous reasons:

    • the Law of Demeter, breaking this law means the code has coupling. If one has to traverse a whole data graph by hand then, there's no information hiding, knowledge of the graph is outside of the component, which means the software is therefore less maintainable, less adaptable. In short : refactoring is a painful process. Anemic domain model suffer from that, and they are recognized as an anti-pattern.

      A somehow modern practice that allows one to not break the Law of Demeter is Tell, Don't Ask.

      That is, you should endeavor to tell objects what you want them to do; do not ask them questions about their state, make a decision, and then tell them what to do.

    • immutability, if data has to be public it should be immutable. In some degree if data is not needed, one module can introduce side effects in another ; if this was true for single threaded programs, it's even more painful with multi-threaded softwares. Today softwares and hardware are getting more and more multi-threaded, threads have to communicate, if an information has to be public it should be immutable. Immutability guarantee thread-safety, one less thing to worry about. Also immutability has to be guaranteed on the whole object graph.

      class IsItImmutable {
        // skipping method accessors for brevity
      
        // OK  <= String is immutable
        private final String str;
      
        // NOK <= java.util.Date is mutable, even if reference is final a date can be modified
        private final Date  date;
      
        // NOK <= Set operations are still possible, so this set is mutable
        private final Set<String> strs;
      
        // NOK <= Set is immutable, set operations are not permitted, however Dates in the set are mutable
        private final Set<Date> udates = Collections.unmodifiableSet(...);
      
        // OK  <= Set is immutable, set operations are not permitted, String is immutable
        private final Set<String> ustrs = Collections.unmodifiableSet(...);
      }