0

For simple classes (and I mean really simple ones), why do we use accessor and mutator methods? Why do not we just make the data members public?

For example, the following class header (in C++) and could have been implemented with much less effort; as it is actually a couple of data members with accessors and mutators that do nothing but access/modify those data members.

I appreciate the advantage of the use of accessors and mutators in more complex classes.

template<class T>
class Node
{
private:
    T        item; // A data item
    Node<T>* next; // Pointer to next node

public:
    Node();
    Node(const T& anItem);
    Node(const T& anItem, Node<T>* nextNodePtr);
    void setItem(const T& anItem);
    void setNext(Node<T>* nextNodePtr);
    T getItem() const;
    Node<T>* getNext() const;
}; // end Node
  • It's very language dependent. For example, in .NET based languages, data binding for both Winforms and WPF relies on properties (ie accesor methods) instead of fields (ie simple variables). – Alejandro Aug 23 '20 at 22:42

1 Answers1

0

This is a very fundamental, basic, and well-defined design principle in OOP - why to use accessors and mutators, in spite of whether a class is big or small.

I would still say, that implementation-usage of this principle still varies from language to language, but the core principle of Object Oriented Design - Encapsulation - remains always same and mandates, that you should always hide everything that is possible to hidden.

This is kind of duplicate of your question, and it refers to why getters and setters are in the play; however, I'll try to bring some other points as well.

Encapsulation, aspect of which is the topic in questions (mutators/accessors), is a fundamental and probably the most important principle of Object Oriented Programming.

First and foremost:

The main point of the Encapsulation is not(!) to restrict/block the access to the member variable, but rather to constrain the access policy and mandate the reasonable access, and therefore avoid any unintended interference, implicit misuse, or accidental accesses.

Think about it: if the user invokes .setUserName("MyUser") the one really intends to write the data into the member field, and that's explicitly clear! otherwise, it would mean that the client has (1) accidentally provided the "MyUser" data as an argument into setter method, and they (2) accidentally invoked the .setUserName method, which is way less likely to happen accidentally both together, then just publicly accessing that field, which takes only one move to do.

That being said, using the principle of encapsulation and advocating it as a core OOP feature, software developers, a lot of frameworks and libraries very often conventionally agree and make use of data classes, ordinary classes, business classes, service, or any other types, relying on the widespread Conventional Design and best practice of how to use member variables - using mutators to mutate and accessors to access the fields.

Many frameworks explicitly invoke setters and getters when they implement IoC or DI.

So, it's the best practice, conventionally agreed, non-smelling code style, and the most safe design of the class members, to use encapsulation and interact with them through mutators and accessors.

Giorgi Tsiklauri
  • 9,715
  • 8
  • 45
  • 66