Comunidad de diseño web y desarrollo en internet online

Mejora tus habilidades como programador

Casi todos los programadores de PHP hemos partido de una pesadilla de código así:

Código :

<h1>Usuarios</h1>
<select name=”users”>
<?php
$sql = "SELECT first_name, last_name from users";
$q = mysql_query($sql);
while ($user = mysql_fetch_obj($)): ?>
<option <? if (isset($_GET[‘user_id’]) && $_GET[‘user_id’] == $user->id): ?> selected=”selected” <?php endif; ?>><?= $user->first_name ?> <?= $user->last_name ?></option>
<?php endwhile ?>
</select>


Quizás hasta nos llegamos a sentir orgullosos de mezclar PHP + MySQL + HTML ¡En menos de 10 líneas de código!

Pero ser un buen programador no consiste en cuán críptico e indescifrable sea tu código ni cuántas instrucciones puedas crear en una sola línea. Vean el siguiente ejemplo, extraído de un framework PHP:

Código :

return '<li class="admin_action_delete">'.link_to(__($params['label'], array(), 'admin'), $this->getUrlForAction('delete'), $object, array('method' => 'delete', 'confirm' => !empty($params['confirm']) ? __($params['confirm'], array(), 'admin') : $params['confirm'])).'</li>';


(He visto ejemplos mucho peores, pero como suele pasar, ahora que necesito uno, no consigo).

Predicción de comentario:

programador :

Duilio, me decepcionas, ¿Dices ser un super programador pero no puedes entender esa línea de código? Es un helper que crea una lista con un link a una ruta para eliminar un item y tiene la opción de que se requiera confirmar si se desea eliminar o no. Además es multi idioma y…




Pufff… ¿Y cuanto tiempo te llevó analizar todo eso? ¿Cuánto tiempo va a pasar hasta que necesites volver a leer esa línea nuevamente y tengas que analizarla otra vez porque se te olvidó lo que hacía?

Un código se escribe una vez, pero se tiene que leer luego muchas veces


Cada minuto que no quisiste gastar separando un poco tu código para que fuese más legible, serán uno o dos minutos que gastarás tratando de entenderte a ti mismo cuando requieras hacer un cambio o corregir un bug.

Hay un dicho famoso que dice “programa como si la persona que va a mantener tu código fuese un asesino en serie que sabe donde vives”.

Toma el tiempo que a ti mismo te va a costar entender lo que hiciste y multiplícalo por 5: ese es el tiempo que tus colegas van a perder leyendo tu código, y van a odiarte, no van a invitarte a sus fiestas ni a presentarte a sus amigas y ruega a Dios que alguno no sea un psicópata capaz de preparar ricino y ponerlo en tu café.

Pero ahora tenemos MVC y toda esta pesadilla de código espagueti terminó para siempre ¿No?

Lamentablemente, no. Ahora se ha vuelto un poco más sutil, estoy cansado de ver código como éste:

Código :

<?php
//Controlador
$users = User::all();
$selected_user = Input::get(‘user_id’, null);
return $View::make(‘users/list’, compact($users, $selected_user)); 


Código :

<!-- Vista -->
    <select name="users">
    <? foreach ($users as $user): ?>
    <option <? if ($selected_user == $user->id): ?>  selected=”selected” <?php endif; ?> value=”<?= $user->id ?>”><?= $user->first_name ?> <?= $user->last_name ?></option>
    <? endforeach; ?>
    </select>


Hablando en general, los programadores aprendieron el concepto de separar la lógica del controlador de la vista, pero muy pocos realmente saben encapsular su lógica dentro de la capa del modelo.

En el ejemplo anterior el controlador está muy bien. Es la vista lo que está fallando.

Supongamos que luego necesitamos un filtro por usuarios en otros módulos de nuestra aplicación.

¿Qué harán? ¿Copiarán y pegaran el mismo código? No. Crearán una vista llamada partials/select_users.php de manera que puedan sólo incluirla cada vez que necesiten el select? Mejor, pero no.

¿Qué pasa si el cliente pide que el nombre completo del usuario (first_name + last_name) se complemente con un “title” como Dr. o Ing.? Tendrías que modificar varias vistas de tu código.

¿Qué pasa si en un módulo en específico necesitas imprimir una lista de usuarios (<ul> <li>) o radios en vez de usar un select? Tendrías que duplicar la lógica de negocios (imprimir una lista de usuarios por nombre completo) para cubrir los cambios en el HTML.

