2012-05-16 20 views
12

He visto algunos proyectos en los que las clases tienen métodos get y set para manipular datos de inserción. Permítanme tener un ejemplo aquí:¿Vale la pena hacer los métodos get y set en OOP?

class Student extends dbClass 
{ 
    private $TableID; 
    private $FullName; 
    private $Gender; 
    private $Address; 




    function setTableID($Value) 
    { 
     $this->TableID = $Value; 
    } 

    function getTableID() 
    { 
     return $this->TableID; 
    } 

    function setFullName($Value) 
    { 
     $this->FullName = $Value; 
    } 

    function getFullName() 
    { 
     return $this->FullName; 
    } 

    function setGender($Value) 
    { 
     $this->Gender = $Value; 
    } 

    function getGender() 
    { 
     return $this->Gender; 
    } 

    function setAddress($Value) 
    { 
     $this->Address = $Value; 
    } 

    function getAddress() 
    { 
     return $this->Address; 
    } 


    function UpdateStudent() 
    { 
     $sql = "UPDATE INTO usertable SET 
     FullName = '".$this->getFullName()."', 
     Gender = '".$this->getGender()."', 
     Address = '".$this->getAddress()."' 
     where TableID='".$this->getTableID()."'"; 
     $this->query($sql); 
    } 
} 

Above es la clase de ejemplo que he visto. Y debajo está el proceso de cómo lo están usando:

$student = new Student; 
$student->setTableID = 1; 
$student->setFullName('My Name'); 
$student->setGender('Male'); 
$student->setAddress('this is my address'); 

$studen->UpdateStudent(); 

¿Vale la pena hacerlo de esta manera? Personalmente creo que es inútil establecer un campo y luego obtener y actualizar registros en él. Realmente lleva mucho tiempo hacerlo para cada módulo. ¿Cuál es la mejor manera de manejar tal cosa? ¿Hay algún problema de seguridad al hacerlo de esta manera?

+1

Los modificadores de acceso (como 'privado') a menudo se malinterpretan como característica de seguridad. En su encarnación actual de C++, en realidad tenían la intención de limitar la exposición ABI (no API); que realmente no es tan relevante para PHP y los lenguajes de scripting. Exigir setters y getters suele ser un efecto secundario, pero no está muy orientado a objetos. Ver también [Getters y setters de PHP: malvado o mal necesario?] (Http://berryllium.nl/2011/02/getters-and-setters-evil-or-necessary-evil/) y [Java: Getters y setters son evil] (http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html) – mario

+0

posible duplicado de [¿Es realmente así de malo no usar setters y getters?] (http://stackoverflow.com/questions/808348/is-it-really-that-wrong-not-using-setters-and-getters) – mario

Respuesta

10

¿Vale la pena hacerlo de esta manera?

Depende.

Haciendo abstracción de un campo por parte del usuario mediante la exposición de una propiedad "inteligente" (es decir getter y/o colocador) tiene dos desventajas:

  1. Usted tiene que escribir más código; si la propiedad realmente no hace nada inteligente, este es un código que no hace nada útil.
  2. El usuario de la propiedad es un poco molesto porque tienen que escribir un poco más también.

Y tiene una ventaja:

  1. En el futuro se puede añadir lógica para las propiedades incluso si antes no había sin romper el código de sus usuarios.

Si esta ventaja es significativa (por ejemplo, si está escribiendo una biblioteca de software reutilizable), tiene mucho sentido escribir propiedades en lugar de campos vacíos. Si no, estás trabajando sin ningún beneficio.

¿Cuál es la mejor manera de manejar tal cosa?

Puede anular las mágicas __get y __set funciones (tal vez en una clase base para que pueda heredar la anulación también) a la propiedad de forma automática hacia delante accesos a sus captadores y definidores. código simplificado:

public function __get($name) { 
    $getter = 'get'.$name; 
    if (method_exists($this, $getter)) { 
     return $this->$getter(); 
    } 

    $message = sprintf('Class "%1$s" does not have a property named "%2$s" or a method named "%3$s".', get_class($this), $name, $getter); 
    throw new \OutOfRangeException($message); 
} 

public function __set($name, $value) { 
    $setter = 'set'.$name; 
    if (method_exists($this, $setter)) { 
     return $this->$setter($value); 
    } 

    $getter = 'get'.$name; 
    if (method_exists($this, $getter)) { 
     $message = sprintf('Implicit property "%2$s" of class "%1$s" cannot be set because it is read-only.', get_class($this), $name); 
    } 
    else { 
     $message = sprintf('Class "%1$s" does not have a property named "%2$s" or a method named "%3$s".', get_class($this), $name, $setter); 
    } 
    throw new \OutOfRangeException($message); 
} 

caveat.emptor: Desde __get y __set se anula, __isset y __unset debe ser anulado, así!

¿Hay algún problema de seguridad al hacerlo de esta manera?

No, ninguna (suponiendo que no inserta errores por accidente).

+0

No creo que haya ninguna lógica futura en eso. La gente de mi nueva compañía usa eso solo para realizar una cosa de base de datos. Ellos piensan que es seguro. No sé cómo se está asegurando. –

+2

@SalmanKhimani: La gente es muy mala para predecir el futuro. Si se trata de un código de empresa, busque getters y setters y no mire hacia atrás. – Jon

1

Hacer setters y getters ayuda a aplicar el encapsulamiento OOP. No estoy seguro de PHP, pero para muchos otros idiomas (Java, C++), un buen IDE (eclipse/netbeans) generará automáticamente estos setters y getters para usted.

Puede que no sea inmediatamente obvio para tipos simples, pero si se tiene que realizar algún tipo de procesamiento más complejo, entonces se vuelve más obvio.

+0

Realmente no mejoran la encapsulación de OOP, pero son más bien una solución para la falta de * propiedades * en un idioma – ThiefMaster

+0

@ThiefMaster, creo que sí ayuda si se necesita algún tipo de lógica/procesamiento para almacenar el valor. – Brady

+0

Sí, pero siguen siendo una solución desagradable. En python puedes usar vars public por ejemplo y simplemente crear una * propiedad * (que accede a funciones getter/setter personalizadas) si alguna vez necesitas lógica adicional. En C# usted crea propiedades y permite que el compilador cree el getter/setter "simple" internamente (nunca las ve y no son funciones reales a las que puede llamar directamente) y si alguna vez necesita una lógica personalizada, simplemente implemente esas funciones por tu cuenta Sin embargo, acceder a la propiedad, sin importar si hay getter/setters o no, siempre se hace a través de 'obj.prop' como una variable – ThiefMaster

5

En los idiomas que no tienen propiedades (miembro público "variables" que en realidad conducen a llamadas de función) utilizando usualmente getter/setters en lugar de variables públicas. De lo contrario, no puede agregar lógica (por ejemplo, al establecer una variable) más adelante si las personas ya están usando su campo simple.

Dado que PHP es un idioma (lamentablemente) la respuesta es sí, úselos.