Starting with my new project groceryList (Let’s Rock&Roll!!!!!)

https://github.com/pvergara/groceryList-back

Publicado en Uncategorized

Testing on SQL (part 3/x) «Given/When/Then style»

This time I’ll try to show you a proposal of testing on SQL by using this clear sections:

  •     Given: The context you will use to prepare some test
  •     When: The action that will be tested
  •     Then[s]: The behavior that will be expected when you ran the action.

Ok… hands on:

This time, the problem we have to solve is to get all the movies in which they work together a range of actors.

To make it, in a «bdd way» the first step is to describe some samples to assure that all the stakeholders understand the behavior:

«If I use an actor’s id that appears on 21 movies, when I query the movies of this actor, then I must receive the 21 movie’s ids where the actor appears on.»

Another example could be: «If I use the identifiers of two actors who appear in a single film in common, when I query the common movies of that actors, then I must receive one movie identifier, and that movie is the only one where these actors acts in common».

The last example will be that: «If I use the identifiers of two actors who appear in NO film in common, when I query the common movies of that actors, then I do not must receive no film identifier»

Now I’ll try to show a way to describe the samples by using SQL.

Important note: If you wanna test the code, you’ll need to obtain the »Sakila Sample Database’ (http://dev.mysql.com/doc/sakila/en/)  and the assertions and example routines are hosted on my github account (https://github.com/pvergara/Tests4Sql).

First example:

/*****************************************************************/
SET @actorKevinBloom_id=25;
SELECT
 @expected:=COUNT(*)
FROM
 `sakila`.`film_actor`
WHERE
 actor_id = @actorKevinBloom_id;

SELECT
 concat('One actor that appears in ',@expected,' movies') as
 "Given",
 @actorKevinBloom_id;
/*****************************************************************/

/*****************************************************************/
SET @actors_id=concat(@actorKevinBloom_id) ;
SELECT
 'I query the films of that actor' as
 "When",
 @actors_id as
 "(Actor id)";

CALL `sakila`.`GetTheCommonFilmsOf`(@actors_id);

/*****************************************************************/

/*****************************************************************/
SELECT @actual:=COUNT(*) FROM `sakila`.`ResultGetTheCommonFilmsOf`;

SELECT
 concat('It returns ',@expected,' films') as
 "Then",
 @expected as
 "Expected",
 @actual as
 "Actual",
 `Tests4Sql`.`AssertEquals_DECIMAL`(@expected,@actual) as
 "Assert";
/*****************************************************************/

Second example:

/*****************************************************************/
SET @actorKevinBloom_id=25,
 @actorChristianAKROYD_id=58;

SELECT
 'Two actors that appears in the same movie' as
 "Given",
 @actorKevinBloom_id,
 @actorChristianAKROYD_id;
/*****************************************************************/

/*****************************************************************/
SET @actors_id=concat(@actorKevinBloom_id, ',', @actorChristianAKROYD_id) ;
SELECT
 'I query the common films of that two actors' as
 "When",
 @actors_id as
 "(two actors)";

CALL `sakila`.`GetTheCommonFilmsOf`(@actors_id);

/*****************************************************************/

/*****************************************************************/
SELECT @actual:=COUNT(*) FROM `sakila`.`ResultGetTheCommonFilmsOf`;

SELECT
 'It returns the exact number of common films' as
 "Then",
 @expected:=1 as
 "Expected",
 @actual as
 "Actual",
 `Tests4Sql`.`AssertEquals_DECIMAL`(@expected,@actual) as
 "Assert";
/*****************************************************************/

/*****************************************************************/
SELECT
 'The common films are exactly ''Sabrina Midnight'' and no more' as
 "Then";

CALL
 `Tests4Sql`.`spAssertSameResult`
 (
 '`sakila`.`ResultGetTheCommonFilmsOf`',
 '(SELECT * FROM `sakila`.`film` WHERE film_id = 755) qryNew',
 'qryTheOldOne.`film_id` = qryTheNewOne.`film_id`'
 )
/*****************************************************************/

 Third example:

/*****************************************************************/
SET
 @actorKevinBloom_id=25,
 @actressPenelopeGUINNESS_id=1;

SELECT
 'Given two actors who DO NOT appear in any common film' as
 "Given",
 @actorKevinBloom_id,
 @actressPenelopeGUINNESS_id;
/*****************************************************************/

/*****************************************************************/
SET @actors_id=concat(@actorKevinBloom_id, ',', @actressPenelopeGUINNESS_id) ;
SELECT
 'I query the common films of that two actors' as
 "When",
 @actors_id as
 "(two actors)";

CALL `sakila`.`GetTheCommonFilmsOf`(@actors_id);

/*****************************************************************/

/*****************************************************************/
SELECT @actual:=COUNT(*) FROM `sakila`.`ResultGetTheCommonFilmsOf`;

SELECT
 'It returns the exact number of common films (no movie)' as
 "Then",
 @expected:=0 as
 "Expected",
 @actual as
 "Actual",
 `Tests4Sql`.`AssertEquals_DECIMAL`(@expected,@actual) as
 "Assert";
/*****************************************************************/

Hope this helps (maybe someone who want to refactor her sql routines 😉 )
 

Tagged with: , , ,
Publicado en BasesDeDatos, Database, Testing

Testing on SQL (part 2/x) spAssertSameResult with samples

Now I’m going to show you more complex code and a sample case.

This time the SQL was written using MySQL.

At this time I’m gonna use two different schemas:

  • sakila (Sample Database created for MySQL servers)
  • Tests4SQL Database where the test functionallity will be placed

Ok…hands on:

First the code for the test functionallity:

DROP PROCEDURE `Tests4Sql`.`spAssertSameResult`;

DELIMITER //
CREATE PROCEDURE `Tests4Sql`.`spAssertSameResult`
(
 oldQryName varchar(256),
 newQryName varchar(256)
)
BEGIN
SET @dyn_sql=CONCAT('
SELECT
 (
 CASE WHEN count(*) = (select count(*) from ',oldQryName,') THEN
 ''GREEN''
 ELSE
 ''RED!!!''
 END
 ) as "Assert_SqlCodeSeemsSimilar"
FROM
(
 SELECT * FROM ',newQryName,'
) qryTheNewOne
 INNER JOIN
(
 SELECT * FROM ',oldQryName,'
) qryTheOldOne
 ON
 (
 qryTheNewOne.city_id = qryTheOldOne.city_id
 );');
PREPARE s1 from @dyn_sql;
EXECUTE s1;

DEALLOCATE PREPARE s1;
END //

DELIMITER ;

Second the same functionality written in different ways:

DROP PROCEDURE `sakila`.`sp_add_some_spanish_cities_hard_to_mantain_version`;
DELIMITER //

CREATE PROCEDURE `sakila`.`sp_add_some_spanish_cities_hard_to_mantain_version`()
BEGIN

/*
 List extracted from the wikipedia:
 http://es.wikipedia.org/wiki/Anexo:Provincias_de_Espa%C3%B1a_por_c%C3%B3digo_postal
 */
 IF NOT EXISTS(select * from `sakila`.`city` WHERE `sakila`.`city`.`city_id` = 8701) THEN
 INSERT INTO
 `sakila`.`city`
 (
 city_id,
 city,
 country_id
 )
 VALUES
 (
 8701,
 'Álava (Vitoria)',
 87
 );
 ELSE
 UPDATE
 `sakila`.`city`
 SET
 city = 'Álava (Vitoria)',
 country_id = 87
 WHERE
 city_id = 8701;
 END IF;

IF NOT EXISTS(select * from `sakila`.`city` WHERE `sakila`.`city`.`city_id` = 8702) THEN
 INSERT INTO
 `sakila`.`city`
 (
 city_id,
 city,
 country_id
 )
 VALUES
 (
 8702,
 'Albacete',
 87
 );
 ELSE
 UPDATE
 `sakila`.`city`
 SET
 city = 'Albacete',
 country_id = 87
 WHERE
 city_id = 8702;
 END IF;

IF NOT EXISTS(select * from `sakila`.`city` WHERE `sakila`.`city`.`city_id` = 8703) THEN
 INSERT INTO
 `sakila`.`city`
 (
 city_id,
 city,
 country_id
 )
 VALUES
 (
 8703,
 'Alicante',
 87
 );
 ELSE
 UPDATE
 `sakila`.`city`
 SET
 city = 'Alicante',
 country_id = 87
 WHERE
 city_id = 8703;
 END IF;
 IF NOT EXISTS(select * from `sakila`.`city` WHERE `sakila`.`city`.`city_id` = 8704) THEN
 INSERT INTO
 `sakila`.`city`
 (
 city_id,
 city,
 country_id
 )
 VALUES
 (
 8704,
 'Almería',
 87
 );
 ELSE
 UPDATE
 `sakila`.`city`
 SET
 city = 'Almería',
 country_id = 87
 WHERE
 city_id = 8704;
 END IF;

IF NOT EXISTS(select * from `sakila`.`city` WHERE `sakila`.`city`.`city_id` = 8705) THEN
 INSERT INTO
 `sakila`.`city`
 (
 city_id,
 city,
 country_id
 )
 VALUES
 (
 8705,
 'Ávila',
 87
 );
 ELSE
 UPDATE
 `sakila`.`city`
 SET
 city = 'Ávila',
 country_id = 87
 WHERE
 city_id = 8705;
 END IF;

/*... and so on*/
END //

DELIMITER ;

 

DROP PROCEDURE `sakila`.`sp_add_some_spanish_cities_another_way_to_make_it_version`;

DELIMITER //
CREATE PROCEDURE `sakila`.`sp_add_some_spanish_cities_another_way_to_make_it_version`()
BEGIN

/*
 List extracted from the wikipedia:
 http://es.wikipedia.org/wiki/Anexo:Provincias_de_Espa%C3%B1a_por_c%C3%B3digo_postal
 */
 CREATE TABLE in_memory_aux_table ENGINE = MEMORY
 select 8701 as id, 'Álava (Vitoria)' as name, 87 as country_id
 UNION ALL
 select 8702 as id, 'Albacete' as name, 87 as country_id
 UNION ALL
 select 8703 as id, 'Alicante' as name, 87 as country_id
 UNION ALL
 select 8704 as id, 'Almería' as name, 87 as country_id
 UNION ALL
 select 8705 as id, 'Ávila' as name, 87 as country_id
 ;
 /*... and so on*/

UPDATE
 `sakila`.`city`
 INNER JOIN
 in_memory_aux_table as qry
 ON (`sakila`.`city`.`city_id` = qry.id)
 SET
 `sakila`.`city`.city = qry.name,
 `sakila`.`city`.country_id = qry.country_id
 ;

INSERT INTO
 `sakila`.`city`
 (
 city_id,
 city,
 country_id
 )
 SELECT
 qry.id,
 qry.name,
 qry.country_id
 FROM
 in_memory_aux_table as qry
 LEFT JOIN
 `sakila`.`city` as cities
 ON (qry.id = cities.city_id)
 WHERE
 cities.city_id IS NULL;

DROP TABLE in_memory_aux_table;
END //

DELIMITER ;

And third… the test!!!:

USE `sakila`;

CALL `sakila`.`sp_add_some_spanish_cities_hard_to_mantain_version`();

CREATE TABLE first_attempt ENGINE=MEMORY
SELECT
 `city`.`city_id`,
 `city`.`city`,
 `city`.`country_id`,
 `city`.`last_update`
FROM
 `sakila`.`city`
WHERE
 `sakila`.`city`.country_id = 87
 AND
 `sakila`.`city`.city_id >=8701;

CALL `sakila`.`sp_add_some_spanish_cities_another_way_to_make_it_version`();

CREATE TABLE second_attempt ENGINE=MEMORY
SELECT
 `city`.`city_id`,
 `city`.`city`,
 `city`.`country_id`,
 `city`.`last_update`
FROM
 `sakila`.`city`
WHERE
 `sakila`.`city`.country_id = 87
 AND
 `sakila`.`city`.city_id >=8701;

CALL `Tests4Sql`.`spAssertSameResult`('`sakila`.`first_attempt`','`sakila`.`second_attempt`');

DROP TABLE first_attempt;
DROP TABLE second_attempt;

Hope this helps!!!!.

Tagged with: , ,
Publicado en BasesDeDatos, Database, Testing

Ensuring that your «refactored SQL code» has the same behaviour that the older one

Try this one:

SELECT
    [Assert_SqlCodeSeemsSimilar] =
    --Maybe this part must be encapsulated on some kind of "fnTest4SQL_SameResult" scalar-function
    (
        CASE WHEN count(*) = <qryTheOldOne_Counter> THEN
            'GREEN'
        ELSE
            'RED!!!'
        END
    )
FROM
(
    <The new code>
) qryTheNewOne
        INNER JOIN
(
    <The old code>
) qryTheOldOne
    ON
    (
        qryTheNewOne.SomeField1 = qryTheOldOne.TheSameField1
            AND
            --The number of "AND statements" depends on the number of fields you want to join.
            --    Is important to think that, in some cases, you only need <Id_Fields> (for example
            -- if the queries only returns fields related with well-normalized database tables) BUT
            -- ALSO you must have to be careful with calculated fields.
        qryTheNewOne.SomeField2 = qryTheOldOne.TheSameField2
            ...
            ...
            ...
            AND
        --Null values sample
        (
            qryTheNewOne.SomeFieldN_NumberWithNullValues = qryTheOldOne.SomeFieldN_NumberWithNullValues
                OR
            (
                qryTheNewOne.SomeFieldN_NumberWithNullValues IS NULL
                    AND
                qryTheOldOne.SomeFieldN_NumberWithNullValues IS NULL
            )
        )
    )

Hope this helps

Tagged with: , , ,
Publicado en Database, software, Uncategorized

Testing on SQL (part 1/x)

An early implementation of what, I think, should be an assertEquals on «SQL code»

Please try to «translate it» to another SQL-Syntax (just like ANSI-SQL), because I will write using de T-SQL syntax:

CREATE FUNCTION dbo.fnTest4SQL_AssertTrue
(
    @Expected as bit,
    @Actual as bit
)
RETURNS NVARCHAR(256)
AS

BEGIN
    DECLARE @RESULT AS nvarchar(256)
    SELECT
        @RESULT =
        (
            CASE WHEN @Expected=@Actual THEN
                'GREEN'
            ELSE
                '______RED______'
            END
        )
    RETURN @RESULT
END
GO

Hope this helps

Tagged with: , ,
Publicado en Database, Uncategorized

Adiós baby ubuntu, adiós (Parte I).

Este fin de semana iba yo a ponerme a hacer cosas con Linux, y me dio una pereza enorme. Después de mucho pensar (y darme un poco de lástima porque yo siempre fui un «linuxero» bastante radical) llegué a la conclusión de que hace tiempo empecé a perder el interés (y las ganas de usar linux) por un único motivo: La distro que llevaba años usando, había cambiado de tal forma que me generaba cierta aversión.

El problema no era sólo la parte visual aunque seguramente fue lo que mas influyó, también había problemas con drivers y no sé, otros «»»pequeños detalles»»» que en el día a día van restando puntos y al final, generan una sensación de desasosiego muy grande al ir a utilizarla.

Conclusión: UBUNTU AL CARAJO!!!!.

Paso a enseñarnos el mail que envíe a unos expertos en la materia para que me aconsejasen qué distro usar:

(La versión original del mail era un poco, vehemente, y he decidido «rebajarla»)

A las buenas nenos.

Mirad, estoy cansado… hastiado … vamos HASTA ARRIBA, del puñetero Ubuntu, quiero un linux de verdad!!!! y necesito que me recomendéis.

Estaba a punto de descargarme el Debian pero me acordé de «su lado oscuro»: ‘Mais pechado que unha porta que sempre se abre polo outro lado’, super radical de la muerte (como me dé por mirar flash… voy de fastidiado… supongo), y tardaré en actualizar a siguientes versiones AÑOS (entre forzen… pre-frozen y post-frozen…jajaja).

Pero bueno si no hay mas remedio tiro por él… lo que si me gustaría es que la distro que elija tenga en cuenta mas o menos estos puntos:

  • Una cosa es configurar y «fine-tunear» servers (que seguro que me toca) tipo Apache, MySQL, o configuraciones de php… y otra cosa (que es lo que NO quiero) sería tener que meterme en «/etc/» para pedir permiso para ir al baño… no sé si me explico… NO QUIERO PERDER EL TIEMPO EN COSAS SUPERTRIVIALES.
  • Nada de bajarse paquetes y esperar 4horas mas hasta que termine de compilar (sii siii, sé las ventajas de que tenga todo super-personalizado para mi ordenador y mega tuneado… pero NO TENGO TIEMPO PARA BOBADAS que quizás me mejoren algo el 10% del tiempo… pero entre tanto habré perdido el 90% 😐 )… dicho de otra forma… Geento NI DE COÑA!!! 🙂
  • Tengo un Acer Travelmate (portátil con 2 años) y pocas ganas de matarme con drivers y bobadas… si, sé donde me meto..y sé que no me libra nadie de tener que hacer algo para que la gráfica realmente funcione bien… pero por favor!!!… es que ahora me estoy peleando con la condenada Wifi!!!!… Y HASTA AQUÍ LLEGAMOS.
  • No soy cool NO QUIERO WINDOWMANAGERS COOL!!!!… de hecho QUIERO TRABAJAR… ojo… hay una diferencia entre WM no cool y bodrio absoluto (si pudiera volver a los gnome DE VERDAD… con su barrita arriba… o abajo sus applets de cpu mem y net… SERÍA LA PERSONA MAS FELIZ DEL MUNDO!!!!)

Bueno ahí va todo, a ver si me podéis ayudar… y sino… volveré a Debian…jajaja.

Quiero volver a enamorarme de Linux…y una buena distro ayuda bastante (y dejar ubuntu… mas!!!!!)

Fué un mail muy cartártico, y muy útil porque ese mismo día estaba instalando una nueva distribución de linux con la que estoy muuuuy contento…. pero de eso hablaré en el siguiente post.

Un saludo!!!

Por cierto gracias a los sabios que me recomendaron la distro :-).

Tagged with:
Publicado en Linux, Opinión, software

WordPress 3.0.1 ERD

This is the first entity-relationship diagram (ERD) of a series of posts I want to publish with the ERD of the most famous open-source projects nowadays.
This is my first post in English too so, even if I hope to not make any mistakes I’d feel very thankful if anyone found an error and mail me (pablocristobal@gmail.com) to improve these publications.
Visual Architect (Professional edition): This is the tool I’m using to make the diagrams. I do know open-source tools like mysql-workbench (I’m working with that one too), dia, and commercial software like Microsoft Visio (the company one I’m working on are Microsoft Partners and I’m using this one too) to make entity-relationship diagrams, but I’m pretty sure that Visual Architect is better than the others.
Hope this helps someone.

Post model

Links model

Terms model

Users model

Options model

Quique I wanna thank you for the review 🙂

Publicado en Database, ERD, software engineering

IE9 Beta… ¿pre-alpha?

Llevo mucho tiempo sin escribir en el blog y, sinceramente, cuando lo cree, no estaba dentro de mis planes escribir entradas «de opinión» sobre productos (y menos aun, si estos productos no tienen relación directa con el mundo del desarrollo del software), pero, es que veo la necesidad de expresarme, y carajo, no voy a crear otro blog sólo para esto… digo yo :-|.

Bueno al tema, esta nueva entrada se centra en comentar mi experiencia (triste, traumática, y sin ningún «final feliz») con la nueva versión EN BETA (primer chiste), del navegador web gratuíto (pero no para todo el mundo) de la compañía de Redmon: Internet Explorer 9 (al que le gustaría que aquí hubiera puesto un enlace… que espere sentadito, que no voy a facilitarle las cosas a ningún martir).

A ver, antes que nada indicar que lo que pongo en la cabecera, para mi, no es coña alguna, que la peña de Microsoft tenga el valor de llamar a este producto Beta, ya de por si no tiene desperdicio. O eso, o es que para mi el concepto de Beta es mas estricto que alguno de estos puntos:

  • «Descargate-El-Producto-Cuatro-Veces-Y-Después-Te-Darás-Cuenta-Que-Tienes-Que-Acceder-A-Otro-Enlace-Porque-Desde-El-Oficial-No-Hay-Forma-De-Que-Se-Entere-Que-Tu-Ordenador-Está-En-Español«
  • «Aunque-El-Software-En-Si-Viene-Con-Un-Instalador-Online-Al-Ser-El-Usuario-1.000.000-Te-Toca-Bajarte-Ciertos-Parches-Para-Tu-Vista-A-Manini«
  • (ESTE ES, SIN LUGAR A DUDAS, MI FAVORITO!!!) «Muy-Bien-Chaval-Has-Conseguido-Pasar-Todas-Las-Pruebas-Iniciales-Que-Te-Hacen-Merecedor-Del-Santo-Grial-De-La-Mona-Lissa-Y-Del-IE9-Pero-Ahora-Cuando-Lo-Instales-Ten-Bien-Preparado-El-Sistema-De-Puntos-De-Recuperación-Porque-Cuando-Lo-Abras-Caerás-En-Un-Bucle-Infinito-De-Pantallas-De-Error-Y-Simpáticas-Ventanitas-Preguntándote-Si-Quieres-Que-Este-Super-Cagarro-Sea-Tu-Navegador-Por-Defecto-Que-Además-Se-Mezclarán-Con-La-Gran-Gran-Graaaan-Utilidad-Creada-Para-Que-Si-Se-Produce-Un-Error-Fatal-Intente-Cargar-De-Nuevo-La-Aplicación-Como-Reza-Tu-Blog-‘Hasta-El-Infinito-(DeTuPaciencia)-Y-Mas-Allá‘»

AAAAAgggghh…. carajo, que agusto me he quedado.

Bueno, ahora, la coña es que, este supermegaproducto, que, parece ser que es la leche en el AcidTest3, que es el mas estándar del mundo con el html5, además que «es una mooonaaadaaaaa» (¿donde carajo están las fotos de Kitty cuando las necesito?)… sooooloo tiene, nada, un detalle sin importancia… una minucia de nada que lo hace… como menos asequible que los demás… y por eso muuuucho mas interesante: EL CARAJO DEL NAVEGADOR SOLO PARECE QUE SERVIRÁ PARA LAS VERSIONES DE VISTA 32Bits (ni la peña de MS, se dió cuenta que había otra versión del vista… ironías de la vida) O PARA WIN7… ahora si 32/64Bits… y yo me pregunto… no no, de verdad, ¿Porqué un producto de software tan imprescindible como es un navegador, en vez de ser lo mas abierto posible, sólo sirve para dos de las versiones del S.O.?…a ver, que soy informático, y puedo entender los motivos técnicos (tecnología .NET… digo yo), potenciar las últimas versiones y enterrar de una vez el XP, etc. Pero, es que la pregunta la hago desde «mi lado» cliente o mejor dicho, consumidor de un software y, sinceramente, cuando chrome, Firefox u otros navegadores lleguen a los niveles de puntos cumplidos en el AcidTest3 como lo hace elIE9 (bueno… o eso dicen, porque, si no ha quedado claro aun, el menda no ha podido probarlo 😦 )… seguirán funcionando para todo tipo de versiones de Windows, ADEMÁS, de para otros sistemas operativos, tanto de escritorio como de móviles… o sea que, sinceramente, no sé para qué carajo se matan en sacar un navegador con tan buena pinta, y ponerlo tan difícil para que la peña lo pruebe… y lo que es mas, yo recomendaría que, DE VERDAD, dejen de llamar a ESO «Beta».

Un saludo.

P.D. Moi, tío, te lo juro que lo he intentado, pero no hay huev… de probar el navegador de marras… por cierto, esta entrada «va por ti».

Tagged with:
Publicado en software

Desarrollo eficaz… pero eficiente. Un difícil equilibrio.

Hace un par de días me encontraba con mi padre comentando un «cambio de rumbo» que ha dado mi vida en el entorno laboral. Uno de los temas que tocamos fue relativo al hecho de que, recientemente estoy empezando a replantearme algunas «ideas puristas» a la hora de desarrollar software… dicho de otra forma, le doy muchas vueltas a las cosas para intentar que los sistemas que desarrollo sean lo mas estructurados posible, lo mejor comentados posible, lo mejor diseñados posible, lo mas separados en capas posible…. y eso lleva su tiempo, y claro, si lo que uno tiene que hacer es una «web chorra» o un programa, así como muy simplón, el tiempo que tardo en hacer las cosas no siempre es el esperado por el cliente.

Cuando le estaba contando esto a mi progenitor, el me comentó que «en el desarrollo de software, al igual que en cualquier ingeniería, hay que intentar que los diseños y los desarrollos, sean eficaces, pero también eficientes»… sobretodo en la empresa privada con mucha competencia.

Antes que comentar mis pensamientos sobre el tema, os recomiendo que leáis esta entrada de la Wikipedia… la parte que mas me gusta de esa Wiki es la frase que dice: «Ejemplo: matar una mosca de un cañonazo es eficaz (o efectivo: conseguimos el objetivo) pero poco eficiente (se gastan recursos desmesurados para la meta buscada). Pero acabar con su vida con un matamoscas, aparte de ser eficaz es eficiente.»

Ahora, ¿que tienen que ver las definiciones de eficaz y eficiente con el desarrollo del software?, muy simple, un desarrollo eficaz en un desarrollo que cumple con los requisitos del cliente, y un desarrollo eficiente, además, ha consumido «pocos recursos»; dicho de otra forma, hemos necesitado un equipo reducido de personas para hacerlo y lo hemos desarrollado en poco tiempo.

En el mundo del desarrollo de software (como en otras disciplinas, como la arquitectura, la ingeniería de minas, la ingeniería industrial, etc.) tenemos que tender a que nuestros desarrollos sean eficaces, pero también eficientes. Esta máxima cobra especial importancia si nuestros trabajos se realizan dentro de empresas privadas, y mas aun, cuando dichas empresas tienen mucha competencia. El motivo es obvio, cuanta mas gente participe en un proyecto mas coste tiene dicho proyecto, cuantas mas horas se invierten en un proyecto, mas coste tiene.

Después de toda esta exposición llega la hora de hacerse preguntas:

¿Es mas eficiente un desarrollo de un código «cogido con pinzas» (en el que está todo mezclado, la mitad de los datos están en base de datos, y la otra mitad en código, etc) que un desarrollo «»»»»bien hecho»»»»» (con su código bien separado en capas, con sus pruebas unitarias y de integración, con su documentación impoluta… y en inglés, su base de datos diseñada desde una herramienta CASE, su ORM bien puestecito, etc.)?… pues, me guste o no, he de admitir que si, es un desarrollo mas eficiente.

Ahora, ¿cual de los dos desarrollos es mas mantenible?, puede parecernos que la segunda forma de desarrollar sin lugar a dudas es mas mantenible, y seguramente lo sea, pero: 1º Seguirá siendo mucho mas costosa (menos eficiente) y 2º quizás no tardemos mucho menos en mantener el sistema que el otro, puesto que, cada nuevo campo en la tabla, cada nuevo requisito, cada cambio en el diseño, requiere que estemos varias horas manteniendo toda la estructura con tantos elementos alrededor del programa, pero que no son necesarios para que el programa funcione (pruebas, documentación, diagramas, …). Ojo, aquí no estoy discutiendo que los elementos «»prescindibles»» no tengan su valor por ejemplo, asegurar la calidad del producto y protegerlo frente a los cambios (pruebas), o para mejorar la comunicación entre los miembros de un equipo  (documentación y diagramas), lo que digo es que, si lo hacemos todo, y todo a la perfección, quizás no vamos a tardar mucho menos en mantener un sistema tan completo (y complejo) que un sistema de tipo «código espagueti», puesto que, además de realizar los cambios en el código (eso será muuuuy rápido), también tenemos que mantener todos los demás elementos (nuevas pruebas unitarias, modificaciones en diagramas, etc.).

Después de estas reflexiones, quiero exponer mis conclusiones personales (que intentaré acatar a partir de ahora):

  1. Si estás desarrollando un software en tu casa, intenta aplicar todos los principios de ingeniería del software que se te ocurran, separa en capas, documéntalo todo, haz diagramas (mínimo entidad-relación y de clases), investiga y aplica en tus desarrollos DDD, TDD, BDD, etc. Porque acabarás adquiriendo soltura, conocimientos y buenas prácticas. Pero si estás desarrollando un sistema para tu empresa, céntrate en el código por encima de todas las cosas, pero intenta llegar a un punto intermedio entre lo rápido y lo mantenible. Porque el cliente suele querer las cosas «para ayer» y a la empresa le interesa que nuestro desarrollo le cueste menos al cliente que el de la competencia, pero también quiere dar una impresión de que un «pequeño cambio» no costará tanto como rehacer el sistema.
  2. Si además de centrarte en el código, quieres ir aplicando elementos que harán tu código mas mantenible, empieza por separar el código en capas (porque es fundamental para hacer un sistema mantenible), después quizás deberías decantarte por el trabajo con pruebas unitarias y de integración (porque te ayudarán a mejorar la calidad de tu sistema, y protegerlo de los cambios que vayas realizando) y al final puedes elegir entre comentar el código  (sobretodo el de negocio y el que se salga de lo normal) o documentar el sistema para que sea fácil de entender «en conjunto» rápidamente (sobretodo pensando que otra persona lo tiene que entender o que tu mismo lo tienes que mantener pasados unos meses).

Con el tiempo, nuestra forma de desarrollar será eficaz y, también será eficiente, tanto a corto plazo (puesto que tardaremos poco en entregar nuestros desarrollos), como a largo plazo (puesto que tardaremos poco en hacer frente a los cambios requeridos, o osea, lo haremos mas mantenible).

Estas son mis reflexiones, espero algún comentario.

Publicado en Ingeniería del software, Programación, software engineering

Integridad referencial ¿Está sobrevalorada?

Actualmente me encuentro escribiendo una serie de post dedicado a una de mis mayores pasiones dentro del mundo del desarrollo de software: Las bases de datos, y bueno, ayer estuve un buen rato preparando una serie de diagramas entidad-relación de uno de los proyectos de software libre mas populares del mundo el Mediawiki (el proyecto detrás de la Wikipedia).

El caso es que, para mi sorpresa, el DDL utilizado para crear la base de datos en su versión para MySQL no cuenta con claves foráneas, lo mas curioso es que no es la primera vez que me encuentro proyectos, ya sean opensource, ya sean privativos, que cuentan con bases de datos que no utilizan con integridad referencial. Otro ejemplo que me tocó revisar hace unos años que creo recordar que no utilizaba esta característica es el «SugarCRM«. A lo largo de mi vida profesional he tenido que trabajar/mantener/revisar diversos sistemas que tampoco contaban con FK’s, incluso el propio MySQL cuenta con varias tecnologías de almacenamiento y, creo recordar que sólo InnoDB cuenta con la posibilidad de trabajar con integridad referencial

Después de esta reflexión, me gustaría saber qué pensáis vosotros sobre el tema ¿está sobrevalorada la integridad referencial? ¿pasa «algo malo» si no la utilizamos? (total, la podemos emular en nuestro sistema, y es mas fácil migrar la información sin utilizarla).

Personalmente soy demasiado «pureta» por lo que yo me decanto por utilizarla, pero ¿qué opinión tenéis al respecto?.

Un saludo.

Tagged with: ,
Publicado en BasesDeDatos
Licenciamiento de este blog
Licencia de Creative Commons
Esta obra está bajo una licencia de Creative Commons.
Calendario
May 2024
L M X J V S D
 12345
6789101112
13141516171819
20212223242526
2728293031