libros

Expresar agradecimiento mediante la comunicacion no violenta

“Tu informe es muy bueno.” “Eres una persona muy sensible.” “Anoche fuiste muy amable al ofrecerte a acompañarme a casa.” Estas son frases típicas de agradecimiento en nuestras vidas, y por sorprendente que parezca alienan de la vida. Si nos fijamos no revela nada de la persona que lo está emitiendo al mismo tiempo que emite juicios. Además de esto existen personas los usan porque “funcionan”, porque según los estudios demuestran que los empleados trabajan más si los elogias. Y es cierto, en primera instancia. Lo malo es que estos elogios van dirigidos sin pensar porque funcionan la persona que los recibe antes o después termina por darse cuenta y hace justamente el efecto contrario y su productividad cae en picado, pasando a sentirse manipulado. Cuando expresemos agradecimiento tenemos que hacerlo simplemente para eso, expresar agradecimiento, sin esperar nada a cambio. La única intención es celebrar la manera en la que la otra persona ha mejorado nuestra vida. Los tres componentes del agradecimiento La manera en la que tenemos que expresar un agradecimiento se puede dividir en tres componentes claros: 1. Las acciones que contribuyeron a nuestro bienestar 2. Las necesidades concretas que han quedado resueltas o satisfechas 3. Los sentimientos que tenemos como resultado de la satisfacción A la hora de usar estos tres componentes no tiene porque ser en este orden específico incluso aveces, basta con un simple “Gracias” o una sonrisa. Sin embargo, si queremos estar seguros de que nuestro agradecimiento lo han recibido por completo, es valioso que lo desarrollemos con la elocuencia necesaria. La recepción de las expresiones de agradecimiento A muchos, entre los que me incluyo, nos resulta difícil recibir de corazón las expresiones de agradecimiento. Nos inquieta el pensamiento de que no nos merezcamos tales elogios, nos preocupa no estar a la altura de tales palabras. Acostumbrados a vivir en una cultura en la que comprar, ganar y merecer es la manera normal de intercambiar, el simple hecho de dar y recibir nos incomoda. El hambre de elogios Por mucho que lo negamos la mayoría de las personas queremos que se nos reconozca y se nos aprecie cuando hacemos algo bien. Es común que por mucho que hagamos de buena fe y actuemos de la mejor manera posible para ayudar se nos recrimine esa vez que nos equivocamos o no actuamos de manera correcta. Y más importante aún, es bastante común que como no se nos reconoce estamos más acostumbrados a prestarle mayor atención a los juicios negativos y reprimendas en contra de nuestra persona. Una vez alguien me hizo un símil que representa esto y decía así. “Después de un día andando por la calle 98 personas te dan un abrazo por haberles ayudado en sus vidas. Y por otro lado 2 te dan un bofetón en la cara porque esas acciones les han hecho mal. Al final del día en tú cabeza recuerdas esos dos últimos, les prestas toda la importancia y olvidarás los 98 anteriores.” Y suena duro y feo pero es la realidad en la mayoría de casos.

Como liberarnos nosotros y asesorar a los demas

En ciertas situaciones no somos conscientes ni nosotros mismos del “mal”, estámos tan acostumbrado a verlo en el día a día que lo consideramos parte de la “rutina” diaria. Para darnos cuenta de ellos hace falta una gran cantidad de energía y un alto nivel de conciencia. Esto requiere saber identificar las diversas necesidades y tener la capacidad de conectarse consigo mismo. En nuestra cultura ambas cosas son difíciles, no se nos ha enseñado nunca a conocer cuáles son nuestras necesidades y además están mal vistas. Cuando una persona dice que tienen una necesidad se la está viendo como una persona inmadura o inadaptada. Además estas personas son consideradas muchas veces como egoístas. Centrarnos en lo que queremos hacer y no en lo que salió mal. Tener la capacidad de distinguir nuestros propios sentimientos y necesidades y empatizar con ellos nos puede salvar de la depresión. Los profesionales que ejercen la psicoterapia y otras áreas similares también pueden usar la Comunicación No Violenta para establecer vínculos recíprocos y auténticos con las personas que consultan, en lugar de interpretar todo lo que dicen. … Cuanto mejor conozcas la gratitud, menos víctima serás del resentimiento, la depresión y la desesperación. La gratitud actuará como un elixir que irá disolviendo gradualmente esa dura corteza que envuelve tu ego —tu necesidad de posesión y de control— y hará de ti una persona generosa. El sentimiento de gratitud pone en marcha una auténtica alquimia espiritual, nos hace magnánimos— engrandece nuestra alma. SAM KEEN

El uso protector de la fuerza

Existen situaciones, excepcionales, em las cuales el uso de la fuerza es inevitable. Como por ejemplo cuando la otra persona no está dispuesta a comunicarse y el peligro es inminente. Son situaciones en las que el uso de la fuerza es necesario, pero para ello tendremos que diferenciar entre los usos protectores y los usos primitivos. Al usar la fuerza de manera protectora buscamos impedir daños o injusticias. La intención del uso de la fuerza de manera primitiva es la de hacer sufrir a la otra persona las consecuencias de sus malos actos. Cuando un niño trata de cruzar la calle corriendo sin mirar y vemos un coche, para evitar el daño ponemos en juego la fuerza protectora. Este puede ser ejercido tanto de manera física (sugetándo la mano para que no cruce) como psíquico (diciéndole “¡Estás loco como ibas a cruzar sin mirar!”) El uso protector de la fuerza se basa en el supuesto de que hay personas que se comportan de una forma que puede resultar perjudicial para ellas o para los demás debido a la ignorancia. Por ello el proceso para corregir estas acciones debe consistir en educar, no en castigar. La ignorancia presupone: 1. No tener conciencia de las consecuencias de nuestras acciones. 2. Ser incapaces de ver cómo satisfacer nuestras necesidades sin perjudicar a los demás. 3. Creer que tenemos “derecho” a castigar o herir a otras personas porque “se lo merecen”. 4. Tener alguna idea delirante, como por ejemplo que “una voz” nos ordenó que matemos a una persona. EL precio del castigo Cuando decidimos hacer algo con el único objetivo de evitar el castigo, estamos desviando la atención del valor que tiene esta acción en si misma. En cambio, nos estamos centrando en las consecuencias de vendrán si no realizamos lo que se nos pide. Siempre que se recure a la fuerza punitiva, se deteriora la autoestima. Existen dos cuestiones que nos ayudaran a entender por qué es poco probable conseguir lo que queremos ayudándonos de un castigo para cambiar el comportamiento de los demás. La primera de ellas es la siguiente: “¿Qué quiero que haga esta persona de manera diferente de lo que hace ahora?” Si sólo nos planteamos esta pregunta puede parecer que el castigo es una buena vía para conseguir nuestro objetivo, conseguir influir en el comportamiento de la persona. Sin embargo, la segunda pregunta nos demuestra que es improbable que el castigo tenga efecto: “¿Qué razones quiero que tenga esta persona para hacer lo que le pido?” Con la segunda pregunta vemos que una vez la persona haga lo que le pedimos no tendrá razón para volver a hacerlo pues el miedo no estará siempre presente. No tendrá una recompensa por la que sienta que quiere hacer esto en otra ocasión.

La expresion plena de la ira

Para expresar la ira con la comunicación no violenta tenemos que desconectar de los demás la responsabilidad de que nosotros estemos furiosos. Es decir tenemos que eliminar ideas de nuestra cabeza tales como: “Él o ella me hizo que me pusiera furioso cuando hizo esto otro” Nunca nos enfadamos por lo que hizo la otra persona, lo que la persona haya hecho es solo un estímulo no la causa de nuestro enfado. La ira surge cuando nos enfadamos y buscamos culpables, es decir, cuando optamos por hacer el papel de Dios y juzgar o culpar a otra persona por haberse equivocado. Para que quede más claro el ejemplo anterior veremos como una misma conducta puede generar ira, frustración o agradecimiento en una persona. Supongamos que hemos quedado a una cierta hora con otra persona y esta llega tarde. Dependiendo de como nos encontremos podremos sentir estos tres sentimientos. - Sentiremos ira si consideramos que llegar tarde a este tipo de encuentros es una falta de respeto y no nos está tomando en serio. - Sentiremos frustración si necesitamos usar nuestro tiempo de la mejor manera posible y ahora hemos estado esperando por ella sin hacer nada. - Sentiremos agradecimiento si nos hacía falta en ese día un tiempo de descanso y reflexión que nos ha venido dado por el estar esperando. Como podemos ver, tal como hemos dicho antes, nuestros sentimientos dependen de nosotros no de los actos del resto. El retraso en la cita con la persona es tan solo un estímulo. Por todo esto en lugar de indignarnos, es mejor pensar en nosotros mismos porque estamos así. Pensar en nuestras propias necesidades empatizar con ellas o con las de los demás. Esto es complicado y exige mucha práctica, durante la cual sustituiremos de manera sistemática el “Estoy enfadado porque ellos…” por “Estoy enfadado porque necesito…” Pasos para expresar la ira: 1. Detenerse. Respirar profundamente. 2. Identificar los pensamientos que contienen juicio. 3. Conectarse con las propias necesidades. 4. Expresar nuestros sentimientos y nuestras necesidades no satisfechas. A veces, entre los pasos 3 y 4 podemos optar por brindar empatía a la otra persona a fin de que esté en mejores condiciones para oírnos cuando nos expresemos en el paso 4.

La conexion con uno mismo a traves de la compasion

Quizás, la comunicación no violenta tenga su aplicación más importante en uno mismo. Como somos interiormente, si nos tratamos de manera violenta es difícil que seamos compasivos con los demás. Ante nuestras propias equivocaciones, solemos enredarnos en un sentimiento de odio hacia nosotros mismos en lugar de beneficiarnos de conocer una nueva limitación que tenemos con la que poder avanzar en nuestro crecimiento personal. Si la manera con la que nos evaluamos nos lleva a sentir vergüenza y con ello cambiamos nuestra conducta, hacemos que nuestro crecimiento y aprendizaje esté guiado por el odio que nos damos a nosotros mismos ¿cómo podemos pretender actuar de distinta forma con el resto de personas? Existe una expresión en nuestro idioma que tiene el gran poder de generar sentimiento de vergüenza y culpa. Es una expresión que parece inofensiva y usamos bastante para evaluarnos, está tan arraigada en nuestra conciencia que nos parece imposible prescindir de ella. Se trata de la expresión “debería“. Cuando la usamos en la mayoría de las ocasiones nos estamos resistiendo a aprender ya que esta expresión implica que no había otra opción. Los seres humanos tenemos la necesidad de tener que elegir y cuando escuchamos una exigencia del tipo que sea solemos resistirla, incluso una exigencia camuflada con un debería. Recompensas Cuando actuamos estamos buscando de alguna forma una recompensa, bien puede ser dinero o simplemente conseguir la aprobación. En el segundo caso ocurre porque en nuestra cultura nos han inculcado que con cada “buena” acción obtendremos una “recompensa”. De niños nos han ensñado que después de una acción “buena” nos responderán con un “eres un buen niño” y una sonrisa, esto hace que de adultos seamos adictos a ello y nos engañemos creyendo que la vida consiste en obtener recompensas por cada cosa que hagamos. Con ello hacemos todo lo que haga bien para otras personas y evitamos todo lo que podría provocar desagrado o castigo. De esta manera lo único que hemos hecho ha sido vivir “comprando” el amor de otros en lugar de enriquecer la nuestra propia vida. Y lo más importante, si logramos optar por esta segunda parte y enriquecer la vida veremos que los demás nos lo agradecen. Este agradecimiento nos dará la auténtica alegría que ninguna aprobación de los demás conseguirá jamás. Al igual que este sentimiento de buscar aprobación existen otros como: - Escapar del castigo (miedo) - Evitar vergüenza - Evitar sentimiento de culpa - Porque es un deber

La recepcion empatica

