What is the difference between referencing an attribute directly or by get/set

Asked

Viewed 993 times

8

As an example I have a private String atributo, so I can have two ways of referencing the same, this internally in the class:

this.atributo

And also:

this.getAtributo();

It’s correct to say it’s wrong to use this.atributo it is right to use this.getAtributo() ?

In cases, I don’t need to take or set class values in my main() or in another class, so I don’t even create the getters and setters, because creating is an indirect way to turn a private attribute into a public attribute, so it would be flawed for security.

But back to the main issue, it is wrong to use this.atributo? And what’s the difference between using one or the other?

5 answers

8


There is no security breach allowing access to the fields (I don’t like the term attribute for this, further in this context). At most it is a encapsulation break, or abstraction leak, even so depends on the case.

If you only have the private field, everything normal, no problem, you can do it at will. The problem starts getting more complicated when you have both.

In fact nothing prevents you to access one or the other as needed. Obviously, direct access to the field only allows you to take the value and change its value. Methods getter/Setter may give the impression that it is a common access, but they may be performing other actions at the time of access or assignment. So they’re only equivalent by coincidence, their purposes are different.

The ideal is to access the methods (when they exist) to maintain coherence. But if you have a good reason to access the field and know of the implication that direct access will not perform the actions normally established in the methods, it’s okay.

Here the answer is: it depends. The most important thing is to understand that the call of one or the other potentially has very different semantics. This could be very confusing.

The methods are usually slower, but when they are accessed privately there is an optimization and probably the method call will be replaced by his code (inline Expansion), if the implementation is simple.

As a curiosity, the methods are created by default by the programmers, even if their only action is access and direct assignment without doing anything else, that is, does the same as if accessing the direct field, because if one day you need the methods they were already being used. If you start by making the field public and one day you need to add a processing to your read or write access, then the method has to be added, changing the public API and requiring all of its consumer codes to be changed. Creating an abstraction increases encapsulation and improves decoupling by hiding the implementation details.

So, if the code will only have access to the field privately OR you are absolutely sure that you will never have a method to access that field, you can expose the field. If you cannot guarantee this it is safer to create the methods. Unless the API is not so public and you agree to change consumer codes.

What is best depends on each scenario. What cannot be preached is decoupling and expose the implementation detail, which is the field. Either you have one benefit or the other, everything is tradeoff.

I replied something similar about C#.

  • I ended up "flying" here at the time of the question and put parameter instead of attributes. Then, the absence of getters and setters and direct reference to the attribute would be indicated when the developer is sure that the attribute will not undergo change relative to its validation and will not be exposed to another class?

  • 1

    If you change the E you used in there for an OR, that’s right. Obviously if the field is only implementation details (it is private) there is no problem and there is no need to create the methods. There are people who create in this scenario because everyone creates, there is no real reason. It is recommended not to create in this case. Another situation now: if you’re going to expose the camp, consider that you can never make it private again if you ever need to. Because someone may have consumed the direct field, a change would be a break from the API. In anemic classes they make sense. In others you have to be careful.

  • 1

    Particularly I prefer to avoid creating the methods until they are necessary. But it is a mistake to adopt this as the default. You have to really look at it case by case. Because a mistake there can create huge complications. If I am developing alone or in a lean, cohesive team with good tools Refactoring, I would risk more not using abstraction and more exposing the field. In an API for third parties consume, I would go the safe way for sure and create the abstractions. Otherwise a change would force depress this API and create a new one.

5

First of all, you spoke about security. Security is not the intention to choose to use private variables. The intention is to protect against programming flaws (especially coupling) that lead to a degradation of code quality.

That said, it is not a good or bad practice to use getVariavel instead of this.variavel within the class itself because it is perfectly normal (even desirable) for class methods to manipulate (rationally, of course) its fields. The (a) author(a) of the class understands those variables and the important thing, in the end, is that the methods honor the public interface of the class and the guarantees proposed by it (or pre/post conditions).

There are those who will talk about performance concern, but this is paranoia-- it is very easy for the compiler to remove this extra call either during the build to bytecode or during the actual run. And, of course, concern with performance without measurements is premature optimization, famous for being the source of all ills.

  • The security issue I mentioned is in the case when I do not use get and set outside the class, so in my view it is more feasible not to generate get and set so already eliminating the possibility of accessing it outside the class, since for the operation it was not necessary to share with getter and Setter

  • 3

    One of the biggest mistakes of object-oriented teaching that I see being committed is that you have to create get/set for all your variables right away. This is simply not true. Creating private variables and then public get/sets is almost as bad as making everything public. Create setters only when needed-- preferably, do not create setters: create methods that change the class’s internal state in a controlled way. For example: create a method acelerar and not a setVelocidade (and only when the need arises).

2

The attribute private does not let you access the variable or method in another class, except in the class itself, using the reserved word this.


When you need to access in another class, you need to use a get and set.


Then use this getParametro() in the class that contains the private variable does not make much sense because it would be easier to use the this.


Like you said, if you don’t need to access, then you don’t even need to create the methods get and set.


Answering his final question: No, it would not be wrong to use this parameter., in fact it is the right way. I hope to have clarified your doubt.

0

With setters, you can check for conditions before effectively changing the variable.

public setIdade(int anos) {
    if (anos > 0) {
      idade = anos;
    }
}

After all, an age should not be negative, although an int may.

Using the attribute directly, there is no way to verify the semantics of the change. That is, it makes sense a negative age?

In the case of getters, it is possible to change implementation without changing the abstraction. In the example, stop using an integer to save age and start using current and birth dates.

The code of the clients of the class will not need to know this change. Just call getIdade() as it already does currently.

public int getIdade() {
  return this.idade;
}

public int getIdade() {
  return diferenca(hoje, nascimento);
}

-1

A good analogy to this problem is the classic of opening the television to change the channel (private variables) instead of using the remote control (methods).

Imagine you have a television class. And you want to change the channel.

It may be easier to access the channel variable directly (by opening the television), but you want to keep the logic of changing the channel under the responsibility of the television.

So the ideal is to create a method to ascendCanal() and descerCanal() and/or changeCanal() also because you keep the television controlling the channel and all that may need to be checked when making this type of change.

By making changes directly to the television variable, you can make the software work now, but it is much easier for logic to break into a future maintenance.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.