Encapsulation Vs DataHiding? - java

This might be the duplicate question but I haven't found the answer yet.
Link 1
Encapsulation:
Encapsulation is the technique of making the fields in a class private
and providing access to the fields via public methods. If a field is
declared private, it cannot be accessed by anyone outside the class,
thereby hiding the fields within the class. For this reason, encapsulation is also referred to as data hiding
Link 2
Encapsulation:
"It […] refers to building a capsule, in the case a conceptual barrier, around some collection of things." — [Wirfs-Brock et al, 1990]
"As a process, encapsulation means the act of enclosing one or more items within a […] container. Encapsulation, as an entity, refers to a package or an enclosure that holds (contains, encloses) one or more items."
"If encapsulation was 'the same thing as information hiding,' then one might make the argument that 'everything that was encapsulated was also hidden.' This is not obviously not true."
Which one should I go with ? Or have I misunderstood the definition ?

The main point is that it doesn't really matter. Anyone can define a term in a slightly different way, and usually various authors adapt the meaning to the various contexts within which they use those terms.
You will not gain any enlightenment from trying to figure out which one is "right" and which one is "wrong". Quotes taken out of context are especially uninformative.
The important thing is to understand the underlying ideas without reference to the vocabulary items used to refer to them.

There is disagreement as to whether the definition of encapsulation should include data hiding so this is going to be a strictly opinion answer. I believe that the latter definitions are more correct since data hiding is not unique to OO programming. It is a separate feature that does not preclude encapsulation which is the binding of functions/methods with a set of variables. In fact, data hiding was the hallmark of early modular programming in languages such as C and Pascal.

The first definition is very Java-centric. The second one is more generic. Both are correct. As to which one to go with, that's a subjective question. Since both are correct, I'd suggest going with the one you prefer...

Encapsulation is more than just data-hiding. It is decoupling internal data representation and implementation from the public interface. Thanks to encapsulation, as long as you don't break the interface contract, you can change internal implementation without anyone outside ever knowing. So I'd say encapsulation = data-hiding + implementation-hiding.

Related

Core OOPS : Encapsulation

Yesterday in an Interview I was asked
How Does Encapsulation works internally ?
I was really confused because as per me Encapsulation is simply
"The state of a class should only be accessed through its public interface."
but when it comes to internal working I ran out of words.So if anyone can explain that it would be so helpful.
I agree with commenters that asking for clarifications is a good idea - good questions can be even better than good answers, and allow you to ensure that you are actually answering what they think that they are asking.
In this case, I assume that they wanted you to explain how Java ensures that programmers do not violate encapsulation. This involves
built-in syntax and semantics for marking fields / methods as public, private, protected, or package-protected.
compiler checks to ensure that these are not violated
(external) tools available to detect code smells relating to encapsulation, such as calls to overridable methods from within a constructor.
(somewhat more far-fetched) no direct access to program memory, making, for example, reinterpret-casts such as found in C / C++ unavailable in Java; this also preserves encapsulation.
You could have ensured that this is what they wanted by asking "are you referring to how Java ensures that programmers do not violate encapsulation, that is, that they do not access the state of objects except through their public interface?"
Additional answers come to mind:
use of meaningful comments, easily accessible via JavaDoc both in-IDE and as browsable documentation, that allow programmers to understand how classes are meant to be used and composed.
strong coding conventions that enforce encapsulation, such as setting fields to the most restrictive access possible, and only making public those parts that should actually be public.

Wondering about Microstream class StorageConfiguration