Parafrasear lo que nos ha dicho el interlocutor puede ser de ayuda ya que al hacer esto estámos comprendiendo y empatizando con el mensaje que trata de darnos. Es por ello que en ocasiones sea una buena práctica parafrasear el mensaje que acaba de transmitirnos. ¿Cuando debo parafrasear y cuando no? Esto no se puede medir o dar una regla exacta, tenemos que saber en cada situación como actuar en función de distintos factores. Al final quien nos está dando el mensaje lo que quiere es que le prestemos atención y lo comprendamos, es por ello que confirmar que entendemos sus motivaciones y sentimientos al dar este mensaje ayuda a conectar mejor con él/ella antes de lanzarnos como locos a dar consejos o soluciones. Primero comprender después aconsejar. No empecemos con consejos rápidos, mensajes tranquilizadores, tratar de explicar cual es nuestra opinión o cómo nos sentimos antes de empatizar. Para dar empatía necesitamos tenerla Puede que esta frase suene absurda pero la realidad es esa, si queremos mostrar empatía hacia una persona primeramente necesitamos tener empatía. En caso de que no tengamos o no la suficiente podemos simplemente decirlo, podemos decirle que no podemos empatizar con él/ella y de esa forma la persona ve que queremos comprender su mensaje. Esto puede ser más que suficiente para que nos ofrezca lo que necesitamos.

Lo que pedimos a los demas para enriquecer nuestra vida

¿Cómo hago lo que no hay que hacer? Lo único que sé es que no quiero hacer lo que no hay que hacer La letra de esta canción pone de relieve los dos problemas que surgen cuando alguien pide una cosa en forma negativa. La gente se confunde y no sabe qué se le pide en realidad. Además, lo más probable es que las peticiones negativas provoquen resistencia en la persona que las recibe. ¿Cómo expresamos los que queremos pedir para conseguir que los demás respondan a nuestras necesidades de manera compasiva? La clave es expresar peticiones de manera positiva, es decir, evitar decir lo que no queremos. Porque en cierta medida el ser humano es vago y no queremos tener que estar pensando que solución darle a la petición de una persona que nos ha dicho que es lo que no quiere. Mejor si nos dice que es lo que quiere realmente y nosotros actuamos en consecuencia. ¿No es así? De todas formas ya no solo por vagueza, no existen dos personas que piensen de igual forma. Por ello es muy fácil que nosotros demos una idea ambigua o no exacta, como puede ser decir lo que no queremos y que la otra persona interprete una manera que no se nos había pasado por la cabeza. En el libro cuenta como una de sus alumnas en un taller estaba disgustada porque su marido pasaba mucho tiempo trabajando. Para mostrarle este sentimiento le dijo: “Me gustaría que pasaras menos tiempo con el trabajo”. Lo que ocurrió fue que su marido a la semana siguiente haciendo caso de su petición se apuntó a un torneo de golf. Esta chica cuenta como no era lo que esperaba, es más, era aún peor ya que lo que ella quería realmente era que su marido pasara más tiempo con ella y su hija. Tras el curso fue nuevamente a hablar con él y esta vez de manera afirmativa le dijo: “Pasas demasiado tiempo en el trabajo y eso me deprime, me gustaría que al menos una vez por semana pasaras una tarde con los niños y conmigo”. Esta vez tuvo un resultado mejor. De igual manera un lenguaje vago hace que la otra persona interprete lo que mejor le parece a él y casi nunca coincide con lo que nosotros queríamos en realidad. Es por eso que frases como: “Me gustaría que fueras más responsable”, “Quiero que dejes ser quien soy”, etc. sean tan vagas que no sabemos realmente porque lo dicen. Si en lugar de eso dijésemos otras frases como: “Quiero que cuando te diga que hagas algo lo hagas sin rechistar y con una sonrisa” en lugar de simplemente “ser mas obediente” no habría lugar para la interpretación. O “Quiero que cuando hago las cosas bien me digas con una sonrisa lo bien que lo hago” en lugar de “quiero que me dejes ser quien soy” al igual que en el ejemplo anterior dejamos claro cual es nuestro deseo y como queremos que se cumpla. De esta manera la otra persona no puede hacer una mala interpretación y aún mejor no tendrá que pensar como interpretarlo o que hacer al respecto. Un lenguaje vago aumenta la confusión interna. La depresión es el premio que obtenemos por ser ‘buenos’. Por otro lado es igual de peligroso pedir algo sin mostrar sentimientos, en ese caso las peticiones pueden sonar como exigencias. Esto hace que hacia quien va dirigida la petición no la reciba de la mejor forma, por ejemplo unos padres que dicen a su hijo: “¿Y si te cortas el pelo?” suena a exigencia por parte de ellos, pero si cambiasen el mensaje a algo similar a: “Me preocupa que tengas el pelo tan largo y no veas bien, sobre todo cuando vas en bicicleta. ¿Y si te cortas el pelo?” Solicitemos la confirmación de nuestras palabras Por raro que pueda parecer, sobre todo al principio debemos pedir a nuestro interlocutor que nos confirme el mensaje que le hemos dado. En muchos casos veremos que con la confirmación hemos expresado mal algunas partes del mensaje y ha interpretado lo que ha creído conveniente. También es importante que agradezcamos cuando se nos confirma el mensaje, además de brindarle empatía a quien sabemos que no quiere confirmar el mensaje. Las peticiones a un grupo En ocasiones empezamos un debate de grupo y la misma persona que lo inicia no sabe como acabarlo. Esto ocurre porque muchas veces ni la misma persona que lo inicia sabe cuando acabarlo porque ni el mismo sabe que esperar de esa conversación que se ha iniciado. Es por esto que es importante que antes de comenzar un debate pensemos que queremos obtener de hacer esta pregunta o comentario, el resto de personas no lo saben, así que al menos debemos saberlo nosotros mismos y debemos dejarlo claro al comenzar. Y, en el mejor de los casos, cuando realmente si conoce que quiere conseguir del tema que él/ella mismo ha sacado no sabemos como parar. En la india existe un término llamado “bas” que se usa para esto, cuando la persona que ha iniciado un tema ya está conforme con la respuesta recibida por parte del grupo dice “bas” y se puede dar por concluida para poder continuar con otro tema. En nuestra lengua no existe tal término pero podemos indicar de otra forma que ya estamos conformes. Las peticiones versus las exigencias Es difícil saber diferenciar entre una exigencia y un petición, para ello tendremos que observar que hace el interlocutor si no se cumple la petición. Por ejemplo, supongamos que Pepe quiere que María se quede con él esta tarde porque se siente solo. Veamos la situación de dos formas distintas. Situación 1: Pepe: Me siento solo y me gustaría que pasaras la tarde conmigo María: Mira, Pepe, estoy muy cansada. Si quieres compañía, ¿que te parece si se lo pides a otra persona? Pepe: (enfadado) ¡Tan egoísta como siempre! Situación 2: Pepe: Me siento solo y me gustaría que pasaras la tarde conmigo María: Mira, Pepe, estoy muy cansada. Si quieres compañía, ¿que te parece si se lo pides a otra persona? Pepe: (se queda sin saber que responder) María: (nota que está disgustado) ¿Estás enfadado? Pepe: No María: Vamos, Pepe, ¿que te pasa? Pepe: Sabes perfectamente que me siento muy solo. Si me quisieras de verdad, esta tarde te quedarías conmigo. Como podemos ver en ambas situaciones Pepe intenta hacer sentir mal a María de manera que trata de exigir que pase con ella la tarde. Sin embargo si Pepe respondiese, por ejemplo: “María, ¿estás agotada y necesitas descansar esta tarde?” Escuchando la respuesta y preocupándose por ella, estaríamos viendo una petición. Es una exigencia si nuestro interlocutor intenta que nos sintamos culpables

Asumir la responsabilidad de nuestros sentimientos

Asumir la responsabilidad de nuestros sentimientos Otro de los componentes de la comunicación no violenta es reconocer el origen de nuestros sentimientos. Nuestros sentiemientos son el resultado de cómo elegimos tomarnos lo que dicen y hacen los demás. Cuando alguien nos transmite un mensaje negativo, tenemos cuatro opciones con respecto a la manera de recibirlo. Una es tomárselo de manera personal, captando en él acusaciones y críticas. Por ejemplo, alguien nos dice: “¡Eres la persona más egocéntrica que he conocido en mi vida!“ Nos lo podemos tomar de las siguientes formas y responder de estas formas: Personal: “Sí, debería ser más sensible con los demás”, aceptamos el punto de vista del otro y nos echamos la culpa. Lo más probable es que en ese momento nos sintamos culpables, avergonzados y deprimidos. Culpa del otro: “No tienes derecho a decirme esto. Siempre tengo en cuenta tus necesidades. ¡Tú eres el egocéntrico!”, lo más probable es que sintamos rabia en este momento. Nuestros sentimientos: “Cuando me dices que soy la persona más egocéntrica que conociste en tu vida, me siento herido, porque yo querría que reconocieras los esfuerzos que hago para tener en cuenta tus preferencias”, al centrarnos en nuestros sentimientos y necesidades, tomamos conciencia de que sentirnos heridos en esta circunstancia viene dado de la necesidad de que nos reconozcan los esfuerzos que hacemos. Sentimientos del otro: si tenemos en cuenta los sentimientos que puede sentir la otra persona y tratamos de comprenderlos, podríamos preguntarle, por ejemplo: “¿Te sientes herida porque necesitas que se tomen en cuenta tus preferencias?“ Distinguir entre dar desde el corazón y estar motivados por la culpa Existen algunas expresiones de uso común que tienden a enmascarar la responsabilidad por nuestros propios sentimientos. Como pueden ser las de carácter impersonal: “Me indigna descubrir faltas de ortografía en los folletos destinados al público.” “Este tipo de cosas me saca de quicio”. Afirmaciones que sólo hacen referencia a lo que hacen los demás: “Me duele que no me felicites el día de mi cumpleaños”. “Si no te terminas la comida, mamá se pondrá muy triste.“. Usar la expresión “me siento … X porque … Y” siendo ´*Y*´ algo distinto de “yo“: “Me siento triste porque dijiste que no me quieres”. “Estoy enojado porque la supervisora no cumplió lo prometido” En todos estos ejemplos podemos ahondar más en la conciencia de nuestra responsabilidad utilizando la expresión: “Me siento … porque yo …“ “Me indigna descubrir faltas de ortografía en los folletos destinados al público porque me gustaría que nuestra empresa proyectase una imagen profesional.” “Si no te terminas la comida, mamá se siente decepcionada, porque quiero que crezcas fuerte y sano.” “Estoy enojado al ver que la supervisora no cumplió su promesa, porque yo había contado con ese fin de semana largo para ir a visitar a mi hermano.”

Dar desde el corazón

Dar desde el corazón Los 4 componentes de la CNV: 1. Observación 2. Sentimiento 3. Necesidades 4. Petición Por ejemplo una madre podría manifestar esos tres aspectos del proceso diciéndole a su hijo adolescente: “Félix, me molesta (sentimiento) ver dos calcetines sucios hechos una bola debajo de la mesita del café (observación) y otros tres al lado del televisor, porque estoy necesitando (necesidad) más orden en las habitaciones de la casa que compartimos” Acto seguido la madre abordaría el componente número cuatro, que es una petición muy específica: “¿Estarías dispuesto a recoger los calcetines y llevártlos a tu habitación o meterlos en la lavadora?” Con este método nos limitamos a decir hechos concretos y como nos sentimos, respecto a estos. De esta forma no estamos dando pié a la discursión, pues nuestros sentimientos son irrevatibles, nadie puede saber como nos sentimos para entrar en una discursión. Además de esto añadimos una solución, de manera que le damos a la otra persona la solución del problema para que no tenga que pensar si quiera. Actos concretos que observamos que están afectando nuestro bienestar. Cómo nos sentimos en relación con lo que observamos. Las necesidades, los valores, los deseos, etc., que dan origen a nuestros sentimientos. Las acciones concretas que pedimos para enriquecer nuestra vida. Es importante tener en cuenta que la comunicación no violenta, no consiste únicamente en como nos expresamos respecto a los demás, también tiene un importante segundo componente. Tenemos que escuchar de manera empática a la segunda parte de la conversación. La CNV tiene dos partes: 1. Expresión honesta mediante los cuatro componentes. 2. Recepción empática mediante los cuatro componentes. De nada sirve comunicar lo que queremos si luego no tenemos en cuenta la opinión del otro, no solo escuhándola, si no teniendo en cuenta lo que dice y empatizando con él. Pudiendo llegar a entender su razonamiento y porque siente que tiene más validez que el nuestro.

