Sobes.tech
Middle

¿Significa esto que la clase es inmutable si tiene una propiedad pública en la clase?

sobes.tech AI

Respuesta de la IA

No.

Una propiedad pública en una clase significa que el valor de esa propiedad puede ser modificado desde fuera del objeto. Un objeto inmutable es aquel cuyo estado (valores de sus propiedades) no puede ser cambiado después de su creación. La presencia de una propiedad pública contradice el principio de inmutabilidad.

Para lograr la inmutabilidad, la clase debe cumplir con las siguientes condiciones:

  • Todas las propiedades deben ser privadas (private) o protegidas (protected).
  • No debe haber setters (métodos que cambien los valores de las propiedades).
  • Todas las dependencias (objetos con los que trabaja la clase) también deben ser inmutables o su estado no debe cambiar desde fuera.
  • El constructor debe inicializar completamente el objeto y no debe ser modificado después de su creación.
  • Si se requieren cambios, se deben crear nuevas instancias del objeto con los nuevos valores.

Ejemplo de una clase con una propiedad pública (mutable):

<?php
class MutableObject
{
    public $value; // Propiedad pública

    public function __construct($value)
    {
        $this->value = $value;
    }
}

$obj = new MutableObject(10);
echo $obj->value; // 10

$obj->value = 20; // Valor cambiado desde fuera
echo $obj->value; // 20

Ejemplo de implementación de una clase inmutable:

<?php
class ImmutableObject
{
    private $value; // Propiedad privada

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function getValue() : int
    {
        return $this->value;
    }

    // Método para "cambiar" el valor, en realidad crea un nuevo objeto
    public function withValue(int $newValue) : self
    {
        return new self($newValue);
    }
}

$obj1 = new ImmutableObject(10);
echo $obj1->getValue(); // 10

// $obj1->value = 20; // Error: No se puede acceder a la propiedad privada

$obj2 = $obj1->withValue(20); // Se crea un nuevo objeto
echo $obj1->getValue(); // 10 (el objeto original no cambió)
echo $obj2->getValue(); // 20 (nuevo objeto con valor cambiado)