Todo esto trae esfuerzos adicionales que podrían evitarse desde un principio. Insisto: cada minuto “ahorrado” en un inicio serán minutos desperdiciados luego.

Veamos cómo mejorar el ejemplo:

1. Si estás trabajando con un framework que incluya un ORM como Ruby on Rails o Laravel en PHP y muchos otros

... seguramente puedes crear propiedades “virtuales”. En Laravel:

Código :

<?php
// Modelo User.php
    public function getFullNameAttribute()
    {
        retrun $this->first_name . ' ' . $this->last_name;
    }


Aunque tu columna “full_name” no exista en la tabla “users” gracias al código anterior podrás acceder a ella como si existiera, siempre que trabajes con tu modelo User:

Código :

<?php $user->full_name ?>


2. Pasa la lógica para generar una lista de usuarios igualmente al modelo:

Código :

    public static function listByName()
    {
        $users = User::all();
        
        $list = array();
        
        foreach ($users as $user)
        {
            $list[$user->id] = $user->full_name;
        }
        
        return $list;
    }


De forma que en cualquier lugar de tu aplicación donde lo necesites podrás retornar la lista de usuarios por nombre simplemente haciendo lo siguiente:

Código :

$user = User::listByName()


3. Utiliza el poder de tu framework (Helpers, etc.)

En Laravel, así como en muchos otros frameworks, hay utilidades que te permiten hacer tareas comunes, por ejemplo en Laravel no necesitas generar un select manualmente, por lo que puedes hacer lo siguiente:

Código :

<?php HTML::select('users', User::listByName(), $selected_user) ?>


¡Lee la documentación de tu framework favorito y aprende qué puede hacer por ti!

¿No usas ningún framework?

Probablemente seas de esas personas super interesantes que prefieren salir a cazar su propia comida en vez de ir al automercado, en ese caso, no es muy difícil crear pequeños componentes que faciliten tus tareas comunes:

Código :

    function options($options, $selected = null)
    {
        $html = "";
        foreach ($options as $idx => $value)
        {
            $select = $selected == $idx ? ' selected="selected"' : '';
            $html .= '<option value="' . $idx . '"' . $select . '>' . $value . '</option>';            
        }
        return $html;
    }


Código :

<h1>Usuarios</h1>
<select name="users">
<?php
    $selected_user = isset ($_GET['user']) ? $_GET['user'] : null;
    options(user_list_by_name(), $selected_user);
?>
</select>


Algunos consejos a tener en cuenta:


Primero piensa en legibilidad y luego en optimización: el código espagueti presentado al inicio del post probablemente se ejecuta unos milisegundos más rápido que las otras opciones más elaboradas.

Hoy en día tenemos servidores MUY potentes, y siempre es mucho más barato comprar un poco más de memoria RAM (en caso de que haga falta) que contratar a otro programador. La diferencia de tareas tan sencillas como un IF o un ciclo no será notable. Piensa en optimizar, pero primero en optimizar el tiempo humano de correción, expansión y mantenimiento del proyecto, luego en el tiempo de procesamiento.

Si este post te comienza a volver improductivo, ignóralo por ahora, sigue trabajando en la forma en que te permita codificar más rápido y cumplir tus compromisos, poco a poco a medida que sientas la necesidad volverás a recordar los consejos acá descritos y empezarás a aplicarlos en tus próximos proyectos. No tienes que cambiar radicalmente de un día para otro.

Mi intención no es sólo enseñarles Laravel sino hacerles mejores programadores en general. Un proyecto con Rails no garantiza un código limpio, así, un proyecto hecho a pie en PHP no tiene que ser un desastre. Unos lenguajes y frameworks te ayudan a escribir mejor código que otros y en esto PHP no tiene fama de ser precisamente el mejor, sin embargo al final depende de cada programador.

En orden de importancia para mí sería: Programador > Framework > Lenguaje.

Recuerden seguirme en Twitter @sileence para poder notificarles de más artículos de programación en general y Laravel.

También recomiendo que aprovechen la promoción de mejorando.la/navidad, en el 2014 se viene un curso de Laravel donde espero poder compartir más con ustedes y ampliar los conocimientos que he ido impartiendo acá en Cristalab :)

¡Saludos!

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

El autor de este artículo ha cerrado los comentarios. Si tienes preguntas o comentarios, puedes hacerlos en el foro

Entra al foro y participa en la discusión

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate