Tinselcity

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Próxima revisión
Revisión previa
bytes:el-aleman [2021/08/18 03:07]
flynn creado
bytes:el-aleman [2021/09/18 14:11] (actual)
flynn
Línea 13: Línea 13:
 Un mal relativamente frecuente entre cierto tipo de desarrollador es el de creer -y actuar según esa creencia- que el proyecto es //suyo//. Tienden a apropiárselo de diferentes modos, aunque principalmente a nivel técnico. //Anfang// era de estos. Un mal relativamente frecuente entre cierto tipo de desarrollador es el de creer -y actuar según esa creencia- que el proyecto es //suyo//. Tienden a apropiárselo de diferentes modos, aunque principalmente a nivel técnico. //Anfang// era de estos.
  
-**WiP**+De hecho, //Anfang// asumía con total naturalidad que el proyecto era suyo y que el resto solo estaba ahí para hacer lo que a él no le apetecía. Pero además es que el resto lo asumía de la misma forma. No sólo esos que declaraban abiertamente que no se le entendía nada, sino también los que, aunque tampoco le entendían, no lo declaraban. Los propios gestores del proyecto también. Ni le entendían, ni hacían nada en absoluto por enfrentarse lo más mínimo a los caprichos de //Anfang//. "Hemos intentado alguna vez que delegue, pero no lo hemos conseguido" - decían. 
 + 
 +Esta apropiación llegaba a extremos como bloquear el repositorio de código durante varios días porque tenía //que hacer unas cosas//; así, sin más explicación. También actualizaba versiones de herramientas sin decir nada. O se guardaba en su propio ordenador otras herramientas para que sólo él tuviera acceso a ellas, o simplemente para que solo él supiera qué herramientas eran. 
 + 
 +Este afán de secretismo técnico lo había extendido un poco hacia los gestores. A veces les //pillaba// discutiendo algún próximo cambio o algún futuro objetivo o lo que fuera y les oía decir cosas como "De esto no les digáis nada al equipo" o "Ya les iremos dando información a los que la necesiten y según la vayan necesitando... pero lo mínimo, eh". Reconozco que, en parte, esto se debía a que en el equipo había más de uno y de dos muy dispuestos a llevar la contraria en todo. Pero el motivo principal era, sin duda, mantener un control estricto sobre el proyecto. 
 + 
 +===== Experiencia y conocimiento ===== 
 + 
 +De //Anfang// escuché, en general, dos descripciones. Por un lado, algunos le describían como un genio, un portento, una eminencia. Otras descripciones, sin embargo, tenían cierta diferencia sutil: "Debe de saber un montón, seguro"
 + 
 +Según pude comprobar personalmente, la realidad era bastante distinta. 
 + 
 +//Anfang//, por encima de otras consideraciones, era bastante mediocre a nivel técnico. Pero escondía esto detrás de su //hablar en alemán// y, por supuesto, del //estatus// conseguido. Se imponía en cualquier decisión empezando a soltar "palabras complejas" sin demasiada relación con el tema y generalmente inconexas. Cuando esto no era suficiente, entonces simplemente posponía la discusión y luego aprovechaba para aplicar su decisión de forma preventiva antes de que volviera a surgir el tema. 
 + 
 +Su conocimiento técnico real era absolutamente decepcionante para alguien en la posición que ocupaba. Después de un par de discusiones con él en las que él mismo se acabó dejando sin ningún argumento real, empezó a evitar hablar conmigo de ningún asunto más. 
 + 
 +En una de esas discusiones, //Anfang// había intentado escribir un diálogo de confirmación. Más o menos. Realmente se trataba de sustituir rápidamente media docena de usos del ''confirm'' nativo del navegador por un ''Dialog'' de //jQueryUI//. El cambio que quería hacerse en las llamadas a ''confirm'' inevitablemente iba a pasar de ser una llamada síncrona a una asíncrona. Esto era inevitable y de hecho era, en parte, el objetivo. Su código, ligeramente resumido, era algo así: 
 + 
 +<sxh javascript; title: Es que es asíncrono> 
 +/** 
 + Presenta un dialogo de confirmación y dependiendo de la respuesta del usuario, se llamara 
 + a la funcion okCallback o a la cancelCallback 
 + * @param {*} msg Mensaje a mostrar en el diálogo 
 + * @param {*} okCallback función a ejecutar cuando el usuario pulsa en aceptar 
 + * @param {*} cancelCallback  función a ejecutar cuando el usuario cancela el diálogo 
 + */ 
 +function confirmCallback(msg, okCallback, cancelCallback) { 
 +    $.when( confirmDfD(msg) ).then(function(confirm) { 
 +        if(confirm){ 
 +            typeof okCallback === 'function' && okCallback(); 
 +        } else { 
 +            typeof cancelCallback === 'function' && cancelCallback(); 
 +        } 
 +    }); 
 +
 +/** 
 + * Muestra un dialogo de confirmación al usuario y devuelve una promesa que resuelve a true o false 
 + * dependiendo de si el usuario acepto o cancelo el diálogo 
 + * @param {*} msg 
 + * @return $.Deferred con resolve a true si acepto el diálogo o a false si lo canceló  
 + */ 
 +function confirmDfD(msg) { 
 +    var dfd = new jQuery.Deferred(); 
 +    var divMsg = "<div style='display:none'>" + msg + "</div>"; 
 +    $(divMsg).dialog({ 
 +        // ... 
 +        buttons: { 
 +            "Aceptar": function () { 
 +                $(this).dialog("close"); 
 +                dfd.resolve(true); 
 +            }, 
 +            "Cancelar": function () { 
 +                $(this).dialog("close"); 
 +                dfd.resolve(false); 
 +            } 
 +        } 
 +    }); 
 +    return dfd.promise(); 
 +
 +</sxh> 
 + 
 +//Anfang// había descubierto las promesas gracias a jQuery. Y nunca había salido de ahí. Su conocimiento de estas era, siendo objetivo, //básico//
 + 
 +Tras escribir ese código me llamó para enseñármelo con cierto orgullo. "He usado Promesas, no sé si conocerás lo que son..." y me explicó que ''confirmDfD'' sería una función interna y que la que se llamaría //externamente// sería ''confirmCallback''. Le pregunté qué necesidad había de escribir dos funciones distintas y de pasar una promesa de una a otra. "Es por la asíncronía." Asentí, pero insistí: "No necesitas tener dos funciones y no hace falta crear la promesa interna." De nuevo su respuesta: "Es porque es asíncrono." 
 + 
 +No quise insistir demasiado pero lo intenté una vez más: 
 + 
 +> ''dialog'' ya es asíncrono y ya te permite pasarle directamente los dos callbacks de //ok// y de //cancel//. Simplemente usando ''dialog'' ya podrías hacer algo así... 
 + 
 +<sxh javascript; title: Sin Deferreds estúpidos de mierda> 
 +function confirmCallback(msg, okCallback, cancelCallback) { 
 +    $("<div>"+msg+"</div>").dialog({ 
 +        // ... 
 +        buttons: { 
 +            "Aceptar": okCallback, 
 +            "Cancelar": cancelCallback 
 +        } 
 +    }); 
 +
 +</sxh> 
 + 
 +> ...y de cara a la llamada seguiría funcionando todo igual. 
 + 
 +Mientras miraba la pantalla, se le volvió a escapar un "Pero la asincronía...". Muy probablemente estaba pensando que yo no tenía ni idea y que no había entendido lo que él decía, pero algo le hacía sospechar que era él el que no sabía lo que decía y que tenía que buscar una salida. Me dijo, como buscando tranquilizarme, que "bueno, en realidad se trata de hacer lo que sea mejor, por supuesto". Luego, con un "Le daré una pensada más", dio por terminada la conversación para que me fuera. 
 + 
 +Antes de que pasaran 30 segundos, //Anfang// ya había subido el código, su código, al repositorio, se había levantado y había ido a contar a quien le tocaba cambiar los usos del ''confirm'' nativo por su ridícula función que había sido "muy complicado; he tenido que usar una Promesa por el tema de la asincronía, claro"
 + 
 +===== Conclusiones ===== 
 + 
 +No escribo todo esto simplemente para entretenerme señalando a alguien. La idea es aprender a tratar con este tipo de personas, porque si no terminan arruinando completamente el proyecto. 
 + 
 +Evidentemente si tenemos la autoridad suficiente -es decir, si estamos en ese puesto de dirección del proyecto- la acción a tomar es clara: Debemos tener el valor de eliminar por completo esta actitud de raíz, antes de que llegue a ser un problema. La forma más clara es evitar dejar toda la autoridad técnica en manos de una sola persona. También ayuda, evidentemente, seleccionar a personas que no tengan aires de //héroes// que se echan todo el proyecto a los hombros pretendiendo que se están sacrificando cuando lo que hacen es imponer únicamente su propio beneficio. No siempre es posible prevenirlo y no siempre tenemos la percepción adecuada o la autoridad para elegir a los miembros del proyecto, así que a veces nos encontraremos que el problema, inevitablemente, está ahí. La solución puede parecer dramática pero lo único que funciona es quitar a esa persona de forma explícita cualquier autoridad. He visto en más de una ocasión cómo algunos intentan introducir a otra persona que, mágicamente, le "destrone", pero en ninguna de las ocasiones esto ha tenido éxito. Mientras siga teniendo la autoridad técnica es prácticamente imposible que se pueda solucionar nada. 
 + 
 +¿Y si no tenemos esa opción? Y si, por ejemplo, ¿no somos más que otro miembro del equipo técnico por debajo de este arquitecto? Tenemos muy pocas opciones entonces. Obviamente asumir la derrota, ponerle un mote y seguir sufriendo como si nada, es una opción, pero no va a mejorar nunca la situación. Algo que //puede// tener cierto éxito es construir una realidad -técnica- paralela en el proyecto. Ir insertando mejoras en el código sin consultarle. Ignorar sus chapuzas pero sustituirlas por soluciones más apropiadas. 
 + 
 +Claro, esta es una estrategia muy arriesgada; nos crearemos fácilmente un enemigo peligroso. Lo que //puede// hacer que tenga éxito es que es similar a una guerra de guerrillas, a un desgaste lento y disimulado. No puedo recomendar algo así en general, pero definitivamente es lo que mayor probabilidad de éxito tiene. Eso sí, hay que saber hacerlo con mucha delicadeza. 
 + 
 +Cuando //Anfang// subió las funciones de ''confirmCallback'' y ''confirmDfd'' yo no dije nada. No me enfrenté a él por ignorar completamente lo que le había dicho. Dos meses y medio después, como si no tuviera ninguna relación, añadí al wiki de documentación y mandé a todo el equipo que, si necesitaban diálogos de información o de confirmación podían hacer algo tan sencillo como... 
 + 
 +<sxh javascript;> 
 +$.confirm("...mensaje..."
 +    .on("accept", function() { ... }) 
 +    .on("cancel", function() { ... }); 
 +</sxh> 
 + 
 +Unos días después, //como ya no hacían falta//, borré las horribles funciones de //Anfang//. Como digo, no puedo recomendar seguir una estrategia así a la ligera, pero sinceramente creo que es muchísimo peor problema no hacer nada contra una persona así.