Should instances use setters/getters for accessing

2019-02-20 19:10发布

问题:

Beginning in every introductory programming class, we are taught to use accessors and setters as opposed to exposing the inner-workings of a class. Students learn the point of the exercise for a later day, but now I understand that such practice (A) prevents the implementation from becoming part of the contractual exported API, (B) improves encapsulation and data-hiding, and (C) allows a guarantee as to whether certain operations should happen (increase a counter, log something, etc.) whenever a variable is set or accessed.

How about using getter/setters from within the instance itself? For example,

class A {
  private:
    int number = 43;
  public:
    int getNumber();
    void setNumber(int);
};

When it comes down to it, does this really matter? Are there any guidelines we can follow, or has there been anything written on this scenario? This question comes up a lot in my mind when I am programming, but I have never seen anybody discuss accessors/mutators with regards to the instance itself.

Thank you!

回答1:

The proper use case for calling a getter or setter from within the instance is when you need to take advantage of the side effects, validation or computations that the getter or setter provides. Why duplicate such functionality from within the object, if you don't have to?

Purists will refactor the side effects, validation or computations into their own private method, and then call that method internally and from the getter/setter. That way, you're not coupling your public interface to any internal implementation details.



回答2:

It will boil down to consistency. IMHO, once you have created accessor methods, there's no business accessing the actual variable directly - even from within the enclosing class.

By using the same setters and getters you have exposed publicly also within the class itself, you get guaranteed common behavior whenever your member variable is accessed. There is a single point through which reads and modifications will go through: be it publicly, or internally.

Think about it, what if someday you introduce a zero check on a specific member integer called myVar? Only code that used setNumber will have that feature then. All lines within the class that have used the variable directly will have to be individually modified.



回答3:

Getters/setters are for encapsulation. A class using getters/setters for accessing its own members is extreme encapsulation! Answer is not necessary, no benefit of doing it.

You may use getter/setter when there is some logic in them and you want to apply it always - even for private member access. One such example is a derived value synthesised by the getter. Whether another class or same class - they have to go through the getter.



回答4:

I'm currently writing lots of tests with Mockito framework, which is used for making mocks, and, of course, all the object properties of a mocked object are set to null. Therefore, if I want to call some real method on that object If that method called the properties directly, I would get NullPointerExceptions, or some sort of unexpected behaviour because properties are null!

Instead, if I used getters inside my class, I could just mock the getX() method to return whatever the property should be set to, and I don't have to worry.

That's one use case in which I found using getters inside a class useful.

Another reason I can think of is because their might be some other computation needed to get or set something other than just an assignment.



标签: java c++ class oop