there are two questions with microstream database and its class StorageConfiguration:
1) What ist the difference of the methods New() and Builder() and the DEFAULT construct?
2) Why the methods are writting uppercased? That does not seem to be Java naming convention.
Thanks for any answers!
I am the MicroStream lead developer and I can gladly answer those questions.
To 1)
"New" is a "static factory method" for the type itself.
"Builder" is a static factory method for a "builder" instance of the type.
Both terms can be perfectly googled for more information about them.
A quick service as a starting point:
"static factory method":
https://www.baeldung.com/java-constructors-vs-static-factory-methods
"builder pattern":
https://en.wikipedia.org/wiki/Builder_pattern
--
To your actually second question, about the "DEFAULT" construct:
If I may, there is no "DEFAULT" construct, but "Default".
(Conventions are important ... mostly. See below.)
"Default" is simply the default implementation (= class) of the interface StorageConfiguration.
Building a software architecture directly in classes quickly turns out to be too rigid and thus bad design. Referencing and instantiating classes directly creates a lot of hardcoded dependencies to one single implementation that can't be changed or made more flexible later on. Inheritance is actually only very rarely flexible enough to be a solution for arising architecture flexibility problems. Interfaces, on the other hand, only define a type and the actual class implementing it hardly matters and can even be easily interchangeable. For example, by only designing via interfaces, every instance can easily be "wrapped" by any desired logic via using the decorator pattern. E.g. adding a logging aspect to a type.
There is a good article with an anecdote about James Gosling (the inventor of Java) named "Why extends is evil" that describes this:
https://www.javaworld.com/article/2073649/why-extends-is-evil.html
So:
"Default" is just the default class implementing the interface it is nested in. It makes sense to name such a class "Default", doesn't it? There can be other classes next to it, like "Wrapper" or "LazyInitializing" or "Dummy" or "Randomizing" or whatever.
This design pattern is used in the entire code of MicroStream, giving it an incredibly flexible and powerful architecture. For example:
With a single line of code, every part of MicroStream (every single "gear" in the machine) can be replaced by a custom implementation. One that does things differently (maybe better?) or fixes a bug without even needing a new MicroStream version. Or one that adds logging or customized exception handling or that introduces object communication where there normally is none. Maybe directly with the application logic (but at your own risk!). Anything is possible, at least inside the boundaries of the interfaces.
Thinking in interfaces might be confusing in the beginning (which is why a lot of developers "burn mark" interfaces with a counterproductive "I" prefix. It hurts me every time I see that), but THEY are the actual design types in Java. Classes are only their implementation vehicles and next to irrelevant on the design level.
--
To 2)
I think a more fitting term for "static factory method" is "pseudo constructor". It is a method that acts as a public API constructor for that type, but it isn't an actual constructor. Following the argumentation about the design advantages of such constructor-encapsulating static methods, the question about the best, consistent naming pattern arose to me. The JDK gives some horribly bad examples that should not be copied. Like "of" or "get". Those names hardly carry the meaning of the method's purpose.
It should be as short but still as descriptive as possible. "create" or "build" would be okay, but are they really the best option? "new" would be best, but ironically, that is a keyword associated with the constructors that should be hidden from public API. "neW" or "nEw" would look extremely ugly and would be cumbersome to type. But what about "New"? Yes, it's not strictly Java naming conventions. But there already is one type of methods that does is an exception to the general naming rule. Which one? Constructors! It's not "new person(...") but "new Person(...)". A method beginning with a capital letter. Since the beginning of Java. So if the static method should take the place of a constructor, wouldn't it be quite logical and a very good signal to apply that same exception ... or ... "extension" of the naming convention to that, too? So ... "New" it is. Perfectly short, perfectly clear. Also not longer and VERY similar to the original constructors. "Person.New" instead of "new Person".
The "naming convention extension" that fits BOTH naming exceptions alike is: "every static method that starts with a capital letter is guaranteed to return a new instance of that type." Not a cached one. Always a new one. (this can be sometime crucial to guarantee the correctness of algorithms.)
This also has some neat side effects. For example:
The pseudo-constructor method for creating a new instance of
"StorageConfigurationBuilder" can be "StorageConfiguration.Builder()".
It is self-explaining, simple, clear.
Or if there is a method "public static Vector Normalized(Vector v)", it implicitely
tells that the passed instance will not be changed, but a new instance will
be returned for the normalized vector value. It's like having the
option to give constructors proper names all of a sudden. Instead of
a sea of different "Vector(...)" methods and having to rely on the
JavaDoc to indirectly explain their meaning, the explanation is right
there in the name. "New(...)", "Normalized(...)", "Copy(...)" etc.
AND it also plays along very nicely with the nested-Default-class
pattern: No need to write "new StorageConfiguration.Default()" (which
would be bad because too hardcoded, anyway), but just
"StorageConfiguration.New" suffices. It will internally create and
return a new "StorageConfiguration.Default" instance. And should that
internal logic ever change, it won't even be noticable by the API
user.
Why do I do that if no one else does?
If one thinks about it, that cannot be a valid argument. I stick VERY closely to standards and conventions as far as they make sense. They do about 99% of the time, but if they contain a problem (like forbidding a static method to be called "new") or lacking a perfectly reasonable feature (like PersonBuilder b = Person.Builder()" or choosing properly speaking names for constructors), then, after careful thought, I br... extend them as needed. This is called innovation. If no one else had that insight so far, bad for them, not for me. The question is not why an inventor creates an improvment, but why no one else has done it so far. If there is an obvious possibility for improvement, it can't be a valid reason not to do it just because no one else did it. Such a thinking causes stagnation and death of progress. Like locking oneself in a 1970ies data storing technology for over 40 years instead of just doing the obviously easier, faster, direct, better way.
I suggest to see the capital letter method naming extension as a testimony to innovation: If a new idea objectively brings considerably more advantages than disadvantages, it should - or almost MUST - be done.
I hereby invite everyone to adopt it.

which cannot be treated as the friend in contrast with oops

i need your help in understanding a question.
which of these cannot be treated as the friend in contrast with oop:
Function
Class
Object
Operator function
i think answer should be Operator function but i am not sure.please
anyone explain this to me.
thanks in advance.
Object.
An object is instantiated, the others are not.
Think about what 'friend' means. It's like schema, you're defining access, but it's all done at compile time... an object is a run time thing so friendship is meaningless and uninforcable. Once your code is compiled it's all reduced to pointers and references and no checks are done.
Also, to further clarify, to create friendship relationships between objects and other objects, or between objects and anything else, you couldn't do that at compile/code time, as you don't know what objects will exist and you can't reference them... Such behaviour, or similar behaviour anyway, COULD be implemented by a language, but the friendships would have to be added at run time, and this would be quite an interesting feature of a high level language, but quite a different feature to friendship as we know it.
Your question makes only sense for C++.
friend is not a contrast to OOP. friend helps OOP by allowing you to expose fewer member variables and member functions. friend allows you to expose your private members to one particular external component. Without friend, you would have to make the members public and expose them to the whole world.
Objects cannot be made friends. friend is a mechanism to control member access and hence, like public, protected and private specifiers, a compile-time issue. Objects, in contrast, exist a run-time[*].
An "operator function" (the correct word would be "overloaded operator") is not that much different from a normal function, really. You can mostly consider overloaded operators as functions with funny names. As far as friend is concerned, there is no difference whether you call your function Add or +, for example.
[*] I realise that this is a slight oversimplification when you consider template metapropgramming or constexpr.

Why friend directive is missing in Java?

I was wondering why Java has been designed without the frienddirective that is available in C++ to allow finer control over which methods and instance variables are available from outside the package in which a class has been defined.
I don't see any practical reason nor any specific drawback, it seems just a design issue but something that wouldn't create any problem if added to the language.
Here are a few reasons off the top of my head:
friend is not required. It is convenient, but not required
friend supports bad design. If one class requires friend access to another, you're doing it wrong. (see above, convenient, not required).
friend breaks encapsulation. Basically, all my privates are belong to me, and that guy over there (my friend).
In general i think it was because of the added cognitive complexity and low number of cases in which it creates an improvement.
I would say that the extremely huge number of lines of java in production at this moment can attest that the friend keyword is not really a big loss :).
Please see #dwb's answer for some more specific reasons.
Only a very naive and inexperienced programmer would advocate against friends. Of course it can be misused, but so can public data, yet that capability is provided.
Contrary to popular opinion, here are many cases, in particular for infrastructure capabilities, where friend access leads to BETTER design, not worse design. Encapsulation is often violated when a method is FORCED to be made public when it really shouldn't be, but we are left with no choice because Java does not support friends.
In addition to the aforementioned package visibility, Java also offers inner and anonymous classes which are not only friends by default, but also automatically have a reference to the containing class. Since creating such helper classes is probably the only reasonable way to use friend in C++, Java doesn't need it since it has another mechanism for that. Iterators are a very good example of this.
Completely agree with spaceghost's statement in his answer
Contrary to popular opinion, here are many cases, in particular for infrastructure capabilities, where friend access leads to BETTER design, not worse design.
My example is simple - if a class A has to provide a special "friend" interface to class B in java we have to place them into the same package. No exceptions. In that case if A is a friend of B and B is a friend of C, A has to be a friend of C which isn't always true. This "friendship transitivity" breaks encapsulation more then any problems which C++ friendship could lead to.
Why not simply think that Java requires friend classes to be co-located ? The package-private visibility allows everyone from the same package to access those members. So you're not only limited to explicitly declared friends, but you allow any (existing or future) friend to alter some members that are specifically designed for this purpose (but not your private stuff). You're still able to fully rely on encapsulation.
Just to add to the other answers:
There is the default package visibility in Java. So, you could call all classes in the same package neighbors. In that case you have explicit control of what you show to the neighbors - just members with package visibility.
So, it's not really a friend but can be similar. And yes, this too leads to bad design...
In my opinion some kind of friend feature (not necessarily very similar to C++'s) would be very helpful in some situations in Java. Currently we have package private/default access hacks to allow collaboration between tightly coupled classes in the same package (String and StringBuffer for instance), but this opens the private implementation interface up to the whole package. Between packages we have evil reflection hacks which causes a whole host of problems.
There is a bit of an additional complication in does this in Java. C++ ignores access restrictions whilst resolving function overloads (and similar) - if a program compiles #define private public shouldn't do anything. Java (mostly) discards non-accessible members. If friendship needs to be taken into account then the resolution is more complicated and less obvious.

Why is using a class as a struct bad practice in Java?

We recently had a code review . One of my classes was used so that I could return/pass more than one type of data from/to methods . The only methods that the class had were getters/setters . One of the team's members ( whose opinion I respect ) said that having a class like that is bad practice ( and not very OOP ) . Why is that ?
There's an argument that classes should either be "data structures" (i.e., focus on storing data with no functionality) or "functionality oriented" (i.e., focus on performing certain actions while storing minimal state). If you follow that argument (which makes sense but isn't always easy to do) then there is nothing necessarily wrong with that.
In fact, one would argue that beans and entity beans are essentially that - data containers with getters and setters.
I have seen certain sources (e.g., the book "clean code") arguing that one should avoid methods with multiple parameters and instead pass them as a single object with getters and setters. This is also closer to the "smalltalk model" of named parameters where order does not matter.
So I think that when used appropriately, your design makes sense.
Note that there are two separate issues here.
Is a "struct-like" class sensible?
Is creating a class to return multiple values from a method sensible?
Struct-like classes
An object class should -- for the most part -- represent a class of real-world objects. A passive, struct-like java bean (all getters and setters) may represent a real-world thing.
However, most real-world things have rules, constraints, behaviors, and basic verbs in which they engage. A struct-like class is rarely a good match for a real-world thing, it's usually some technical thing. That makes it less than ideal OO design.
Multiple returns from a method
While Python has this, Java doesn't. Multiple return values isn't an OO question, per se. It's a question of working through the language limitations.
Multiple return values may mean that an object has changed state. Perhaps one method changes the state and some group of getters return the values stemming from this state change.
To be honest, it sounds fine to me. What alternative did the reviewer suggest?
Following OOP "best practices" and all is fine, but you've got to be pragmatic and actually get the job done.
Using Value Objects like this (OO speak for 'struct') is a perfectly legitimate approach in some cases.
In general, you'll want to isolate the knowledge needed to operate upon a class into the class itself. If you have a class like this, either it is used in multiple places, and thus can take on some of the functionality in both of those places, or it is in a single place, and should be an inner class. If it is used in multiple ways, but in completely different ways, such that there is no shared functionality, having it be a single class is misleading, indicating a shared functionality where there is none.
However, there are often specific reasons for where these general rules may or may not apply, so it depends on what your class was supposed to represent.
I think he might be confusing "not very OOP" for bad practice. I think he expected you to provide several methods that would each return 1 value that was needed (as you will have to use them in your new class anyway that isn't too bad).
Note that in this case you probably shouldn't use getters/setters, just make the data public. No this is "not very OOP" but is the right way to do it.
Maybe Josh Bloch offers some insight into this here.

Categories