que-son-getters-y-setters-en-programacion

Qué son los getter y setters

Los métodos getter y setter son métodos permiten controlar cómo se accede y modifica el estado interno de un objeto.

Proporcionan una forma controlada de actualizar el estado interno de un objeto, permitiendo validaciones y restricciones sobre los valores que se pueden asignar.

Los getter (del inglés get) son métodos que permiten acceder al valor de una propiedad privada o protegida de una clase.

Por su parte, los setter (del ingles set) son métodos que permiten modificar el valor de una propiedad privada o protegida de una clase.

Ambos métodos, getter y setter pueden incluir lógica adicional, como transformación de datos o acceso controlado, antes de devolver el valor.

Por lo demás, los método getter o setter no tienen nada de especial. Es simplemente una convención de nombres que usamos. Pero por lo demás son métodos de instancia absolutamente normales.

Caso practico

Supongamos que tenemos una clase Persona que tiene una variable privada nombre. Crear un método getter y setter para esta propiedad es tan sencillo como crear dos métodos.

  • El método GetNombre() que devuelve la variable nombre
  • El método SetNombre() que reempleza la variable nombre

Es decir, algo así,

public class Persona
{
    private string nombre;

    // Getter
    public string GetNombre()
    {
        return nombre;
    }
    
    // Setter
    public void SetNombre(string valor)
    {
        nombre = valor;        
    }
}

Como vemos, es simplemente una convención de nombres para dos métodos que tienen la mínima lógica posible para gestionar la variable privada nombre.

Ejemplos en distintos lenguajes

Veamos un ejemplo de implementación en distintos lenguajes de programación,

En C#, las funciones getter y setter se implementan utilizando métodos convencionales para acceder y modificar campos privados de una clase.

public class Persona
{
    private string nombre;

    // Getter
    public string GetNombre()
    {
        return nombre;
    }

    // Setter
    public void SetNombre(string valor)
    {
        if (!string.IsNullOrEmpty(valor))
        {
            nombre = valor;
        }
    }
}

// Uso
Persona persona = new Persona();
persona.SetNombre("Juan");
Console.WriteLine(persona.GetNombre());

En C++, se pueden definir métodos de acceso (getters) y métodos de modificación (setters) para interactuar con campos privados de una clase.

#include <iostream>
#include <string>

class Persona {
private:
    std::string nombre;

public:
    // Getter
    std::string getNombre() const {
        return nombre;
    }

    // Setter
    void setNombre(const std::string& valor) {
        if (!valor.empty()) {
            nombre = valor;
        }
    }
};

// Uso
int main() {
    Persona persona;
    persona.setNombre("Juan");
    std::cout << persona.getNombre() << std::endl;
    return 0;
}

En JavaScript, no existen funciones getter y setter como en otros lenguajes, pero se pueden simular utilizando métodos para acceder y modificar campos privados de un objeto.

class Persona {
    constructor() {
        this._nombre = "";
    }

    // Getter
    getNombre() {
        return this._nombre;
    }

    // Setter
    setNombre(valor) {
        if (valor) {
            this._nombre = valor;
        }
    }
}

// Uso
const persona = new Persona();
persona.setNombre("Juan");
console.log(persona.getNombre());

En TypeScript, se pueden definir propiedades utilizando la sintaxis get y set para interactuar con campos privados de una clase de manera similar a C#.

class Persona {
    private nombre: string = "";

    // Getter
    getNombre(): string {
        return this.nombre;
    }

    // Setter
    setNombre(valor: string): void {
        if (valor) {
            this.nombre = valor;
        }
    }
}

// Uso
const persona = new Persona();
persona.setNombre("Juan");
console.log(persona.getNombre());

En Python, se pueden utilizar decoradores @property y @nombre.setter para definir métodos getter y setter como parte de una propiedad.

class Persona:
    def __init__(self):
        self._nombre = ""

    # Getter
    def get_nombre(self):
        return self._nombre

    # Setter
    def set_nombre(self, valor):
        if valor:
            self._nombre = valor

# Uso
persona = Persona()
persona.set_nombre("Juan")
print(persona.get_nombre())

Buenas prácticas Consejos

Como casi todo en programación, los métodos getter y setter no están exentos de cierta polémica. Hay gente que los defiende, y gente que opina que incluso no son necesarios.

Entre los detractores, el argumento principal es que no tiene mucho sentido crear métodos para todas las variables, simplemente para acceder a ellas. Para eso, ¿por qué no simplemente usar las variables directamente?

Yo os cuento la versión clásica a favor de su existencia. En teoría, las variables de un objeto deben ser siempre privadas, ya que constituyen el estado interno de la instancia.

El acceso a ellas debe ser “controlado”, y para ello existen los métodos getter y setter. De igual forma que tu no dejas a alguien cualquiera que te meta mano en la tripa, y te toquetee los riñones.

De esta forma, los métodos getter y setter permiten ocultar la implementación interna de una clase y exponer solo lo necesario. Esto protege la integridad de los datos, añadir validaciones, y evitar accesos no controlados.

Por otro lado, al acceder mediante métodos getter y setter, siempre me da una cierta libertad para modificar y mantener el comportamiento de una clase, por ejemplo ante cambios futuros.

Además, a diferencia de variables, yo puedo sobre escribir el comportamiento de los métodos getter y setter en clases hijas. Lo cuál, es una gran ventaja, y además facilita tareas como el testeo.

En cualquier caso, si usáis métodos getter y setter, la primera norma es mantenerlos simples y claros. Tienen que ser funciones muy ligeras, que hagan una mínima validación y nada más.

Nada de leer de una base de datos, de hacer un cálculo complicado, o ninguna otra tarea pesada o side effects. Los métodos getter y setter tienen que ser sencillos y rápidos.

Para aliviar un poco la sobrecarga que supone tener que definir métodos getter y setter para todas las variables, muchos lenguajes implementan el concepto de Propiedades, que veremos en el siguiente artículo.