2010-09-03 10 views
8

Estoy haciendo la transición al uso de OOP para todos mis proyectos, históricamente todo lo que he construido ha sido bastante pequeño y OOP no parecía ser una opción eficiente, pero ahora con grandes proyectos sí lo es. Sin embargo, más recientemente me he encontrado con más y más preguntas de "mejores prácticas" que tengo y no puedo encontrar la respuesta.PHP OOP Theory - ¿Error al verificar dentro o fuera de la clase?

Por ejemplo, imagina que tengo el siguiente:

class numbers{ 

    function __construct($number){ 
     $this->number = (int)$number; 
    } 

    function add($add){ 
     $this->added = $this->number + $add; 
    } 

    function multiply($multiply){ 
     $this->multiplied = $this->number * $multiply; 
    } 

    function minus($minus){ 
     $this->minused = $this->number - $minus; 
    } 

    function number(){ 
     return $this->number(); 
    } 
} 

Ahora vamos a decir que quiero aplicar add, entonces multiply y luego minus. Cada etapa puede fallar (no incluí eso en el ejemplo, pero imagino que está allí). Aquí es donde radica mi problema, debería hacer:

$numbers = new numbers(8); 
if($numbers->add(7)){ 
    if($numbers->multiply(6)){ 
     if($numbers->minus(7){ 
      echo $numbers->number(); 
     }else{ 
      echo 'error minusing'; 
     } 
    }else{ 
     echo 'error multiplying number'; 
    } 
}else{ 
    echo 'error adding number'; 
} 

O debería tener esa parte en mi constructor, como:

class numbers{ 

    function __construct($number){ 
     $this->add(6); 
     $this->multiply(9); 
     $this->minus(7); 
     if($this->error){ 
      return false; 
     }else{ 
      return true; 
     } 
    } 

    function add($add){ 
     $this->added = $this->number + $add; 
     if(!this->added){ 
      $this->error = "couldn't be added"; 
     } 
    } 

    function multiply($multiply){ 
     $this->multiplied = $this->number * $multiply; 
     if(!this->multiplied){ 
      $this->error = "couldn't be multiplied"; 
     } 
    } 

    function minus($minus){ 
     $this->minused = $this->number - $minus; 
     if(!this->minused){ 
      $this->error = "couldn't be minused"; 
     } 
    } 

    function number(){ 
     return $this->number(); 
    } 

    function error(){ 
     return $this->error(); 
    } 

} 

y luego simplemente hacer:

$numbers = new numbers(5); 
if($numbers){ 
    echo $numbers->number(); 
}else{ 
    echo $numbers->error(); 
} 

este momento si el ejemplo es largo (también ignoro los errores, lo escribí aquí solo para delinear lo que trato de hacer, este no es el código que estoy usando ...) pero no sé cómo pregunta sin un ejemplo. Básicamente, ¿debería estar revisando los errores dentro de la clase o debería hacerlo afuera cuando llamo a la clase?

+0

@FrustratedWithFormsDesigner: ¿Por qué la edición? El método se llama 'menos' - es perfectamente aceptable usar la forma del verbo en este caso. Creo que su edición hizo la pregunta más confusa, no menos. – Gian

+0

@Gian: cuando se usa un nombre de método como verbo, generalmente es mejor dejar en claro que se está hablando del método, no de un verbo general, más similar. Esto: "Quiero' agregar', luego 'multiplicar' y luego' menos'. " deja en claro que estás hablando de llamar al método 'menos', sin tratar de usar mal la palabra "menos" como verbo. – FrustratedWithFormsDesigner

+3

En el mundo de habla inglesa, se llama restar. Minus es un signo. –

Respuesta

11

Casi siempre tiene sentido imponer consistencia a las actualizaciones dentro de la clase (es decir, cada vez que un método puede modificar el estado interno de la clase, verifique la entrada). Luego use exceptions para que sea el problema del que llama si esa entrada no está bien formada, o si esa operación violará alguna clase invariante.

+3

+1 de mí. Declara cosas mejores que mi respuesta (ahora eliminada). No he tomado mi café todavía. –

0

La comprobación de errores realizada dentro de una clase debería ocuparse de las posibilidades de que falle el método de esa clase. En otras palabras, si su clase de números tiene un método de división, debe verificar para asegurarse de que el denominador no sea cero.

La comprobación de errores que se realiza en la instancia de una clase (fuera de la clase) debería llevar a verificar que se devuelven los resultados correctos de una propiedad o método de clase. Como normalmente esto no debería suceder con una clase bien diseñada, normalmente se verifican casos extremos.

Sin embargo, cuando comienzas a tener una clase que realiza un seguimiento de varias cosas como tu caso, normalmente separaría la clase aún más. Cree clases para manejar sus funciones matemáticas y luego haga que su clase de números use esas clases de matemáticas. De esta forma tendrá una mejor separación de preocupaciones, un código más ordenado y pruebas más fáciles.

+0

debes votar mi respuesta entonces. por lo poco que hice, ciertamente agregué cheques por cada posible cosa que podría salir mal (excepto cosas locas como la falta de memoria). –

0

Personalmente, me mantendría alejado de lo que está tratando de hacer en el constructor en el segundo ejemplo. Implementa códigos duros e infringe el information hiding principal. De lo contrario, sin saber lo que hace internamente la clase, cuando lo hace $num = new Number(8);, es difícil entender por qué usted está recibiendo 47 volver ... También viola el magic number principal sin ...

En cuanto a los métodos, se ven muy bien a yo. Es posible que desee lanzar una excepción en esos casos o devolver un booleano. Lo que usted escoja es un factor de mucho más de lo que se discute aquí (como su preferencia, ¿qué es exactamente la clase está haciendo, convenciones, etc) ...

Ah, y usted tiene algunos problemas en bucle infinito Tu clase.function number() debería ser:

function number() { 
    return $this->number; 
} 

Y lo mismo para error() ...