Identificar y expresar los sentimientos

Identificar y expresar los sentimientos En la actualidad se nos educa para orientarnos hacia los demás más que para estar en contacto con nosotros mismos. Tenemos metida en la cabeza la siguiente pregunta: “¿Qué quieren los demás que yo diga y haga?” Una vez tenía un compañero de habitación que ponía la música a un volumen tan alto que no me dejaba dormir, y me preguntaron que era lo que sentía con eso. A lo que respondí: “Siento que por la noche no habría que poner la música tan alta”. Al decir la palabra “siento” seguida de “que”, la oración, pese a incluir el verbo “sentir”, en realidad no expresa mis verdaderos sentimientos, no tan solo opinión. Al tratar de expresar nuevamente mis sentimientos, dije: “Siento que si una persona se comporta de esta manera es porque sufre un transtorno de personalidad”. Pero con esto no mejoraba la cosa seguía siendo una opinión y no un sentimiento. Tras reflexionar un rato, me di cuenta de algo y respondí: “No siento absolutamente nada”. Era obvio que si tenía sentimientos al respecto, pero lamentablemente no sabía cómo darme cuenta de ellos, y mucho menos, cómo expresarlos. Los sentimientos versus la ausencia de sentimientos El lenguaje suele dar pie a confusiones, como cuando utilizamos el verbo “sentir” cuando en realidad no estamos expresando un sentimiento. Por ejemplo, en la frase: “Siento que no he hecho un buen trato”, sería más adecuado decir “creo” que “siento”. En general, no expresamos claramente nuestros sentimientos cuando en una oración, después de “siento”, utilizamos palabras como las siguientes: que: “Siento que tú deberías haberlo sabido”. como: “Me siento como un fracasado” como si: “Siento como si viviera con una pared” Por otro lado, no es indispensable usar la palabra “sentir”. Podemos decir en lugar de “me siento irritado”, “estoy irritado”. Distingamos entre lo que sentimos y lo que pensamos de la reacción o comportamiento de los otros hacia nosotros También es importante diferenciar cuando describimos lo que creemos que otras personas perciben de nosotros y la realidad. “Siento que soy insignificante para mis compañeros en el trabajo” La palabra “insignificante” describe cómo creo que los demás me evalúan, en lugar de ser un sentimiento verdadero, como podría ser: “me siento triste” o “me siento desalentado”. incomprendido, indica la valoración que hago del nivel de comprensión de la otra persona en lugar de expresar un sentimiento real. Sería mejor decir “ansioso”, “molesto” o cualquier otra emoción. ignorado, otra vez más es como creo que los demás actúan sobre mi en lugar de como me siento. Cómo estos ejemplos existen otras palabras, a continuación dejaré una muestra de unas cuantas de ellas. abandonado despojado manipulado acorralado despreciado obligado amenazado estafado olvidado atacado excluido presionado atrapado explotado rebajado coaccionado forzado rechazado degradado humillado subvalorado desamparado incomprendido superfluo desatendido intimidado traicionado desdeñado invisible ultrajado desfavorecido maltratado utilizado Cualquiera de estas palabras en la frase anterior podría encajar pero ninguna de ellas expresan realmente un sentimiento de que sentimos en ese momento.

La comunicación que bloquea la compasión

La comunicación que bloquea la compasión La comunicación que nos aliena de la vida surge de las sociedades jerárquicas o de dominación, y las sustenta. Cuando los pueblos están controlados por un número pequeño de individuos que buscan el beneficio propio, a los reyes, zares, nobles, etc., les resulta muy útil que las masas se eduquen con una mentalidad de esclavos. A tal efecto, el lenguaje de lo incorrecto y de expresiones como “deberías” y “tienes que” es totalmente adecuado para ese propósito: cuanto más acostumbramos a las personas a pensar en términos de juicios moralistas que implican lo que está mal o incorrecto, tanto más aprenden a mirar hacia fuera de sí mismos. la comunicación que aliena de la vida tiene profundas raíces filosóficas y políticas Los juicios moralistas Los juicios moralistas, ciertas formas de comunicación nos alienan de nuestro estado natural de compasión o solidaridad. Estos juicios se reflejan en comentarios como: “Tu problema es que eres muy egoísta”, “Eres una perezosa”, “Están llenos de prejuicios”, “Esto es inapropiado”. Echar la culpa a laguien, insultarlo rebajarlo, ponerle etiquetas criticarlo, establecer comparacion y emitir diagnósticos son distintas maneras de formular juicios. Es importante no confundir los juicios de valor con los juicios moralistas. Todos hacemos juicios de valor con respecto a las cosas de la vida que estimamos. Podemos valorar, por ejemplo, la honradez, la libertad o la paz. Los juicios de valor reflejan nuestras creencias con respecto a cómo podría mejorar la vida. En cuanto a los juicios moralistas, los hacemos en relación con las personas y conductas cuando no concuerdan con nuestros juicios de valor. Decimos, por ejemplo, “La violencia es mala. Quien mata a otro ser humano es malvado”. En lugar de usar “Me asusta el uso de la violencia para resolver conflictos; yo valoro el empleo de otros medios en la resolución de los conflictos humanos” Clasificar y juzgar a las personas promueve la violencia Las comparaciones son una forma de juicio Negación de la responsabilidad El lenguaje que solemos usar oscurece la conciencia de nuestra responsabilidad personal El uso de una expresión tan abitual “tener que”, como en el caso de la afirmación: “Te guste o no, tienes que hacerlo”, ilustra hasta qué punto nuestra responsabilidad personal por nuestras acciones se ve oscurecida por esta manera de haber. En cuanto a la expresión “hacer sentir”, como en el caso de “Me haces sentir culpable”, constituye otro ejemplo más de cómo el lenguaje nos allana el camino para que podamos negar nuestra responsabilidad personal con respecto a lo que sentimos y a lo que pensamos. Negamos la responsabilidad de nuestros actos cuando atribuimos su causa a: - Fuerzas difusas e impersonales: “Limpié mi habitación porque tenía que hacerlo“ - Nuestro estado de salud, un diagnóstico o nuestra historia personal o psicológica: “*Bebo porque soy alcohólico*” - Lo que hacen los demás: “Le pegué a mi hijo porque cruzó la calle corriendo“ - Órdenes de la autoridad: “Mentí al cliente porque mi jefe me dijo que lo hiciera“ - Presiones de grupo: “Empecé a fumar porque todos mis amigos lo hacían“ - Políticas, normas y reglas institucionales: “Tengo que expulsarte por esta infracción porque es la política de la escuela“ - Los roles asignados según sexo, posición social o edad: “Me fastidia ir a trabajar, pero tengo que hacerlo porque soy marido y padre”. - Impulsos irrefrenables: “Me superaron las ganas de comer bombones y me los comí“ Cuando pensamos que “alguien merece algo” bloqueamos la comunicación compasiva

Observar sin evaluar

Observar si envaluar Si combinamos la observación y la evaluación seguramente la otra persona escuchará una crítica La comunicación no violenta, no nos dice que seamos totalmente objetivos ni tampoco que nos abstengamos de hacer evaluaciones. Lo único que nos dice es que mantengamos una separación entre nuestras observaciones y nuestras evaluaciones. | Comunicación | Ejemplo observación con evaluación | Ejemplo observación sin evaluación | | :———– | :————————————- | :————————————- | | Uso del verbo “ser” sin indicar si la persona que evalúa acepta o no la responsabilidad de la evaluación | Eres demasiado generoso | Cuando te veo darle a alguien el direno para tu almuerzo, creo que eres demasiado generoso | | Uso de verbos con connotaciones evaluativos | Pepe siempre posterga las cosas | Pepe sólo estudia para los exámenes la noche anterior | | Dar por sentado que las inferencias que uno hace de las ideas, los sentimientos, los proyectos y los deseos de otra persona son las únicas posibles | No terminará el trabajo a tiempo | No creo que termine el trabajo a tiempo | | Confundir una predicción con una certeza | Si tu alimentación no es equilibrada, vas a enfermarte | Si tu alimentación no es equilibrada, temo que te enfermes | | No ser específico al citar ejemplos | Las minorías no cuidan su vivienda | No he visto que la familia que vive en el número 123 de la calle Pepe retire la nieve de la acera de su casa | | Usar palabras que implican habilidad sin precisar que se hace una evaluación | Pepe Pérez juega mal al fútbol | Pepe Pérez no ha marcado un gol en veinte partidos | | Usar adverbios y adjetivos de maneras que no indiquen que se hace una evaluación | Pepito es feo | No encuentro a Pepito físicamente atractivo | Palabras como “a menudo” o “rara vez” contribuyen también a confundir la observación con la evaluación. | Evaluaciones | Observaciones | | :————- | :————- | | Raras veces haces lo que quiero | Las tres últimas veces que empecé una actividad, me dijiste que no querías hacerla | | A menudo viene sin avisar | Viene sin avisar al menos tres veces por semana |

Olores del código: test

Olores del código: test Existen muchas cosas que no huelen bien en el código y a continuación vas a poder ver las referentes a los test. Esta es una publicación parte de una serie de publicaciones que haré referentes a olores del código. Test Test insuficientes, ¿cuantos test debe tener mi suite? Siento tener que decírtelo pero no hay una métrica para ello. Tienes que tener tantos test como para probar todo lo que puede fallar. Aunque he escuchado decir que normalmente con tener un 80% de la aplicación testada puede valer. Usa una herramientas de cobertura, existen herramientas que te hacen análisis sobre la cobertura de tus test (a veces los propios IDE´s lo tienen integrado). Estas te analizan que partes están cubiertas con un test y cuales no, te hacen tener una visión de como está el proyecto. No te saltes los test triviales, en ocasiones puedes pensar que este test es demasiado obvio como para comprobarlo. Pero la verdad es que este tipo de test tienen más valor como documentación que como comprobación en sí mismo. Hazlos y deja reflejado ese comportamiento. Un test ignorado es una pregunta sobre ambigüedad, a veces no tenemos claro el comportamiento de algún detalle de comportamiento. Esto lo podemos dejar reflejado como un test comentado o ignorado, de esta manera esta cuestión queda reflejada en el código y será más fácil de solucionar. Testea condiciones del entorno, a menudo nos podemos encontrar delante de una solución conrrecta pero ser el entorno quien nos genera errores. Es por ello que hay que tener en cuenta las condiciones del entorno. Testear exhaustivamente cerca de los bugs, cuando encontramos un bug en una función es muy probable que no se encuentre solo. Es por ello que una vez encuentras un bug es recomendable testar esa función a fondo, probablemente encuentres más errores. Los test deben de ser rápidos, un test lento es un test que no se va a ejecutar. Cuando estás ejecutando la suite de test constantemente el test más lento es el test que terminarás por saltar. Este hará que tu ritmo de trabajo baje y te cansarás, por eso es mejor que los test sean lo más rápido posible. Referencias Libro original sobre Clean Code, esta publicación corresponde con el capítulo 17.

Olores del código: funciones y nombres

Olores del código: funciones y nombres Existen muchas cosas que no huelen bien en el código y a continuación vas a poder ver las referentes a funciones y nombres. Esta es una publicación parte de una serie de publicaciones que haré referentes a olores del código. Funciones 1.Muchos argumentos, las funciones son mejores cuantos menos argumentos tengan. Lo ideal es que no tengan ninguno y como máximo tres, a partir de tres deberías cuestionarte si los argumentos no son realmente un objeto con esas características, por ejemplo. 2.Argumentos de salida, los argumentos como salida no son intuitivos. Al usar una función se entiende que los argumentos son parámetros de entrada y la salida la devolveremos al terminar la ejecución con el return. 3.Argumentos bandera, los argumentos boolean para indicar a la función el tipo de comportamiento que tiene que hacer son confusos. Si una función puede hacer más de una cosa, sepárala en dos funciones independientes. 4.Funciones muertas, funciones que nunca son usadas no tienes porqué tenerlas. No guardes código viejo inútil, bórralo. Tu sistema de control de versiones lo recordará por ti! Nombres 1.Escoge nombres descriptivos, los buenos nombres son el 90% de la legibilidad del código. Darle un buen nombre a una función, a una variable o a una clase no es algo trivial. Esta es de las partes más difíciles, los buenos nombres requieren de pensarlos con calma. No dejes nombres como i, j o aux. Los dos primeros casos si lo usas en un índice de un bucle, se podría pero porque esta variable i no abarca más de las tres líneas del bucle. Si se tratara de un índice global, no lo hagas! 2.Escoge nombres con un nivel de abstracción adecuado, al escoger nombre ten en cuenta en el nivel en el que te encuentras y mantén siempre el mismo. Si estás, por ejemplo, con una interfaz módem con varias funciones como la siguiente. public interface Modem { boolean dial(String phoneNumber); boolean disconect(); boolean send(); String getConnectedPhoneNumber(); } De primeras puede parecer que está correcta pero realmente ¿nos interesa saber que está implementada con un número de teléfono? Dentro de un tiempo si queremos usar otro tipo de localizador ¿como lo hacemos? Es por ello que sería mejor si lo hiciéramos de la siguiente forma. public interface Modem { boolean connect(String connectionLocator); boolean disconect(); boolean send(); String getConnectedLocator(); } 3.Usa la nomenclatura standar, donde sea posible, cuando estás implementando un patrón es probable que este tenga una nomenclatura estandarizada para dar nombres a ciertas partes de la aplicación como pueden ser las funciones, métodos o las clases. Sigue el estándar todo lo posible de esta forma no generas confusiones. Por ejemplo si tienes un método que transforma tu objeto a String, en Java, se usa toString(). Otro ejemplo son las funciones que puedes ver en los condicionales if(), estas suelen empezar por is. Quedando de esta forma if(isFromSpain(phoneNumber)). 4.Nombres no ambiguos, tienes que escoger un nombre que no se quede corto y deje esconder parte de la tarea que realiza una función. Si tienes una función que se llama rename() e internamente, cambia el nombre y añade un prefijo, te estás quedando corto. Un mejor nombre sería renameAndAddPrefix(). 5.Usa nombres largos para ámbitos largos, después tanto hablar de dar nombres descriptivos puedes llegar al extremo de dar nombres largos a variables contadoras en los iteradores. Como te he dicho en el apartado anterior si el ámbito del índice es solamente dentro del iterador for no hace falta que lo llames numberCounter si tienes dos líneas de código dentro y se ve que solamente se usa como iterador. 6.Evita codificar, a día de hoy los IDEs que tenemos son potentes, nos ayudan con los nombres, nos avisan si hay duplicados, si no usamos una variable. No tenemos que comenzar por l_ para indicar que la variable es local, ni nada parecido los IDEs nos lo indican. 7.Los nombres deben ser descriptivos, sin efectos secundarios, los nombres tienen que ser sinceros. No puedes tener una función public getTimer(){ if(localTimer == null){ localTimer = new Timer(): } return localTimer; } Si nos fijamos esta función no devuelve un timer lo que hace realmente es crear uno si no existe ya y luego lo devuelve. Un posible nombre más correcto para la función podría ser createIfNotExistsAndReturnTimer. Referencias Libro original sobre Clean Code, esta publicación corresponde con el capítulo 17.

Olores del código: comentarios y entorno

Olores del código: comentarios y entorno Existen muchas cosas que no huelen bien en el código y a continuación vas a poder ver las referentes a comentarios y al entorno. Esta es una publicación parte de una serie de publicaciones que haré referentes a olores del código. Comentarios Se que lo hemos hablado en varias ocasiones pero una vez más, los comentarios no son una mejora del código. Al contrario, suelen entorpecer más de lo que ayudan por las siguientes razones: 1.Información inapropiada, no hace falta añadir meta-datos a un fichero con comentarios. Cosas como fecha de última modificación, autor, etc no son necesarios y sólo generan ruido. 2.Comentarios obsoletos, tener comentarios explicando una parte de código es algo común (no he dicho que esté bien, es común solo eso). Pero la realidad es que esos comentarios nadie se encarga de mantenerlos y quedan rápidamente desfasados con el código al que está atado. Porque si tu cambias el funcionamiento de un método porque no está correcto, no te acuerdas de modificar el comentario que lo explicaba. 3.Comentarios redundantes, ya que no me vas a hacer caso y vas a poner un comentario, al menos que no diga lo mismo que puedo ver i++; //increment i no lo hagas. 4.Comentarios pobres, si sigues pensando que hace falta poner un comentario, al menos escribe el mejor que puedas. Usa la terminología del contexto en el que estás y no generes más confusión de la que ya hay. 5.Código comentado, por favor esto nunca. No dejes código comentado suelto por tu clase, este código nadie lo borra porque nadie sabe porqué está ahí. Y la realidad es que con cada día que pasa se vuelve más irrelevante, la variables que usa dejan de existir, lo métodos a los que llama cambian la firma, etc. Si está comentado, bórralo no es necesario. Si alguien lo necesita puede volver a la versión anterior de tu sistema de control de versiones y verlo. Entorno 1.Desplegar requiere más de un paso, si tienes una aplicación esta tiene que ser fácil de desplegar un paso, dos como mucho. No debes tener que comprobar decenas de ficheros, ver que dependencias falta y complicarte la vida a ti y a quien quiera usarlo. Tendrías que ser capaz de hacer algo parecido a esto get application, cd application, deploy application, run application. 2.Test requiere más de un paso, al igual que el caso anterior esta tiene que ser fácilmente testable. Tiene que poder ser testada con un simple comando que ejecute todos los test. Referencias Libro original sobre Clean Code, esta publicación corresponde con el capítulo 17. Sistema de control de veriones

JUnit Internos

JUnit Internos JUnit es de los frameworks open source más famosos de testing en Java. Es simple en su concepto, preciso y elegante de implementar. Además al tener tanta fama y tantos seguidores podemos encontrar documentación de sobra. Ejemplo básico Supongamos que tenemos una calculadora con la siguiente implementación. No es importante la implementación en si, pero si quieres reproducir un test te lo dejo, por aquí ;) public class Calculator { public int evaluate(String expression) { int sum = 0; for (String summand: expression.split("\\+")) sum += Integer.valueOf(summand); return sum; } } Y como es normal queremos hacer un test de nuestra calculadora porque como ya sabemos tener una buena batería de test es importante. Entonces implementamos el siguiente. import static org.junit.Assert.assertEquals; import org.junit.Test; public class CalculatorTest { @Test public void evaluatesExpression() { Calculator calculator = new Calculator(); int sum = calculator.evaluate("1+2+3"); assertEquals(6, sum); } } Como vemos es bastante fácil y limpio, es por lo que es tan famoso. Y como este podemos hacer todos los test que queramos, buscando hacer que falle la calculadora. Porque si conseguimos que falle es buena señal, ya hemos descubierto un hueco que tapar, una funcionalidad rota o que no existe. Y claro, mejor encontrarla nosotros que un usuario frustrado. Pasar los test no significa que no falle Y es aquí donde quería llegar, como he dicho puedes hacer todos los test que se te ocurran. Y ahí está el punto, los que se te ocurran. En este caso sólo tenemos uno y parece claro que esta calculadora no está completa ¿verdad? Claro, eso lo vemos nosotros que conocemos más operaciones aritméticas que no sea la suma. Pero, quien ha implementado esta calculadora no conocía más. Para él parece que está completa y testeada contra todos los problemas y casos existentes. No se si ves lo que trato de decirte. Tener una gran batería de test no significa que tu aplicación esté correcta o perfecta porque pasa todos los test. Eso solo significa que aún no has encontrado/escrito los suficientes test para encontrar un fallo. Y antes o después alguien se le ocurrirá otro caso que haga que la aplicación explote. Es por eso que los test si son importantes, es un gran apoyo contra los cambio que puedas hacer al código. Pero no significa que vaya a funcionar en todos los casos que se den. Haces test para probar todo, sabiendo que todo no puede ser probado. Esto es lo que le pasa al autor en este capítulo. Nos muestra un código de primeras bastante correcto y limpio, con una batería de test bastante completa. Y va haciendo varios cambios en el código, nombres de variables, encapsula algunos métodos, etc y finalmente descubre un fallo. Este fallo no estaba visible por como se redactaban las condiciones. Y tras un poco más de cambios en el código, descubre como dos condiciones más sobran. En un primer momento, miras y ves fSuffix > 0 puede parecer que tiene sentido. ... if (fSuffix > 0) result = result + computeCommonSuffix(); return result; ... Pero después de varias vueltas al código con paciencia, llegamos a esto otro que al verlo choca. ... if (suffixLength >= 0) result = result + computeCommonSuffix(); return result; ... Ya que al tratarse de una aplicación que comprueba si dos strings tienen algún carácter distinto. Si nos ponemos a ver el código, llegamos a la conclusión de como esa comparación no tiene sentido. Puesto que si ha llegado a este punto es porque existe un sufijo, es decir es imposible que sea 0 y nunca entrará al else. Una vez sabemos esto podemos borrar ambas comparaciones dejando más claro aún el código. Y todo esto porque el autor quiso darle una vuelta a un aplicación que parecía, de primeras testeada a prueba de misiles nucleares. Pero a pesar de ello se podía mejorar aún más. Siempre se puede mejorar Referencias Libro original sobre Clean Code. Página oficial de JUnit. Wiki primeros pasos con JUnit.

Refinamiento Sucesivo

Refinamiento Sucesivo Si te mostrara ahora un trozo de código y te dijese: “Mira que limpio está” podrías pensar que esto ha salido a la primera de mi cabeza porque soy muy bueno pero no es así. Cuando escribes un código la mayoría de veces te pasará que empiezas a hacer cosas “porque funcionan” sin pensar mucho en las buenas prácticas sobretodo cuando estás empezando con ellas. Pero no por eso debes dejarlo pasar. El código que escribas debes considerarlo como un borrador que siempre tiene mejoras pendientes, cada vez que hagas una funcionalidad antes de considerarla hecha dale una vuelta, revísala como si fuera de tu amigo o compañero y trata de mejorarla (siempre se puede). Es por ello que en este capítulo del libro muestra una clase que implementa y como al verla en su “forma final” gusta pero cuando te enseña las primeras versiones ves que realmente no era tan bonita en sus inicio que se ha llevado varios refinamientos para dejarla en el punto en el que se encuentra ahora. En Incrementalismo La mejor forma de romper un programa que funciona es hacer cambios de nombres “para mejorar” la legibilidad en masa esto no suele llegar a buen puerto nunca… Suele generar problemas, conflictos con otros nombres, y un largo etcétera. Para poder hacer estos cambios tranquilos hay una solución TDD, esto junto con hacer muchos cambios pequeños que vamos comprobando. En este caso las comprobaciones las podremos hacer de manera automáticas con los test que tendremos hechos para nuestro programa. De manera que después de cada cambio ejecutamos los test y si estos fallan volveremos al estado anterior donde todo funcionaba, no haremos cambios que rompan el programa. O en caso de que lo que se rompa sea poca cosa y veamos que se puede solucionar porque no era así como debería funcionar, podemos solucionarlo pero como estábamos hablando de cambios de nombres a variables y métodos normalmente si estos generan un problema no suele ser tan trivial. Conclusión Es por todo ello que el código que hacemos no se considera terminado cuando funciona, porque hacer que funcione algo puede hacerlo cualquiera pero los buenos programadores además lo hacen de manera limpia y lo dejan con pruebas para evitar que los cambios lo rompan. Referencias Libro original TDD, Test Driven Development o Desarrollo Dirigido por Test. Notas Durante todo el capítulo el autor hace cambios en su primera versión del código y va explicando cada uno de ellos la línea que sigue de pensamiento. Subiré estos cambios explicados de manera calmada en el futuro.

Concurrencia

Concurrencia Concurrencia… Aaaah mi amiga la concurrencia, como te quiero y te odio a la vez. Tú junto con la recursividad has sido, de momento, los dos conceptos que más me ha costado entender en la informática. Es de esas cosas que o entiendes a la primera o tardas tiempo hasta que un día, hace “click” en tú cabeza y todo cobra sentido, vamos a por ti ¿eres realmente tan necesaria? ¿Que es la concurrencia? La concurrencia, resumiendo mucho, consiste en poder hacer mas de una tarea en el mismo instante de tiempo. Llevado al mundo de la programación dos funciones/métodos/ejecuciones están ejecutándose al mismo tiempo. Problemas que surgen Imaginemos que tenemos un simple programa que incrementa un contador, turno para ser atendidos, cada vez que un usuario pulsa un botón, fácil ¿no? Una clase con un campo contador y un método que devuelve el contador y le suma una unidad. Pues si este trabajo lo hacemos concurrente pongamos que con tres usuarios que llegan en el mismo instante de tiempo y lo solicitan a la vez pueden ocurrir muchas cosas si no controlamos este contador como debemos. Puede ser que el primer usuario tenga el número 15, luego el segundo el 16 y quede un 17 para el siguiente, suerte todo ha salido bien. O puede que al ser la petición al mismo tiempo ambos tengan el 15 y quede el 16 para el siguiente. O aún peor puede que el primero tenga el 15 el segundo el 16 pero quede un 16 para el siguiente que venga. En la concurrencia todo es posible. Los hilos deben ser independientes Cuando trabajamos con concurrencia y creamos nuestros hilos para dar solución al problema estos deben ser lo más independientes posibles, porque no te puedes basar en el estado de otro hilo en ningún momento ya que este va a su ritmo al igual que tú, puede que estés esperando algo que aún no ha ocurrido. Ejemplos Productor-Consumidor Uno de los ejemplos típicos en la concurrencia es el del la pila de productos en la que una persona se encarga de añadir objetos a ella y otro de consumir de la misma. El que produce tiene que esperar a tener espacio para añadir el nuevo objeto y el que consume tiene que esperar a que exista algún objeto en la pila para poder consumir. Para lograr estar coordinados el consumidor y el productor mandan señales de aviso el uno al otro, quien produce cada vez que añade un producto avisa que la pila no está vacía y el consumidor cada vez que saca un objeto avisa de que la pila no está llena. Así ambos saben que pueden actuar. Lectores-Escritores Otro ejemplo conocido es el de lectores y escritores. Si tenemos un documento el cual puede ser leído y escrito por múltiples personas no se puede solucionar de igual forma que el anterior, pues si el escritor no puede actuar sobre el documento hasta que el/los lector/es terminen con él puedes tener múltiples lectores, que se acumulen y que nunca llegue a estar libre el documento. Hay que buscar una forma de hacerlo de manera más equilibrada. Conclusión La concurrencia de código no es trivial, cuesta de comprender y mucho más de manejar con correctitud. Si estás pensando en empezar con ella, tómatelo con calma y no esperes que todo cobre sentido en un día. Referencias Libro original

Sistemas

Sistemas En este capítulo el autor empieza con un símil que me gusta mucho y voy a tratar de traducir lo más fielmente que sé. ¿Cómo construirías una ciudad? ¿Podrías administrar todos los detalles por ti mismo? Probablemente no. Incluso administrar una ciudad es mucho para una sola persona. Sin embargo, las ciudades funcionan (la mayor parte del tiempo) Funcionan porque tienen equipos de personas que administran partes de la ciudad, el sistema de agua, etc […] Las ciudades funcionan porque tienen los niveles apropiados de abstracción y modularidad haciendo posible para las personas y “componentes” se las arreglen para trabajar efectivamente, sin entenderla a gran escala. Aunque los equipos de desarrollo a menudo se organizan así también, los sistemas en los que trabajan a menudo no tienen la misma separación de preocupaciones y niveles de abstracción. […] En este capítulo veremos como mantenerse limpio a niveles altos de abstracción, a nivel de sistema. Y me gusta porque realmente veo así una aplicación o producto software como un ente enorme que tienes que separar en pequeñas “responsabilidades” para poder gestionarlo. Separar la construcción de un sistema de usarlo Una de las formas de separar la construcción del uso es mover todos los aspectos de construcción (creación de objetos) a nuestro main. De esta maneja queda un flujo limpio y fácil de comprender, creamos todos los objetos que nos hacen falta en el main y luego los enviamos a la parte de nuestra aplicación donde nos sea necesario. Es decir a nuestro main no le entra información de la aplicación solo envía hacia afuera. Fábricas Esto no siempre es posible, por ejemplo si tenemos una aplicación de pedidos, esta tendrá que modificar la lista de pedidos añadiendo un nuevo objeto alguna que otra vez. Para ello podemos usar el patrón Abstract Factory Como podemos ver nuestro cliente (main) tiene una interfaz genérica para nuestros productos (productoA) y una fábrica (AbstractFactory), de esta manera el conoce que puede crear productos mediante el uso de la fábrica pero desconoce como esta los crea ya que es una interfaz y carece de detalles de implementación. A él lo único que le interesa e importa es que puede crearlos y usarlos. Inyección de dependencia La inyección de dependencia consiste, como su nombre indica, en añadir, insertar dependencia a un objeto. Esto no es recomendable porque creas una dependencia grande entre objetos pero en ocasiones es la mejor solución que tenemos para asegurarnos de que el objeto B que usamos dentro del objeto A es el que queremos y como lo queremos. Una interfaz puede ser algo como IDisposable, IEnumerable o IPrintable. Una clase es una implementación real de una o más de estas interfaces: List o Map pueden ser implementaciones de IEnumerable. Para entendernos: a menudo tus clases dependen unas de otras. P.ej. podría tener una clase database que acceda a su base de datos, pero también desea que esta clase inicie sesión para acceder a la base de datos. Supongamos que tiene un registrador (logger) entonces la base de datos tiene una dependencia al registrador. Hasta aquí todo bien. Puede modelar esta dependencia dentro de su clase de Base de Datos con la siguiente línea: var logger = new Logger (); y todo está bien Está bien hasta el día en que se da cuenta de que necesita un grupo de registradores: a veces desea iniciar sesión en la consola, a veces en el sistema de archivos, a veces usando TCP / IP y un servidor de registro remoto, y así sucesivamente … Y, por supuesto, NO quieres cambiar todo tu código (mientras tanto, tienes miles de millones) y reemplazar todas las líneas var logger = new Logger (); por: var logger = new TcpLogger (); Primero, esto no es divertido. En segundo lugar, esto es propenso a errores. Tercero, este es un trabajo estúpido y repetitivo para un mono entrenado. Entonces, ¿Qué haces? Obviamente, es una buena idea introducir una interfaz ICanLog (o similar) que implementan todos los registradores. Así que el paso 1 en tu código es lo que haces: ICanLog logger = new Logger (); Ahora que la inferencia de tipo ya no cambia de tipo, siempre tienes una única interfaz contra la cual desarrollar. El siguiente paso es que no desee tener un nuevo Logger() una y otra vez. Así que pones la fiabilidad para crear instancias nuevas en una única clase central de fábrica y obtienes un código como: ICanLog logger = LoggerFactory.Create (); La fábrica misma decide qué tipo de registrador crear. A su código ya no le importa, y si desea cambiar el tipo de registrador que está utilizando, cámbielo una vez: Dentro de la fábrica. De esta manera con la interfaz te aseguras que todas las implementaciones de registrador, sea cual sea actúen de la misma forma ya que implementan la misma interfaz. Esta última último tramo de la publicación es una traducción de una respuesta en StackOverflow la respuesta completa aquí. Referencias Libro original Abstract Factory Esquema abstract factory (imagen) Inyección de dependencia StackOverflow Respuesta StakOverflow

Clases

Clases Hasta ahora hemos visto como escribir de la mejor manera posible lineas y bloques de código, pero aun no hemos visto como hacerlo con las clases. Ordenar los métodos A la hora de organizar las clases es importante que si tenemos un método que hace uso de otro que tenemos en nuestra clase, es mejor si lo ponemos a continuación, de manera que si estamos leyendo el código no tengamos que dar saltos en él y sea lo más parecido a un artículo. Modificadores Nuestras variables, métodos o funcionalidades deben tener el modificador más restrictivo posible, si tenemos que acceder a un método en un test y no podemos por ser privado lo pondremos como protected, de manera que será accesible desde el mismo paquete. Principio de responsabilidad única Un punto importante a la hora de desarrollar un clase es el tamaño porque, el tamaño si importa, al igual que con lo métodos las clases tienen que ser lo más pequeñas posibles y en lo que a dimensiones se refiere no hay un máximo de líneas. En su lugar lo que hay que tener en cuenta es el número de responsabilidades, una clase no debe tener más de una responsabilidad si se te pasa por la cabeza añadirle otra (consejo, probablemente esto sea una nueva clase). Y esto el principio más importante en la Orientación a Objetos, el principio de responsabilidad única (SRP) y en resumidas cuentas dice que una clase debe tener un solo cometido, de manera que si cambia sea por una única razón. Evitando entremezclar términos de lógica de negocio, con persistencia, con interfaz de usuario. Cohesión Es importante que las clases tengan el menor número posible de instancias de variables y además, para lograr mayor cohesión estas variables tienen que ser accedidas por el mayor número de métodos de la clase. Se dice que una clase es cohesiva cuando cada método de esta accede a cada variable instanciada. En general es complicado alcanzar estos niveles de cohesión. Por ejemplo la siguiente clase tiene un nivel de cohesión bastante elevado. public class Stack { private int topOfStack = 0; List<Integer> elements = new LinkedList<Integer>(); public int size() { return topOfStack; } public void push(int element) { topOfStack++; elements.add(element); } public int pop() throws PoppedWhenEmpty { if (topOfStack == 0) throw new PoppedWhenEmpty(); int element = elements.get(--topOfStack); elements.remove(topOfStack); return element; } } Como se ve tienen tan solo dos variables instanciadas y sólo en un método no se accede a ambas (size). Libro original

Test Unitarios

Test Unitarios La programación a evolucionado mucho en tan solo 20 años, antes por 1997 cuando estaba empezando no había forma de probar las funciones que creábamos. No era raro crear la función añadirle una parte en la que podamos introducir por teclado caracteres o alguna orden y ver como responde este, pero a día de hoy existen los test unitarios. Test que ejecutarán nuestra función y comprobarán si el resultado obtenido es el que nosotros esperábamos. Tan buenos son estos test y tanto ruido han hecho las metodologías ágiles y el TDD que no es raro a día de hoy que en una entrevista de trabajo te pregunten explícitamente por ellos. Las tres leyes del TDD No escribirás código de producción hasta que exista un test que falle. No escribirás más de un test unitario que falle. No escribirás más código de producción del necesario para pasar el test. Estas reglas se convierten en un ciclo de trabajo que no dura más de 30 segundos. Escribes un test, compruebas que falle, escribes el código para que este no falle. De esta manera escribimos los test y el código que lo pase al mismo tiempo. Si tomamos este hábito será fácil escribir docenas de test diariamente lo que hará que cada mes tu software tenga cientos de test nuevos que lo prueban ¿quien no quiere eso? Mantener los test limpios Puede que pienses que los test son una simple herramienta para llegar a un código de producción sólido y robusto, que realmente el fin es este código de producción. Y por ello no le prestes mucha importancia al como realizar los test, los creas con “prisa” dejas variables o los propios test con malos nombres. El problema vendrá en el futuro cuando creando un nuevo test para una nueva funcionalidad tienes que cambiar algo del código y bum explotan unos cuantos test a parte del nuevo. Comienzas a leer y ves que no tienes idea de que están probando realmente, en ese momento comenzará un viaje el cual (con suerte) si has escrito el test hace poco y tienes buena memoria acaba rápido pero en la mayoría de casos no será así. Con todo esto quiero decir que el código de los test es tan importante como el de producción. Un test limpio ¿Como mantenemos un test limpio? Legibilidad, al igual que hemos hablado de como hacer un código limpio los test funcionan de un modo similar: claridad, simplicidad y densidad. Imagina que te enfrentas a este test: public void testGetPageHieratchyAsXmlDoesntContainSymbolicLinks() throws Exception{ WikiPage pageOne = crawler.addPage(root, PathParser.parse("PageOne")); crawler.addPage(root, PathParser.parse("PageOne.ChildOne")); crawler.addPage(root, PathParser.parse("PageTwo")); PageData data = pageOne.getData(); WikiPageProperties properties = data.getProperties(); WikiPageProperty symLinks = properties.set(SymbolicPage.PROPERTY_NAME); symLinks.set("SymPage", "PageTwo"); pageOne.commit(data); request.setResource("root"); request.addInput("type", "pages"); Responder responder = new SerializedPageResponder(); SimpleResponse response = (SimpleResponse) responder.makeResponse(new FitNesseContext(root), request); String xml = response.getContent(); assertEquals("text/xml", response.getContentType()); assertSubString("<name>PageOne</name>", xml); assertSubString("<name>PageTwo</name>", xml); assertSubString("<name>ChildOne</name>", xml); assertNotSubString("SymPage", xml); } Puede que logres comprenderlo después de un tiempo de análisis, no digo que sea imposible. Incluso puede que no te lleve mucho tiempo, pero enfrentarse a test así diariamente acaba quemando antes nuestra cabeza. Si en lugar de eso tenemos ese mismo test pero de la siguiente forma: public void testSymbolicLinksAreNotInXmlPageHierarchy() throws Exception { WikiPage page = makePage("PageOne"); makePages("PageOne.ChildOne", "PageTwo"); addLinkTo(page, "PageTwo", "SymPage"); submitRequest("root", "type:pages"); assertResponseIsXML(); assertResponseContains( "<name>PageOne</name>", "<name>PageTwo</name>", "<name>ChildOne</name>" ); assertResponseDoesNotContain("SymPage"); } Sigue teniendo las mismas tres partes diferenciadas. Una primera parte donde creas los datos para el test, a continuación donde utilizamos estos datos y finalmente comprobamos si el resultado es el esperado. Un solo assert por test Una buena mentalidad es la de un solo assert por test, en la práctica no es tan fácil y veremos que aveces tendremos que poner más de uno. Es una mentalidad que se suele tener en cuenta pero no es posible llevarla a cabo en todos los casos. Por ello mejor el mínimo de asserts por test. Lo que realmente tiene que ser único por test es el concepto a probar, que es lo que queremos poner a prueba y eliminar todo el ruido que pueda generarse a su alrededor. Con esto me refiero, si tienes una función que puede generar tres casos, por ejemplo. Dado un número este puede ser mayor, menor o igual. No haremos un test que pruebe estos tres casos de una sola vez, tenemos que hacer tres test independientes de manera que cada uno de ellos prueba un concepto, un caso. F.I.R.S.T. Las cinco reglas que siguen los test limpios: Fast, rápido: un test tiene que ejecutarse rápido, si tenemos un test que tarda bastante en completarse no nos gustará ejecutarlo con frecuencia y tardaremos más en ver posibles errores. Independent, independiente: los test tienen que ser independientes unos de otros, no podemos tener test que están conectados entre ellos porque en el momento que el primero falle todos los demás irán detrás, y será complicado saber donde empieza el problema. Repeatable, repetible: los test tienen que poder ser ejecutados en cualquier ambiente (enviroment) desde producción hasta tu portátil en casa sin conexión a internet. Self-validating, auto-validados: los test tienen que, por si mismos, dar como resultado un boolean (verdadero o falso) no queremos test que guarden un resultado en un documento de texto que tendremos que mirar a posterior y comprobar si coincide con otro que ya tenemos, Somos humanos y nos equivocamos, podemos no comprobar bien estos resultados y más cuando llevamos ya unas cuantas horas de trabajo encima ese día. Timely, oportuno: los test solo serán escritos antes del código de producción que haga que los pase. Si tratas de escribirlos después acabarás odiando los test, porque habrá partes que son muy complicadas de probar o el código de producción que tienes no está si quiera pensado para ser probado. Libro original Referencias Template method Given When Then

Límites

Límites Cuando consumimos una API de terceros existe un conflicto de ideas entre quien la crea y quien la consume. Los creadores quieren llegar a la mayor cantidad de público posible y, los consumidores de esta, quieren que sea lo más consisa posible y esté lo mejor enfocada con su problema para evitar funcionalidades superfluas. Por ejemplo si usamos un Map es normal ver lo siguiente repetidas veces en nuestro código. Sensor s = (Sensor) sensor.get(sensorId); Si, funciona y si, estámos acostumbrados a verlo con bastante frecuencia pero en términos de clean code es mejorable. Todo porque clase Map devuelve un objeto genérico. ¿Pero por qué no “solucionamos” este problema? Podemos crear una clase en medio que en lugar de devolver object devuelva Sensor directamente public class Sensor { ... public Sensor getById(String id) { return (Sensor) sensors.get(sensorId); } ... } De esta forma evitamos muchos problemas y hacemos que el uso sea más claro, además podremos limitar el uso a las funcionalidades que realmente nos hacen falta evitando el ruido del que hablamos en el comienzo de una API que trata de contentar a un gran público. Aprende con los test Si estamos haciendo uso de una nueva API es normal que al comienzo hagamos algunas funcionalidades pequeñas para comprender el funcionamiento de esta y como trabajar con ella correctamente en un proyecto de pruebas donde no rompas nada. ¿Y si en lugar de eso creamos unos test básico? ¿Qué puede tener de malo? Que cuando cambien la API nos demos cuenta porque los test fallan, si un conpañero está en la misma situación pueda ver las funciones básicas en esta “documentación” hechas con los test, si dentro de un tiempo vamos a volver a usarla tener donde refrescar la memoria. Creo que he logrado dejar claro que es una buena idea que ayuda más de lo que molesta y no te consumirá tanto tiempo como para no merecer la pena. Libro original

Manejo de errores

Manejo de errores Puede sonar raro hablar de errores en un libro que trata sobre código limpio, pero los errores son algo que ocurre porque somos humanos y como tal erramos. Un usuario puede perfectamente introducir un dato no válido y esto tenemos que controlarlo de alguna manera. Usa excepciones en lugar de códigos de error Antes era normal ver en funciones esta función devolverá un número mayor a 0 en caso de que termine correctamente, en caso contrario -1 si no se encontró el fichero, -2 si no se pudo acceder, etc. Esto ocurría porque no existían excepciones, a día de hoy hacer esto solo hace que el código de quien usa tu función se ensucie al tener que controlar si el valor devuelto es válido o no y porque no lo es. En lugar de esto todo queda más limpio si cuando ocurre un error lanzamos una excepción. Usa excepciones sin marcar (Unchecked Exceptions) Las checked exceptions son aquellas que tienen que estar en la firma del método reflejadas como que pueden ocurrir en algún momento. En los inicios cuando Java las añadió parecían una buena idea, pero con el paso de los años se han dado cuenta que no son tan necesarias como pensaban. Esto ocurre porque si, tiene sus ventajas, pero también sus inconvenientes. Uno de ellos es que estas no respetan el principio abierto/cerrado (Open/Closed Principle). Imaginemos, lanzamos un nuevo checked exception en un método y el catch de este está tres niveles por debajo en la implementación. Tendremos que ir nivel por nivel cambiando la firma de todos los métodos para que la aplicación compile nuevamente… Esto no parece una buena idea, y eso que solo son tres niveles si se tratase de una aplicación grande en la que hay muchos más niveles pasaremos una buena tarde cambiando todos los niveles. Esto podemos evitarlo usando unchecked exceptions. Explica el contexto de tu excepción Si creas una excepción, se lo más claro posible explicando el contexto y la localización del error en el mensaje. ¿Porqué ha ocurrido esta excepción? Define el flujo normal No hay porque crear excepciones sin pensar hay casos en los que, con cambiar la lógica de nuestra aplicación solucionamos el problema. Supongamos lo siguiente: try { GastosDeComida gastos = reporteDeGastos.obtenerComida(idEmpleado); gastosTotales += gastos.obtenerTotal(); } catch (GastosDeComidaNoEncontrados e){ gastosTotales += obtenerComidaPorDia(); } En este ejemplo si no encontramos los gastos en comida del empleado lanzamos una excepción y entonces añadimos la comida por días pero, ¿porqué generamos esta excepción? Si en lugar de lanzar la excepción controlamos en el método obtenerTotal(), si no hay total en este empleado devolvamos la comida por día, de manera que pase lo que pase siempre devolveremos un dato con el que poder trabajar y todo se soluciona evitando todo esto. No devuelvas nulos Si has trabajado con Java un tiempo, es normal que en algún momento te encuentres creando algo como esto: if(usuario != null){ Tarea[] tareas = usuario.obtenerTareas(); if(tareas != null){ ... } } Puede incluso que te parezca hasta normal ¡pero no lo es! si estás creando una clase y devuelves un nulo recuerda, te estás dejando más trabajo para el futuro. Puedes pensar que no es para tanto, una comprobación de si es nulo o no y ya está pero veamos, que ves más fácil de comprender y ver de primeras entre estos dos códigos: List<Empleado> empleados = obtenerEmpleados(); if(empleados != null){ for(Empleado e: empleados){ pagoTotal += e.obtenerPago(); } } List<Empleado> empleados = obtenerEmpleados(); for(Empleado e: empleados){ pagoTotal += e.obtenerPago(); } Creo que ves por donde voy, la segunda opción queda más clara. Pero además dejando la claridad y lo bonito que queda supongamos que se te olvida hacer la comprobación de si es nulo o no, ¿ahora que? a buscar en la pila del error porque es nulo y donde y como tengo que hacer para solucionarlo. Y todo porque cuando implementaste la función obtenerEmpleados() no hiciste una comprobación del tipo si no hay empleados devuelvo una lista vacía. No pases nulos como parámetros Si devolver nulos está mal, ¡pasarlos como parámetros es aún peor! Imagina que estás usando una API la cual no espera que le pases un nulo, ¿que va a pasar? Pues lo esperado nuestro “querido” NullPointerException y como lo vas a solucionar si la API es tuya puedes añadirle excepciones que, no deberían estar ahí, ensucian y hacen que sea menos claro su funcionamiento. Así que hazte un favor y evita los nulos de todas las formas que puedas. Libro original TODO Escribe tu bloque Try-Catch-Finally primero

Objetos y estructuras de datos

Objetos y estructuras de datos ¿Porque crear variables privadas si acto seguido creamos los getters y setters? Con esto hacemos que el modificador private pierda el sentido. Los getter y setter solo deben estar cuando sea necesario su existencia porque estamos compartiendo esos datos crudos. Cuando creamos una clase lo hacemos con la intención de mostrar unos datos con un formato. Por ejemplo, si estamos con una clase que sea para control del combustible de un vehículo ¿Cual de las dos clases siguientes esta mejor? public interface Vehiculo{ public double capacidadDelTanqueEnLitros; public double litrosDeGasolinaActuales; } public interface Vehiculo{ void rellenarTanque(double litros); double damePorcentajeDeCombustibleRestante(); } El segundo caso es el aconsejable, en esta clase no importa como guardamos los datos si en litros o galones o centímetros cúbicos. El usuario solo le interesa cuanto le queda respecto del total y poder indicar que ha llenado el deposito, y eso es lo que le damos en la segunda. No tenemos que dar mas datos de los que son necesarios y con el formato correcto. De forma que si en algún momento queremos cambiar la forma en la que implementamos esta clase, el tipo de datos o la forma de calcular, el usuario no le supondrá problema. Ya que en el segundo caso seguiremos devolviendo el mismo resultado, pero calculado de otra manera o en otras unidades pero haciendo la conversión antes de devolver el resultado. En el primer caso el usuario de nuestra clase tendrá que hacer cambios donde use esos campos. Datos estructurados u Objetos Pongamos unos ejemplos para reflejar las diferencias entre estos. En el primero de ellos implementamos una clase por cada figura geométrica y otra en la que calculamos el área. public class Cuadrado { public Punto superiorDerecho; public double lado; } public class Rectangulo { public Punto superiorDerecho; public double altura; public double anchura; } public class Circulo { public Punto centro; public double radio; } public class Geometria { public final double PI = 3.141592653589793; public double area(Object figura) throws FiguraNoSoportada { if (figura instanceof Cuadrado) { Cuadrado cuadrado = (Cuadrado) figura; return cuadrado.lado * cuadrado.lado; }if (figura instanceof Rectacgulo) { Rectangulo rectangulo = (Rectangulo) figura; return rectangulo.altura * rectangulo.anchura; }if (figura instanceof Circulo) { Circulo circulo = (Circulo) figura; return PI * circulo.radio * circulo.radio; } throw new FiguraNoSoportada(); } } Los programadores orientados a objetos estarán arrancándose los pelos de la cabeza al ver esto, pero tiene sus aspectos positivos si tienes que añadir una función perímetro en la clase Geometría las clases de figuras ¡no se ven afectadas! Pero por otro lado si incorporamos una nueva figura todos los métodos de la clase Geometría tendrán que ser actualizados con la nueva. Si por el contrario tenemos el caso siguiente en el que usamos la orientación a objetos en el que el método area() sea polimórfico, la clase Geometría no sera necesaria gracias al uso de las interfaces. Y en caso de tener que añadir una nueva figura ¡no tendremos que hacer nada! public class Cuadrado implements Figura { private Punto superiorDerecho; private double lado; public double area() { return lado * lado; } } public class Rectangulo implements Figura { private Punto superiorDerecho; private double altura; private double anchura; public double area() { return altura * anchura; } } public class Circulo implements Figura { private Punto centro; private double radio; public final double PI = 3.141592653589793; public double area() { return PI * radio * radio; } } Solo para dejarlo claro son dos implementaciones completamente opuestas objetos o estructuras de datos, tu decides. Si prevés que vas a incluir nuevas funciones en un futuro las estructuras de datos son mucho mas fáciles pero, por el otro lado, si tu previsión es que incluirás nuevos “tipos” de datos la orientación a objetos soluciona el problema mucho mas sencillamente. La ley de Demeter Resumiendo mucho esta ley dice que quien modifica (modulo que lo usa) un objeto no debe conocer sus entresijos (como se implementa internamente). Esta ley no es aplicable a las estructuras de datos, ya que como vimos antes el funcionamiento de estas es justamente lo contrario. Esta ley de Demeter es aplicable para la orientación a objetos. Híbridos Si vas a implementar ambos casos a medias terminaras por no implementar ninguno y quedarte con la peor parte de los dos. No hagas un híbrido de objeto y estructura de datos porque acabaras con la peor parte de cada uno de ellos, analiza y decide cual compensa mas implementar, seguramente no uses todas sus ventajas y sufras algunos de sus defectos pero es decisión tuya saber cual compensa una cosa con la otra de mejor forma. Libro original

Formato

Formato ¿Dejar una linea en blanco entre métodos o no? ¿El corchete de inicio de la función en la misma linea o en la siguiente? ¿Los campos de la clase todos en la parte superior o al final? Parecen pequeños detalles insignificantes pero a la hora de leer y comprender lo que hemos hecho es mejor seguir siempre un mismo estilo y mas aun si estamos trabajando en equipo. A veces depende del lenguaje que usemos pero en la gran mayoría de casos es un tema del cada persona. De estos temas no hay hojas de estilo estrictas que sigan todos los programadores, pero existe unas “normas” que todos conocen o van descubriendo con el paso del tiempo. Formato vertical ¿Cuanto debe ocupar un fichero? Como ya dije no hay nada escrito en Java un fichero es una clase, si estamos haciendo lo correcto. Estas si miramos casos de proyectos ya desarrollados vemos que rara vez superan las 500 lineas y que normalmente se extienden 200 lineas, en esta extensión una clase tiene mas que suficiente para realizar todas las funciones que debería. Toda nuestra clase debe de estar estructurada como un articulo empezando por un titulo que nos acerque sobre el tema que trata esta, luego una introducción donde tendremos los campos de la clase y el constructor, con lo que sabremos con una mirada rápida quienes son los “personajes” que tenemos en nuestra historia. Un nudo donde estarán todas las funciones de la clase. Todos estos métodos deben de estar tan cerca unos de otros como de relacionados estén entre si. De manera que si en un primer método usamos un segundo este debería estar justo debajo, como si continuásemos un párrafo. Todo esto es por sentido común, no lo pondremos lejos para estar saltando de arriba a abajo sin parar hasta marearnos. De igual manera las variables no las declararemos muy lejos de donde las usamos, si estas solo tienen razón de ser dentro de un método lo declararemos en este. Si es una variable para controlar un bucle, esta estará justo encima del bucle. Formato horizontal En los inicios de la informática no se escribían mas de 80 caracteres (si no me equivoco) porque los terminales donde se veían no alcanzaban mas. Hoy en día no podemos tener esta guía dada la gran cantidad de monitores en el mercado, panorámicos, etc. de todos los tamaños y colores. Pero como limite se podría decir que unos 120 caracteres es una medida buena. Los espacios entre los parámetros de una función, personalmente me gusta que después de cada coma ‘,’ dejar un espacio y es recomendable para ayudar a ver que se tratan de variables diferentes. De la misma forma podemos dejar espacios entre las variables de una operación si ayuda a que esta se vea de forma mas clara. Cuando declaramos muchas variables seguidas, hay quienes las declaran de la siguiente forma: private Socket socket; private InputStream input; private OutputStream output; private Request request; private Response response; private FitNesseContext context; protected long requestParsingTimeLimit; private long requestProgress; private long requestPars; Puede parecer a primera vista que de esta forma queda mas claro pero no, no es verdad es mas fácil no seguir la linea que toca y terminar leyendo mas arriba de donde empezamos equivocándonos. private Socket socket; private InputStream input; private OutputStream output; private Request request; Reglas de equipo Todas esta reglas que seguimos cada uno de nosotros al escribir no dejan de ser por gusto personal. Por ello si vamos a realizar un proyecto en equipo es mejor usar 10 minutos antes de empezar a hacer nada y llegar a un acuerdo entre todos para que todo este sea de la misma forma y no veamos decenas de estilos diferentes. Sera una ayuda en el futuro si tenemos que leer parte del trabajo hecho por un compañero. Libro original

Comentarios

Comentarios Comentarios, un buen comentario puede ser muy útil, puede ser la mejor ayuda que encontraste ese día pero, por otra parte pueden ser tan dañinos y malvados que ni el mismo autor de ellos sabrá porque están ahí. La mala noticia es que la mayoría de las veces los comentarios entran en este segundo grupo. Malos comentarios No arreglan mal código Se supone que cuando dejamos un comentario lo hacemos para suplir alguna carencia que tenemos en el código así que primer consejo, no maquilles mal código con comentarios. Si unas líneas de tu código no hacen lo que dicen, no están nombradas como deberían o no tienen sentido que estén ahí, no les añadas un comentario aclaratorio no es la solución. No explican que estás haciendo Si estás ante una condición como esta // Comprobar si el empleado puede ser seleccionado para jubilarse if ((empleado.señal & SEÑAL) && (empleado.edad > 65)) ¿Porque no intentas darle la vuelta a esto y hacer un código auto explicativo? if (empleado.estaPreparadoParaLaJubulación()) No son redundantes Si tienes unas líneas que se explican por si solas no dejes un comentario que explican exactamente lo mismo. // Si está cerrado devuelve la hora de apertura if(cerrado){ return new HorarioApertura(); } Tampoco hagas esto, creo que sobra explicar porqué. /** * * @param titulo El titulo del CD * @param autor El autor del CD * @param año El año del CD */ public CD(String titulo, String autor, String año){ ... } No engañan No dejes comentarios que engañan al lector, no escribas diciendo que este método devuelve verdadero cuando la tienda está cerrada y luego si miras la implementación realmente lo que hace es mirar si está cerrada y en caso de que no lo esté espera un tiempo para realizar una segunda comprobación. Porque con esto solo logras que al usar esta función no obtengas los resultados esperados. Deben aportar algo Si escribes un comentario para explicar algo que no tiene razón de ser explicado, sobra no dejes ese comentario no expliques que esta variable que estás declarando es privada si delante de ella tienes puesto private, no dejes un comentario sobre un constructor por defecto diciendo “este es el constructor por defecto”. ¿Que pretendes lograr con todo esto? Yo te digo lo que logras con todo ello, logras generar ruido en el código. Con ruido me refiero a líneas de código que no tienen razón de estar ahí que entorpecen a los demás a la hora de leer. No cierran funciones En los inicios de la programación, estos tenían algo de sentido pero a día de hoy no tienen razón de ser. Si no sabes de lo que te hablo mejor, no los has tenido que ver significa de algún modo todo que estamos por el buen camino. Me refiero a lo siguiente. while(condición()){ if(comprobación()){ for(){ ... } //for ... } //if } //while A día de hoy con los IDEs que tenemos que nos marcan con colores donde cierra cada llave, nos permiten colapsar las líneas que tiene dentro incluso, no hay razón válida para que esto siga existiendo. No son código no válido No comentes código que ha dejado de servir, que ya no funciona o incluso nunca ha llegado a funcionar. Si ese código ya no lo usas ¿para que lo “guardas”? En serio crees que en algún momento haciendo construyendo otra clase, dirás “cónchale voy a rescatar este trozo que dejé comentado, que no tiene nada que ver” porque te aviso ya, que esto no ocurre. Es más si ya se te ha ocurrido la solución una vez, se te ocurrirá una segunda y de manera más rápida, en serio no comentes código porque te costó mucho trabajo llegar a él o porque “me será útil luego”. Buenos comentarios Existen circunstancias, como ya he comentado, donde un comentario puede ser de gran ayuda. Aunque bajo mi punto de vista siguen siendo un arma de doble filo, explicaré al final porqué. Comentarios legales Comentarios que por la razón legal que sea tienen que estar escritos, con el autor, el año, empresa, etc. Comentarios informativos Comentarios que información básica de alguna sentencia compleja. Una expresión regular por ejemplo, puede estar bien explicar de manera rápida y básica que comprueba, aunque siempre se puede extraer a una clase que se encarga de estas comprobaciones, de forma que este comentario no haga falta. Explicar la intención Si has solucionado un problema no de la mejor forma, puedes indicar que lo has hecho así con un porqué. Comentarios aclaratorios En caso de que estés usando una librería que los valores que devuelve no corresponden con resultados legibles, puede estar bien un comentario a final de la línea explicando porque ese 1 que devuelve si es mayor que nuestro valor indica que debemos sumar dos valores. Javadocs Si estás creando una API pública es casi obligatorio dejar estos comentarios siguiendo el formato. TODO Estos comentarios están estandarizados y representan problemas que como programador no puedes solucionar en este momento o porque no quieres dejar lo que estás haciendo y dejas esta nota para volver en un futuro. Además al estar estandarizados los IDEs potentes en la actualidad son capaces de encontrarlos por nuestro proyecto y mostrarnos una lista con todos ellos. Libro original

Funciones

