3
I am studying for the Java Programmer SE 7 I certification exam.
I use Selftest Kaplan (recommended by Oracle itself).
I came across the following question: (I will leave everything in English on purpose. Not to translate and end up omitting information).
Given:
public class Pedometer { private double stride; private double[] measurements; }
Which code Fragment is a method that Meets good Encapsulation Principles?
a) public void getStride(double stride) { stride = this.stride; } b) public void getStride(double stride) { this.stride = stride; } c) public double[] getMeasurements() { return this.measurements; } d) public double[] getMeasurements() { return measurements.clone(); }
Repsondi the option c, although I found the option d very interesting.
When I went to see the result I saw that in fact, the correct option was the d.
Why?
I’m not questioning the workings of the method clone()
and not questioning that cloning an object is "better", but questioning: why this implementation is not common?
I’ve worked on several Java projects and never seen one getter thus.
Eclipse, for example, does not generate the getter s thus (ggas
).
Not even the lombok
makes this implementation.
Explanation of the reply by Kaplan:
Explanation: The following code Fragment is a method that Meets good Encapsulation Principles:
public double[] getMeasurements() { return measurements.clone(); }
In this code Fragment, the accessor method uses the
clone
method to Return a copy of themeasurements
field, rather than a Ference to the field itself. Accessor methods should Return copies of field Objects. A copy of a field will Prevent other classes from modifying Fields directly and will require going through mutator methods.The two versions of the accessor method
getStride
do not Meet good Encapsulation Principles. Neither method Returns the value of thestride
field as expected, but Instead modifies thestride
field like a mutator method. Also, the statementstride = this.stride;
overwrites thestride
Parameter, rather than assigning thestride
Parameter to thestride
field as expected.The accessor method
getMeasurements
that Returns a direct Reference to themeasurements
field Object does not Meet good Encapsulation Principles. Accessor methods should not Return direct References to field Objects. Direct access will allow other classes to Modify Fields directly without going through mutator methods.
What is your question? I think that the answer is already well explained why to do so. Although I’ve never seen it, I also believe the explanation makes a lot of sense
– Sorack
@Sorack edited the question and left the doubt in bold. If this is the right way to implement, why don’t we implement it like this?
– igventurelli
I think this is one of the examples of what differentiates someone who programs in Java and someone who programs and is certified. There are things that we only learn by studying for certification. I think it makes a lot of sense that this implementation, so much so that usually when you import classes from a WS, they already come with a
setter
andgetter
differentiated forList
, for example.– Sorack
I understand. On the other hand, if we use the
clone()
for all the getter s of all our classes, will be created a huge amount of objects. Imagine that for eachgetAtributo()
a new object is created? How often do we do this in our systems? Several!– igventurelli
But you see, this doesn’t include primitive types. So it’s not for everything that’s used, you know? I think it’s a bit of a matter of architecture too...
– Sorack
I agree. Primitive types do not enter into this account. But still I think the amount will be much higher than referencing the attribute directly. I also agree that it is a question of architecture, but I would like a concrete answer that says why we do not use it like this. I swear, I never saw a getter that way. If I’m implementing wrong, I want to correct myself to do right.
– igventurelli
I even understand why it is not common, because it is more or less rare to need to return one array whole which is a member of an object. I even accept the premise. But honestly destroy the performance of the application to achieve something of dubious benefit, and even worse, it is not obvious that it will have a bad performance, it is something that makes me think that the certification of Java is worthless or has negative weight. It is ideology overriding pragmatism.
– Maniero
I’m not saying it doesn’t make sense to do this ever, but in the given example I wouldn’t because I don’t have enough information to make a decision that could compromise the execution of the application. Perhaps it is only the fault of the question to be very badly asked, which questions the validity of the certification in the same way. Primitive types are "cloned" automatically, but it is guaranteed that it is small and has value semantics.
– Maniero
It is true that Java never fully understood the function of having types by value and by reference, so it made almost all of them by reference, even when by value it makes more sense semantically. Maybe you don’t see why most programmers are more pragmatic, good.
– Maniero
I think that that answer @bigown on a question about immutability lightens a little the ideas
– Sorack
Give you a precise answer as to why not do is very difficult, since each developer must have a reason that led him to do so (it is easier to answer why to do so). For me, the reason they don’t do it this way is that as much as Java is an object-oriented language, programs are still, in a sense, written in a procedural mode. If you stop to analyze most Javabeans, they are but structs glorified. continues...
– Felipe Marinho
They contain no logic, do not check whether past values are valid, do not guarantee that they will be in a consistent state and everything that was "encapsulated" is exposed. At the end of the day, it wouldn’t make any difference if your attributes were public and your methods didn’t exist.
– Felipe Marinho