Un caso sin romper

Pocas veces nos ponemos a disertar en horas de trabajo sobre metodologías, casos de uso, o formas de afrontar una u otra estructura de datos, cada vez menos la verdad. Sin embargo esta tarde ha sido bastante curioso porque nos hemos topado con la misteriosa encruzijada que he titulado como "el caso sin romper".

Siendo más específicos estoy hablando de una lógica de aplicación (llámale controlador, view, espagueti o lo sea que esté de moda ahora) en PHP. Un típico "trozo de código" en el que se han programado las funcionalidades de agregar y editar de una simple tabla de la base de datos.

A mí particularmente me gusta tener controladores separados, por lo que tendría un método add() y otro edit(). Cierto es que en un porcentaje muy elevado de ocasiones el código de ambas funciones es muy similar, muchas veces se podría mezclar y, con una simple discriminación de $id, podríamos hacer el trabajo. En ese caso creo que mi solución se iría a una función parte_comun($params) donde encapsularíamos todo ese código que no debería de estar duplicado (por ejemplo).

Dejando los bizarrismos de lado, el caso que nos llevó a la disertación fue básicamente un switch(). Ambas acciones de las que os estaba hablando (agregar y editar) se ubicaron dentro de la misma función/método, llamémosle add_edit($accion='', $id='') y dependiendo de la variable $accion se hacía una cosa u otra. Algo (esquemáticamente hablando) tal que el siguiente trozo de código:

function add_edit($accion='', $id='') {
    switch($accion) {
        case "add":
            // Lógica de add siempre que no haya id
            // Mucha de esta lógica es común a ambos
            break;
        case "edit":
            // Lógica de edit siempre que haya id
            // Mucha de esta lógica es común a ambos
            break;
    }
}

Entendible, pero el punto álgido llegó al ver el truco, dentro de ese switch() se había omitido un break por no repetir código, por lo que ambas acciones (add y edit) se llamaban secuencialmente, aunando toda la "lógica común a ambas" en uno de los case y controlando en todo momento si existía $id para no romper nada. El esquema podría ser más o menos el siguiente:

function add_edit($accion='', $id='') {
    switch($accion) {
        case "add":
            // Lógica de add siempre que no haya id
        case "edit":
            // Lógica de edit siempre que haya id
            // Lógica común a ambos que se ejecutará
            // porque en el add no hay un break
            break;
    }
}

Funciona perfectamente, aunque yo lo catalogué de solución sucia. Llegados a este punto me parecía mejor idea mantener los case del switch con sus breaks correspondientes y hacer una llamada a una función para no repetir código. Pero aún entendiendo que podría ser una práctica de primero de carrera, tampoco supe argumentar demasiado el motivo de ese sentimiento de suciedad. Mi propuesta:

function add_edit($accion='', $id='') {
    switch($accion) {
        case "add":
            // Lógica de add siempre que no haya id
            parte_comun($params);
            break;
        case "edit":
            // Lógica de edit siempre que haya id
            parte_comun($params);
            break;
    }
}

function parte_comun($params) {
    // Mucha de esta lógica es común a ambos
}

Es posible que mi mente cuando ve un switch() obvie los break porque está acostumbrada a las indentaciones de Python, o algún otro vicio adquirido a lo largo del tiempo...

Sea como fuere - espero vuestros comentarios porque yo tampoco estoy demasiado ducho en optimización de estructuras, por muy simples que parezcan - tengo que admitir que me lo pasé bien viendo el punto de vista que ofrecían mis compañeros. Aún no compartiéndolo, creo que intenté abrir la mente un poco más de lo habitual.

Espero no tener agujetas mañana.

code

About the author

Óscar
has doubledaddy super powers, father of Hugo and Nico, husband of Marta, *nix user, Djangonaut and open source passionate.
  • La cuestión es: switch($accion) { case "edit": // recuperas datos, no dejas tocar el id, ya lo tienes case "add":// creas un objeto vacío con los mismos campos del edit si no existe// si ha pasado por el edit ya no haces nada, ya tienes los campos rellenos y el id // si por el contrario entras primero por el add, al crear el objeto le pones id cero, menos uno o // lo que quieras para que al final haga un insert en vez de un update // la parte común es identica// crear y rellenar formulario// validarlo // meter en base de datos, update si id >0 o insert en otro caso break; } Pero ...Entiendo lo que dices de que otros lenguajes de programación no te permiten cerrar el switch y por ende, esto no funcionaría nunca.
  • Pongamos otro caso. Muy diferente a lo de encapsular trozos de código que se repite.Este es una caso en el que el break del switch no está donde acaba la función. switch ($this->input->post('action')){ case "crea_usuario": $arr=array(); $add=array(); $add['email'] = $this->input->post('email'); //buscar primero si existe el email y no dejarle $existe_email =$this->users_model->existeEmail($add['email'],'',$add['dominio_id']); if ($existe_email) { $partial_data=array(); $partial_data['id']=0; $partial_data['error']=lang('adm_email_usado'); $arr[]=$partial_data; echo json_encode($arr); break; } // crea el usuario y finaliza donde el break indica $id = $this->users_model->addUser($add); break;
blog comments powered by Disqus