Funciones Como ya vimos en el capítulo anterior nombrar coherentemente es importante, pero no es lo único que tenemos que hacer. Las funciones si están bien nombradas pero ocupan 3.000 líneas no son precisamente algo manejable, y buscar donde se produce un error en ellas será un dolor de cabeza. El libro recomienda que cada función ocupe tanto como abarque tu pantalla, siempre y cuando esta no sea extremadamente grande, unas 20 (llegando al límite, pero con la mitad sobra para poder cumplir con su objetivo la función) Haz solo una cosa! Por ello mantener funciones que sean pequeñas en cuanto a líneas de código y funcionalidad es importante. No debes de liarte y hacer en un mismo bloque 100 cosas distintas, haz una sola cosa por cada función, dale un buen nombre y así sarbás a donde acudir cuando falle. Identación Otro punto importante es la identación es algo que si sigues el consejo anterior se soluciona un poco. La cuestión de este punto es que no debes comenzar a encadenar condiciones (por ejemplo, if {} else), aumentándo la identación del código con cada una de ellas, hasta llegar a salir de la pantalla. Esto hace que no sea legible de manera rápida y cómoda y más fácil de liarte a la hora de revisar el trabajo ya hecho. Switch Esta sentencia por como está diseñada es difícil que ocupe poco, ya que con tres opciones solamente se extiende 12 líneas. Además si queremos modificar este porque ha cambiado los requisitos de nuestra aplicación un switch nos dará problemas, no siendo la mejor opción. Para evitar que esto ocurra nos recomienda hacer el uso de la abstracción. Argumentos Cuando declaramos una función a veces nos olvidamos de que los argumentos luego tendremos que completarlos al hacer uso de esa y comenzamos a solicitar una gran cantidad de ellos. Esto hace que luego cuando la llamemos quede un churro en medio de nuestro código con muchos parámetros que nos chocará cuando estemos leyendola. Además de que siempre será más complicado de modificar en un futuro. En el libro nos recomiendan, que cada función como máximo deba tener 3 parámetros. Si hace uso de más de estos la mayoría de veces significa que lo que necesitas no son los parámetros como tal, si no un objeto con todos estos atributos. Por ejemplo si queremos pintar un punto en pantalla, podremos pedir como parámetros: coordenada X, coordenada Y, radio. Pero si nos fijamos realmente las dos primeras pertenecen a lo mismo, un punto, si en lugar de esto simplemente solicitamos punto y radio queda todo más claro. Nombrar correctamente Las funciones deben de ser nombradas como verbos (acciones) de manera que sean ejemplificativas de que están haciendo en su interior sin tener que investigarla. Por esta misma razón es importante que no hagamos dentro de una función más de lo que decimos hacer, si tenemos una función comprobarConección no debemos hacer más que la comprobación, si se nos ocurriera que, una vez comprobado su correcto estado la inicializamos, tendríamos que llamar de mejor manera a esta algo como: comprobarConecciónEIniciar Argumentos de salida Estos argumentos existen por razones historicas, desde la llegada de la Orientación a Objetos (OO) carecen de sentido, es más hacen que las funcuiones no sean tan claras como deberían. Si una función tiene que devolver algo, esto lo hará por su parámetro de salida (su return) no por un argumento pasado que es un objeto que modificamos. Si tenemos que modificar un objeto lo haremos de la siguiente forma: objeto.actualizarParámetro(); Códigos de error De igual forma los códigos de error no son nada aconsejable, si los usamos tendremos que comprobar si el valor entra dentro de uno de los códigos de error que existen para esa función y luego actuar en consecuencia. Esto hace que el código se haga más complejo añadiendo comprobaciones innecesarias que con excepciones sería más fácil dentro de un bloque try {} catch Libro original

Nombres significativos

Nombres significativos En este capítulo se trata un tema el cual me importa especialmente, nombrar variables, métodos, clases o cualquier cosa que requiera ser nombrada. Es algo que en los inicios de mi aprendizaje con la programación nadie me dijo y después de dos años me di cuenta y he ido corrigiendo poco a poco. Evita la desinformación & Usa nombres que revelen infromación Dar un buen nombre puede llevar tiempo, pero ayuda a ahorrar más en el futuro. Supongamos tenemos lo siguiente private void calcula(int numero){ // haz algo largo y lioso ... } Cuando nos encontremos en nuestro programa esto tendremos que mirar primero si hay algún buen comentario que nos diga que hace, con suerte, o pasar una divertida tarde descifrando que es lo que obtenemos de todo esto y si realmente es lo que queremos porque “calcula” pero que es lo que calcula. Esto es un ejemplo extremista pero queda más claro de esta forma. Si en lugar de esto tuviésemos esto otro sería mucho más fácil private void calculaPresiónDelAgua(int metrosCubicos){ // haz algo largo y lioso ... } Nombres pronunciable De igual manera los nombres tienen que ser pronunciables no le demos nombres cortos con siglas que hace que a la hora de nombrarlo sea imposible. Imagina tienes un campo que guarda la fecha con el formato año-mes-dia-hora-minuto-segundo y decides llamar a este private date genamdhms; cuando trates de preguntar a otra persona del equipo por este campo ¿como lo nombrarás? y claro, suerte para que tus compañeros le den el mismo nombre y sean capaces de ponerse de acuerdo. Mejor si lo llamas de la forma private date generateTimestamp Nombres buscables Es bastante normal ver trozos de código como este for (int j=0; j<34; j++){ s += (t[j]*4/5); } Que no está mal cumple su función (cualquiera que sea, supongo) pero si queremos corregir, por ejemplo ese “34” en algún momento prque ha cambiado el límite, para empezar no sabemos que es lo que indica y segundo ¿como lo piensas buscar entre todas las líneas de código? sería mejor si hicieramos esto en su lugar. int realDaysPerIdealDay = 4; const int WORK_DAYS_PER_WEEK = 5; int sum = 0; for (int j=0; j < NUMBER_OF_TASKS; j++) { int realTaskDays = taskEstimate[j] * realDaysPerIdealDay; int realTaskWeeks = (realdays / WORK_DAYS_PER_WEEK); sum += realTaskWeeks; } De esta forma en un futuro si queremos cambiar el número de tareas o como se calculan estas por día, solo tendremos que usar el buscador y cambiarlo donde esté la constante. Notación húngara Por bagajes culturales de los primeros lenguajes de programación donde indicaban en el nombre de la propia variable el tipo de esta, entiendo que porque era más cómodo al no tener los lenguajes actuales de tipado fuerte y los potentes IDE que tenemos en la actualidad. Pero a día de hoy estoy no es necesario el propio compilador te avisa si no es compatible la variable (en caso de Java, por ejemplo). No hagas String telefonoString Nombres de clase Estos deben de ser nombres no verbos usar Customer, Wikipage, Account en lugar de Manager, Processor, Data Nombres de métodos De forma contraria los métodos deben de ser nombrados como verbos, identificando una acción postPayment, deletePage, save No seas lindo Nombrar tratando de ser gracioso por alguna broma que tienes con cierto compañero, o porque está relacionado con una serie de televisión famosa que “todo el mundo conoce” o “está claro lo que significa” no es una buena idea, por mucho que te vayas a reir cuando lo leas. Recuerda no todas las personas tienen el mismo nivel de cultura en los mismos temas que tú y no tienen porque saber que significan esas siglas. No añadas contexto gratuitamente Si estás desarrollando una aplicación que se llama “Gas Station Deluxe” es mala idea nombrar todas las clases con el prefijo “GSD”. Te estás añadiendo ruido cada vez que pulses “G” para usar algún método, variable, etc que realmente si empieza por esta letra el IDE te hará sugerencias de todo lo que no necesitas. A parte de estos puntos que he resumido de forma muy simple, hay otros puntos que se tratan en el libro que he decidido no añadir. Puntos no descritos Make Meaningful Distinctions Avoid Encodings Member Prefixes Interfaces and Implementation Avoid Mental Mapping Pick One Word per Concept Don’t Pun Use Solution Domain Names Use Problem Domain Names Add Meaningful Context Libro original

Código limpio

Código limpio Todo este capítulo se dedica a hacernos ver la importancia que tiene el código, que este sea lo más limpio posible y, los diferentes puntos de vista sobre que es código limpio. Además muestra como afecta en gran medida en los proyectos actuales y a los equipos que lo desarrollan. ¿Que es el código limpio? Para algunos de los autores que nombra, el código limpio es un código el cual es placentero de leer, otros nombran que tiene que ser enfocado, sin rodeos, elegante entre otros calificativos con los que estoy bastante de acuerdo. Y si es tan bueno, ¿porque todos no lo hacen de esta forma?. El libro lo deja bastante claro con un símil entre el código y el arte. Una persona es capaz de diferenciar un buen cuadro en el que el artista ha representado bien un objeto (por ejemplo) pero por mucho que esa persona vea cuadros o lea sobre ellos no va a saber pintar uno. Con el código limpio ocurre de igual forma, un programador al verlo lo reconoce pero por mucho que vea y lea sobre patrones y técnicas, sin las horas suficientes de práctica no logrará hacerlo. Y para muchos que ya se encuentran en el sector trabajando reaccionan: “Para que voy a aprender chino, si ya funciona como estoy” y no se molestan en aprender y practicar las nuevas técnicas. Equipos sufren problemas por código lioso/sucio Muestra como ha visto mermar la productividad de equipos profesionales de desarrollo porque empiezan a implementar código lioso excusándose en: “Si no, no llegaremos al deadline. Después lo arreglo” y este “después” es nunca y termina por ser un software lioso y desastroso que ha llegado a tal punto de descontrol que ni los mismos creadores son capaces de manejar. Y cuando el inversor ve lo que está pasando solicita que rescriban el código completo, contratando a un nuevo equipo que se encargará de ello mientras los otros continuan desarrollando paralelamente. Esta situación puede alargarse durante mucho tiempo, ha llegado a ver casos en los que tardan hasta 10 años, con los costes que esto conlleva. ¿Para quien escribimos el código? Un detalle a tener en cuenta cuando escribimos código es saber para quien escribimos este, algunas personas piensan que el código que escriben es para los usuarios finales de la aplicación ¿eres uno de ellos? para unos usuarios finales a los que se le da una aplicación empaquetada, compilada, ofuscada en algunos casos, que solo le importa si le soluciona su problema y en un tiempo comprensible, ¿para ellos? Escribimos código para otros programadores, otros que usaran nuestras librerías, otros que se incorporarán al equipo a mitad, otros que tratarán de ayudarnos a solucionar problemas del que no vemos salida, incluso para nosotros mismos en el futuro. Pasamos más tiempo leyendo código que escribiendo, mejor si lo que escribimos es claro y no requiere de grandes esfuerzos para comprenderlo. Libro original

Prefacio

Prefacio Se resume en una frase: “Las pequeñas cosas si importan” La filosofía de las 5 S: Sort, ordenar, saber dónde están las cosas. Darles nombres significativos para que se más fácil. Systematize, sistematizar. Como dice el dicho: Un lugar para cada cosa y cada cosa en su lugar. Cada trozo de código debe estar donde se espera que esté y, si no lo está, refactor ya!! Shine, limpieza. Mantener el espacio de trabajo limpio no dejes trozos de código comentados porque “Me harán falta en el futuro” eso no ocurre. Standarization, estandarización. El grupo de trabajo tiene que estar de acuerdo sobre como dejar el espacio de trabajo limpio y donde va cada cosa, así todos lo harán de la misma forma. Self-discipline, auto-disciplina. Para mí la más importante, tienes que tener la capacidad de seguir las practicas y ser capaz de ver su trabajo sin creer que es la mejor creación del universo, reflexionar y estar dispuesto a cambiar. Introdución Para lograr escribir código limpio no basta con leer sobre los principios y patrones. Aprender es más que conocer el conocimiento requiere conocerlo y aplicarlo, trabajar con ello, practicar y aprender aún más. Este es el objetivo del libro hacerte trabajar y ¡trabajar duro! Este libro se ha dividido en tres partes fundamentales, la primera más teórica, preparatoria para los dos siguientes donde introducir los principios y patrones que se usarán en los dos siguientes. Por ello tiene menos partes de código ejemplificativas. La segunda parte consta de ejercicios que van evolucionando en cuanto a dificultad. Ejercicios han de tomarse con calma y comprender. El tercero y último es la recompensa, una lista resumiendo lo que hemos aprendido en los ejemplos (ejercicios) anteriores. AVISO: Si lees solamente el primer y tercer capítulo de este libro añadirás uno más a la lista de “sentirse bien” pero si decides detenerte debidamente en el segundo asentarás estos conocimientos mucho mejor.