Showing posts with label clean code. Show all posts
Showing posts with label clean code. Show all posts

Thursday, April 20, 2017

Remove the excuses for not being a professional



Do you want to remove the excuses for not being a professional software developer?

  1. Release as frequently as possible, it will give you tons of feedback about the product, the design, the code, the architecture and so on... And at the same time, it forces you to have confidence in the code, automatic testing, automatic deployment, good tooling and infrastructure and learn one of the most difficult but useful skills for a developer... the skill of making large changes in small chunks  (parallel changes, dark releases, refactoring (code and data), etc...)
  2. Use TDD to put pressure on the design and force you to think about it and decouple from infrastructure.
  3. Pair as much as possible to be forced to have focus, understand other developers, think as hard as possible in the problem at hand. Or mob programming as an alternative. No twitter, no Facebook, no notifications... only respect and hard work. Professionalism :) 
  4. Be a whole team for the product, including of course the customer, business, and so on... Learn about the problem to solve, the business language, propose new features and experiments, find alternative solutions, even find better problems... Be part of the business and the product.

So when some people said that agile is a excuse to avoid being professional, I don't longer know whether to laugh or cry. If I want to be unprofessional, I prefer a classic/waterfall approach, without any delivery in several months :)


Learn about business, learn your craft, be part of a team with a purpose...
Be a professional software developer

And remember: nothings add value, until it helps real customers to make something...

References and related posts:



Monday, October 24, 2016

Global code retreat Madrid 2016/10/22


This Saturday I participated in the Global day of Code Retreat event organized by Madrid Software Craftsmanship community. This was the first time I went to the a Code Retreat and I can say I like a lot very much the format.



During all the day, we was resolving the game of life, in pairs, with different restrictions and deleting all the code in each iteration... It is a very interesting deliberate practice to improve our skills, and using the same problem all the time allow us to approach using different techniques.

The best part is that in each iteration we change pairs so during the day you have the opportunity to discuss and solve the same problem with different people using very different point of view.
I think that this promiscuous pairing is the most effective way for trying new techniques and learn new insights.

Lot of thanks, the facilitator Juan D Vega, Luis Rovirosa and all the rest of the organizers from Idealista



Thanks a lot to all of my pairs: Alvaro Fidalgo, Ruben Chavarria, Oscar Pernas, Javier del Saz, Guillermo Domingez, Angel Sanz... Sorry but I don't remember the name of another person that work with Angel Sanz and me in the last iteration.

The constrains that  Juan D Vega introduced were:

  1. Iteration. Ping-Pong pairing
  2. Iteration. No naked primitives
  3. Iteration. No Mouse + 3 minutes limit discussion
  4. Iteration. No conditional statements
  5. Iteration. Mute Session (impossible for me :-) )
  6. Iteration. Code swap (with another pair) in the middle of the iteration. Very funny and interesting.

The most difficult one for me was the 5 iteration, because I worked with Java (and I have no idea) and not talking is very, very difficult.
The most funny and interesting iteration for me was the code swap.

For sure the next year I will repeat :)

P.D. I am happy with the code retreat, but I am very happy that two colleagues from TheMotion join me at the event (Cesar Ortiz, Ludo), and even more happy with the post-coderetreat conversations, learning, insights, etc.

References:



Sunday, August 21, 2016

Agile is not a recipe for success...

Post previously published in Spanish agilidad no es una receta para el exito


Agile is not a recipe for success, is a recipe for failure...
Fail fast, cheap and learning during the process... Agile will not avoid the failure, but it will help to avoid failing in the same way, at the same problem or using a ton of resources.

Agile assume the following:
  • We will fail to estimate.
  • We will fail to understand the customer's requests.
  • We will fail to select technologies.
  • The requirements will change (always).
So agile proposed:
  • Estimate very small chunks (or no estimate at all).
  • Deliver running systems to obtain feedback and adapt the system to the real need of the customer.
  • Use agile practices to have under control the technical debt and to allow maintenance/evolution of the system with a reasonable cost.
  • Maximize the amount of work not done.
  • Create code with good quality to make very easy to adapt it to future changes.
And all of this using very fast/small cycles (timeboxing, iterations, continuous delivery), so even if we fail is very difficult that this failure generates a great problem.

And all this process reinforced with a continuous improvement process (with retrospectives and team improvements).

Embrace Failure
Embrace Change
Embrace Chaos

Sunday, August 14, 2016

Why I use the term "software craftsman"

I like to think that I can consider myself a professional software developer after 20 years or working on it. Since some years ago I feel very aligned with agile software development movement and lately with the software craftmanship movement. I started to be interested in agile in 2002-2003 and in the software craftsmanship in 2012.
Currently when I try to describe myself I use the words “software craftsman” as an equivalent to “software developer, continuously trying to improve his skills and craft”.



Let me explain what I mean by “software craftsman”:
  • I mean being professional as software developer
    • Trying not only to create working code, trying to create simple, easy to maintain code.
    • Trying not only to create the code that the business required, also trying to help the business to growth (with different solutions, even without using code). Adding steadily value to the business.
  • In order to be a good professional there is a strong need to learn and improve our skills, tools and practices. Or even look for new ones.
  • IMHO a good process for learning or improving ours skills is participating in the community of professional software developers. In this process the mentor / apprentice format works very well to improve our skills.
Why not using the “agile software developer” denomination?
In fact, for my, this definition can be a good option, but currently, the term agile is even more confuse that craftsmanship.

For me, at least in my experience, the development of applications and systems has more in common with a craft than with an engineering. Engineering is the application of mathematics, empirical evidence and scientific knowledge, so it is possible to plan, predict and control. IMHO software development for non trivial systems requires sense and respond and other approaches can derive in a false sense of control.

Some kind of software efforts are more adapted to a engineering approach (algorithms, compilers, software for science), but in my case, this is the exception, not the norm.

So, currently in my linkedin profile I indicate that I work as Software Craftsman… I also indicate that I work as a Shaman, but this is different history :-)

References:

Tuesday, July 05, 2016

Pamplona Software Craftmanship 2016

17, 18th June
Official site: http://pamplonaswcraft.com/
Twitter: https://twitter.com/pamplonaswcraft
Twitter official hastag: https://twitter.com/hashtag/scpna?src=hash



The event was organized basically by three guys (#amazing) from https://twitter.com/540info http://540deg.com/.
It was a mix of Open Space and Talks.

Sessions

What a mess! Alfredo Casado

Examples about rewrites of systems that as usually gone bad… is very strange that this kind of things are good idea…
The most important thing is to help the team to evolve, the evolution of the code is a consequence.
There is a paper from Eric Evans (DDD) about how to refactor the system when the evil is still under control. He explain some interesting patterns from this paper. DDD Bubble context and DDD Autonomous Bubble. With some details this patterns are strategies to make a “parallel change” but at the systems level.
Another possibility to make evolutionary architectures are systems optimized for deleting the code (as expressed by Greg Young at The art of destroying software (great talk by the way)).
Ricardo Borillo talk about the use of scientist at flywire http://engineering.flywire.com/blog/how-we-use-scientist to make parallel changes for algorithms.

Leaving the monolith, Event Sourcing powered Javier Ferrer

He described how they develop a new version for Lets Go chat as a parallel change using Akka and event sourcing in a AWS infrastructure (using SQS and SNS for messaging).
He gave us some references for event sourcing:
The implementation is a good example of SNS+SQS tipical use… We were talking about the events persistence. They are only storing the messages in S3 but they only use this messages for recovery.

DDD Carlos Buenos Vinos

This was a very introductory talk, so I used my two feets :)
Some of his talks can be viewed at his youtube channel https://www.youtube.com/channel/UCPOAykv_UgFa79_mub4Orbw

Cómo inyectar pasión en un equipo

This was a open discussion about the subject.
Some interesting ideas:
  • Book club 
  • Code review using Mob programming format 

Software Economics Carlos Buenos Vinos

This session collapse in a discussion about how to measure economic impact of some of the classical XP practices.
He recommend Martin Fowler @ OOP2014 "Workflows of Refactoring" (of course this is a great talk)
You can see the complete version of this talk at https://www.youtube.com/watch?v=31QIVxcTOvg

Errores que he cometido. Carlos Ble

As usually, Carlos is a inspiring person who talk with humility and very transparent. The talk was very inspiring.
Lately the effort to be better professional is leading himself to be better person (can you be a good professional without being a good person?)
A workplace is a good place to be better person, we should try to align ourselves as person and as a professional and detect any kind of conflict between this two facets.
One of the most important softskill to develop is empathy.
Is very important the Non Violent Communication (by default we are judging other people all the time, even unconsciously. We should learn how to empathize with other people and always use a Non Violent Communication (no judgement, only facts, not aggressive behaviors).
When you should interact or express your ideas not in your mother language, you can prepare notes or even read part of the ideas…
The best thing to change anything in other people is to change it in ourselves. Be the change that you wish to see in the world.
Is not a good idea to “carry” the responsibility of all the things when this is a shared task, we should share the responsibility and look the problem from lot of points of view.
Is very important the focus/attention on the details. For example in development, there are some small details that change completely the productivity (IDE shortcuts, tools, pomodoros, naming…).
As a result I will give another opportunity to PyCharm and the refactor tool that provides ;)

Interesting references:

Task based UI / Event Sourcing Ricardo Borillo

Ricardo explained the architecture that they are using in the fronted and all the frameworks and libraries that inspire this solution. The objective is to create a "task based" UI with an unidirectional flow of the information. They use libraries instead of frameworks, because They don't want to be hijacked by the frameworks (as they prefer to use agile practices and follow YAGNI, SIMPLE design…)

He explained how work react and flux and some other “hipster” frontend stuff like elm, om, etc…

It was interesting that they only have one backend endpoint (using http or even websocket) for process all the commands send by the frontend. These commands can be write commands (as in CQRS) or read commands to query some information. This allow them to implement each command very independent and easy to test and avoid all the overhead related to expose all the entities as rest endpoint (as if all the planet was a CRUD system :) )

The classical rest approach force the client to make tons of requests and to include lot of logic to aggregate/relate and navigation. In my opinion all this rest approach is a bad decision, because any interesting system never is a simple CRUD.




They made this interesting practices:
  • They include the commands and functionality of the command as DoD of the their user stories 
  • They create acceptance tests for each command 

How to improve pairing rubocoptero batu

The outcome of this session is this interesting document that they and other community members are still improving
Pairing Guidelines

Community of Needs vs Community of solutions. Antonio de la Torre

Very interesting talk/discussion about two different kind of person and community and how they map in the Cynefin Framework
For me this was one of the most interesting/inspiring talk of the event. The problem is that it is only the initial point for further investigation and learning (and very difficult to transmit without the conversation).
Madriagil 2016 06 13 Presentación Talk Needs vs Solutions


References:

Show me the code Modesto San Juan

Interesting discussion about the code for the RPG Kata generated in a previous session. Cesar showed us his tests and the code to obtain feedback (BTW very clean tests).
The discussion derives towards Properties based testing. In this case this approach for the testing improve the readability of the tests or even the design.
Another interesting example was Modesto explaining how in this case a Reactive Approach allow a better evolution of the design.
You can test from the event consuming entry point and maintain lot of the tests even if the game rules change.
For this reactive stuff you can use specific libraries or simple design as objects that consume event in one thread from a queue (is familiar, isn't it?).

References (adapted for python):
scpna3.jpg


Final notes and other references or interesting stuff

As usual in this kind of events the best things are:
  • The networking. All the conference is design for generating a good networking environment 
  • There were lot of great conversations and corridor discussions.
  • The format is great and explain/practice how a Complex system can be perfectly managed using few small rules and tons of collaboration. (Is real agility in practice). 
  • We made a retrospective each day and all the decision/improvement identified in this retrospective were fixed for the next day. 

Other random links that can be interesting:

Updated

Manuel Rivero pointed me that property based testing and mutation testing are two completely different beasts... so I remove the references to mutation testing from the Show me the code session notes, because in fact all the conversation was about property based testing. Thank you Manu.
More references:


Ruben Egiluz send me lot of typos and improvements for my English :-)   Thanks a lot Ruben.


Sunday, June 26, 2016

Simplicity is the Key

Understanding the Four Rules of Simple Design
Kent Beck. Foreword
What I notice in practice was that the more change I anticipated, the harder it got to make changes. My incorrect speculations interfered with the changes I actually ended up making.
....
I first experimented by ignoring any changes that seemed like they would happen longer than six month in the future. My designs were simpler, I started making progress sooner, and I stressed less about the unknowable future. I shortened the time horizon to three month. More better. One month. More. A week. A day. Oh hell, what happens if I don't add any design elements not demanded by the current code and tests? Still more better.

Sunday, June 28, 2015

Un generador de deuda técnica o el mito del x10

Por todos lados dicen que un programador muy bueno puede ser hasta 10 veces más productivo que uno malo...

Yo creo que la relación no es exactamente así sino que uno bueno puede ser dos o tres veces más productivo que uno normal y uno malo, en realidad no es que tenga una productividad muy baja o nula, sino que genera más deuda técnica y problemas del valor que aporta (código de muy mala calidad, muchos bugs, diseños malos y no entendibles).

Normalmente no nos atrevemos a decirlo, pero hay gente que no la quieres en tu equipo ni aunque vengan con un supuesto "coste cero". En estos casos, realmente prefieres que esté parado y sin tocar un teclado. Por lo menos que no haga el mal.

Es un generador de deuda técnica...


Por eso es tan importante conseguir crear un buen equipo que trabaje coordinado y con una visión común. En estos casos cualquier problema de generación sistemática de deuda técnica se detectaría de inmediato y se podría solventar.

Por cierto que los humanos solemos ser muy malos evaluandonos a nosotros mismos (ya sabes, aquello de que el 90% piensa que conduce mejor que la media)... :-)

Saturday, October 25, 2014

TDD/BDD práctico para aplicaciones con dominio rico / scbcn14



Este domingo en la Barcelona Software Craftmanship 2014, Nestor y yo (@eferro) llevamos una sesión en la que queriamos obtener feedback sobre el flujo de trabajo con TDD que estamos haciendo en Alea Soluciones.
La sesión es una evolución de la que presentamos en la AOS de Valladolid (de tests unitarios de clases a tests untarios de funcionalidad) y las slides de la presentación que usamos están en:
Por supuesto las slides sin contexto son un poco densas y no aportan mucho, pero se grabo la sesión por lo que en cuanto tenga el enlace actualizaré el post.

Creo que a la gente les aporto algunas cosillas y lo mejor fue que obtuvimos un feedback muy bueno y se genero un debate que nos ha enriquecido muchísimo...

Muchas gracias a todos los que participasteis, ni os imagináis lo valioso que es el feedback Gracias.

Referencias:

Wednesday, October 08, 2014

Taller y charlas seleccionadas para la PyConES 2014 Zaragoza



Ya se han seleccionado las charlas para la PyConES 2014 (Zaragoza). De las que habíamos presentado, finalmente han seleccionado las siguientes:


Podéis ver la descripción de todas las charlas en http://2014.es.pycon.org/talks

Para el caso del taller, el objetivo es poder crear una aplicación en la que el negocio sea el centro y que la arquitectura emerja del propio proceso de creación. Se trabajara en parejas y usaremos TDD para la creación. Por supuesto se requiere que los asistentes se lleven un portátil con un python + virtualenv instalado.


Nos vemos en Zaragoza !!!!



Wednesday, September 17, 2014

Votación Talleres / Charlas para la PyConEs 2014

Después de éxito de las charlas de la PyConES 2013, este año, para la PyConES 2014 (Zaragoza), el equipo de Alea Soluciones hemos echado la casa por la ventana y presentado gran cantidad de talleres/charlas.

Os pongo por aquí las propuestas por si queréis votarlas para que las acepten o por si queréis dar feedback sobre las mismas.

Muchas Gracias por vuestros votos !!!

En el panel de la pycon tenéis todas las charlas y talleres que se han presentado y que tienen pintaza :-)

Es posible que algunas de ellas, de forma directa o con modificaciones se presenten para la CAS 2014 (Barcelona) así que cualquier comentario, propuesta o mejora será muy bienvenida.


Thursday, June 05, 2014

De Test Unitarios de clases a Tests Unitarios de funcionalidad, un gran paso

Actualización:
He usado este post como base para una sesión en el AOS2014 y he actualizado el post para tener en cuenta alguno de los comentarios recibidos.

La aplicación se desarrolla usando TDD excepto en ciertas partes que tenemos identificadas y que cubrimos de otra forma. Durante este proceso hemos ido evolucionando en la forma de hacer TDD.

Antes tests unitarios considerando aislamiento por clases y a veces incluso testeando por métodos de esas clases... Mucho mock. Requiere tener algo claro el diseño, pero requiere poco "poder" cerebral :-)

Ejemplos:
test_detect_bridge_profile
test_detect_catv
test_deprovision_raise_error_when_snmp_exception_was_raised
test_deprovision_service_ports_with_provisioned_ont_from_repository
test_provision_raise_error_when_snmp_exception_was_raised
test_provision_service_ports

A este tipo de tests les llamamos Test Unitarios de clase.

Hemos evolucionado a tests unitarios mas centrados en las funcionalidades de negocio y que pueden usar una o mas clases. Al igual que los Tests Unitarios de clase, estos tests son independientes unos de otros y no tienen ningún tipo de dependencia externa (BD, Red, Eventos, etc).
A este tipo de tests les llamamos Test Unitarios de funcionalidad.

Ejemplos:
CPE status
  CPE Events History
    Acknowledge CPE status events
      ✓ it acknowledges cpe status events
    CPE Events with errors
      when ask for all the cpe status events with error
        ✓ it returns all the events with error
      when ask for the number of events with error of a cpe
        ✓ it returns the number of errors of the cpe
    Remove CPE status event history
      ✓ it removes the status history of a cpe
    history event recieved
      ✓ it registers the event
    when ask for events history returns only event limit
      ✓ it returns events bases to limit option
    when cpe goes offline
      ✓ it creates history events only when cpe status changed
      ✓ it removes cpe status
    when voip changes status
      ✓ it creates history events only when voip status changed
...

A continuación podemos ver un extracto de la implementación de estos tests:

Como se puede ver intentan en todo momento reflejar términos de negocio, en nuestro caso referidos a telecomunicaciones  y al estado de un CPE (Customer-premises equipment)

La entrada de este test es la lógica de negocio (cpe_status_service) que implementa el estado del CPE, para el que hemos usado dobles de pruebas sólo para los ports (Sistema de credenciales SIP (SipCredentials), Repositorios de persistencia (que en este caso están implementados en memoria (InMemoryCPEStatusRepository, InMemoryCPEStatusEventHistoryRepository)), y el reloj del sistema (Clock) que aunque no se suele tener en cuenta es claramente un port del sistema).

Por otro lado, existen otros tests, realizados también con TDD para cubrir implementaciones de los ports identificados (repositorios, SipCredentials, etc).


Actualmente todo el sistema esta cubierto por los siguientes test:
Tests unitarios
- Test Unitarios de clases 672 / 0.9s
- Test Unitarios de funcionalidad 135 / 0.45s

Test integracion:
- Total 166 12.89s
- De contrato 45 10s

Intentamos desarrollar siguiendo este orden
  1. Lógica de negocio
  2. Adaptadores
  3. Deliveries (servicio rest, interface cli, publicación/recepción de eventos y mensajes asíncronos)
Para desarrollar Lógica de negocio
  • Identificamos ports
  • TDD funcionalidades (dobles de pruebas/implementaciones simples para los ports) 
  • TDD sobre adaptadores (implementaciones de esos ports)
  • Test de contrato de librerías / tecnologías  (usados por esos adaptadores)
Evidentemente todo esto puede estar salpicados de spikes cuando queremos probar librerías, hacer bosquejos de adaptadores o cualquier otro tipo de prueba

Ahora mismo los deliveries no los probamos demasiado.

Conclusiones:

Ventajas de los Tests unitarios de funcionalidad con respecto a Test unitarios de clases
  • Nos cuesta mucho menos mantener el código (refactors mucho mejores)
  • Menor tendencia al sobre diseño
  • El código refleja mejor el dominio
  • Tenemos antes una solución completa que vamos refinando paulatinamente
Desventajas
  • Algunas veces cuesta identificar los ports y cuesta un poco empezar una funcionalidad
Para paliar esta desventaja,  algunas veces creamos mocks y tests de menor alcance que solo nos valen para ayudarnos a encajar las piezas (andamiaje) luego los borramos.

Podemos concluir que este cambio ha sido un gran avance para el equipo y ahora siempre que tenemos que añadir funcionalidades en una parte que tiene los tests unitarios por clases, lo primero que nos planteamos es si hacer nuevos tests por funcionalidades. A veces lo hacemos, otra veces no, depende del ROI.

Referencias:


Saturday, June 22, 2013

El arte del patadon pa'lante / Postponer decisiones técnicas

24/6/2013 Actualización de formato y añadidas referencias

Este post contiene la esencia de lo que estamos haciendo en Alea Soluciones para postponer en todo lo posible las decisiones técnicas. Vamos a usar este post como base para compartir nuestras experiencias al respecto en el AOS2013
Comenzamos:

Nuestro contexto

  • Hacemos productos en entorno de telecomunicaciones
  • Equipo Extreme Programming
  • Deploy continuo / Entrega continua

A qué nos referimos

Postponer todas las decisiones técnicas hasta el último momento responsable

Que no postponemos

  • La forma en qué hemos decidido trabajar (de forma ágil, deploy continuo, extreme programming)
  • El lenguaje base de desarrollo  de cada componente... python...
  • Buenas prácticas de OO

Por qué queremos postponer / Beneficios conseguidos

  • Cuanto más tarde tomemos una decisión más conocimiento tendremos del negocio y del entorno técnico
  • Soluciones más simples/sencillas
  • Soluciones más pequeñas
  • Trabajar menos :-)
  • Más probabilidades de no hacer nada que no aporte valor real ahora
  • Más probabilidades de no hacer sobre ingeniería
  • Menos esfuerzo en rehacer trabajo si es necesario
  • Nuestro objetivo es tener mucho juego de cintura... reaccionar bien y rápido a cualquier cosa... y sin echarnos las manos a la cabeza
  • Cuanto más postponemos, menos llenamos la mochila.... es más dificil coger lastre y tendemos a viajar ligeros.... añadimos menos cosas innecesarias.
  • Todos sabemos que una mudanza se hace fácil si tenemos pocas cosas
  • Una buena arquitectura nos permite postergar decisiones importantes, esto no significa que estemos obligados a hacerlo. Sin embargo, al poder postergarlas tenemos muchísima flexibilidad.
Esta forma de actuar está alineada con los principios lean de eliminar el desperdicio y los principios ágiles de post poner hasta el último momento responsable y es una  de las forma de actuar que mas puede ayudar  a la creación de un arquitectura limpia. A su vez una arquitectura limpia hace que sea mas fácil post poner otras decisiones.

Cómo lo hacemos

  • Postergamos las decisiones de forma consciente y meditada
  • Consideramos una decisión como buena cuando:
    • nos compromete lo mínimo posible
    • nos permite postponer otras decisiones
    • Es fácilmente cambiable
    • Ataca un problema actual (no futuro)
    • Suficientemente bueno (sin sobreingenieria, ni nuestra ni de otra gente)
    • Prohibido Megaconstrucciones
  • Reusamos librerías pero no Frameworks (vamos no dejamos que nos usen a nosotros)
  • Consideramos qué todo se puede cambiar (código / diseño / proceso)
  • Cuanto vamos a afrontar un sprint o un grupo de funcionalidades nos centramos en identificar qué tenemos que cambiar en nuestra arquitectura y nuestro entendimiento del dominio / lenguaje ubicuo.
  • y lo que se decidió era lo correcto en ese momento y en ese contexto y si hay que cambiarlo, no pasa nada, manos a la obra...
  • Método Hamburguesa descomposición de PBIs grandes.
  • Clean Code
  • DDD (u otra variante que permita que la arquitectura no se centre en las herramientas BD, GUI, etc)

Qué necesitamos para hacer fácil postponer.

  • seguridad/confidence
  • Feedback temprano
  • TDD
  • Refactor continuo
  • Todo se pueda cambiar
Dividimos cambios medios/grandes en cambios pequeños, incluso duplicando código y duplicando datos... todo con el objetivo de poder postponer decisiones, no impedir deploy y hacer cambios incrementales, pequeños y seguros.

Código no es un snapshot, es algo en movimiento
Siempre puedes iterar... iterar/refactorizar es fácil sin miedo y con red... TDD, BDD...

Problemas/Sensaciones que genera postponer decisiones...

  • Incertidumbre
  • Ansiedad
  • Conflicto (como ingenieros)

Postponer... hasta el infinito y más allá...

Hasta el último momento responsable!!!!


Referencias:

Monday, October 29, 2012

Resumen Clean Coders capitulo 6: TDD Parte 2 (III) Conclusiones



Continuamos con el resumen del Capitulo 6 Parte 2. En este caso finalizamos con las conclusiones.
Si no lo has hecho, puedes leer los anteriores posts sobre el capitulo (parte 1  parte 2).

Conclusiones

  • El código se pudre porque tenemos miedo a cambiarlo
  • Para mantenerlo limpio tenemos que eliminar el miedo a cambiarlo
  • Sólo con una batería de tests en la que confiamos se elimina el miedo a cambiar el código
  • Reglas del TDD
    • No se puede escribir código de producción excepto para pasar un test que está fallando
    • Escribe solo lo suficiente de un test para demostrar el fallo (no compilar es un fallo)
    • Escribe solo lo suficiente del código en producción como para pasar el test fallando
  • Siguiendo estas reglas de TDD se consigue:
    • Menos defectos
    • Tiempos de depuración más bajos
    • Documentación de bajo nivel confiable y detallada
    • Código altamente desacoplado
    • Y una batería de tests en la que puedes confiar
  • TDD te hace ir más rápido
  • Los desarrolladores profesionales debemos esperar que el departamento de QA no encuentre ningún defecto (ese es el objetivo)
Con este post concluimos el resumen de este interesante capitulo de clean coders 

Thursday, October 25, 2012

Resumen Clean Coders capitulo 6: TDD Parte 2 (II)



Continuamos con el resumen del Capitulo 6 Parte 2. Tal y como comentamos el capitulo es muy completo y contiene gran cantidad de información por lo que hemos dividido el resumen en tres posts. Este es el segundo.

Si no lo has leido, puedes comenzar por el anterior post sobre este capitulo.

Para trabajar con código legacy en el que no tenemos tests:

  • Encuentra un modulo pequeño que puedas probarlo sin realizar demasiados cambios
  • Realiza los tests para realizar esos cambios con más seguridad
  • Para funcionalidades nuevas, se hacen pequeños cambios para poderlas testear
  • Si en una modificación, existe la posibilidad de modificar y hacer los tests a posteriori o hacer un nuevo módulo, deberemos hacer un nuevo módulo, usando TDD Siempre que sea código nuevo, se hace con TDD

Como testear GUI/View

  • Para la parte de vista pura, no merece la pena, puesto que es una parte que se presta a muchos cambios (estilo, presentación, …) y que además no tiene un resultado prefijado sino que se suele ajustar continuamente
  • Pero se puede probar todo el código relacionado en las capas anteriores...
  • Es decir podemos probar el contenido de los elementos de pantalla, pero no merece la pena testar cómo están posicionados, qué forma tienen, colores, etc...
  • Para ello se separa el GUI en dos componentes Presenter / View
    • Presenter interroga objetos de negocio y prepara estructuras de datos
    • Las estructuras de datos generadas por el Presenter, son renderizadas por el objeto View
    • Se testea el Presenter
  • Algunos hacen tests para las vistas (a nivel de interface), pero en ese caso lo hacen después de realizar las vistas, con el objetivo de que una vez que han conseguido un resultado, detectar si cambia. El, en general no lo recomienda.

Como testear la BD

  • Se testea que tu esquema y tus consultas funcionan como se supone
  • Necesitas tener la aplicación y la capa de BD separada
  • Esto permite probar la aplicación sin la BD real
  • Luego se puede probar la capa de BD separada. Por ejemplo se puede testear:
    • Se puede testear que se genera el SQL correcto
    • Incluso se puede probar que el SQL se comporta bien cargando una pequeña cantidad de datos

Disciplina y profesionalismo

  • El software es una disciplina que tiene que atender a muchísimos detalles, cualquier pequeño cambio y/o error hace que la aplicación deje de funcionar. Es muy propenso al fallo humano y las consecuencias (a nivel de la aplicación) suelen ser importantes.
  • Esto no pasa en otras disciplinas, y quizás en la que si pasa es en contabilidad y por eso establecieron como “buena práctica” el “sistema de partida doble” (Double-entry bookkeeping system) por el que cada entrada se realiza de dos formas independientes con cálculos independientes de forma que si existe una discrepancia se detectase de forma más o menos inmediata.
  • El TDD sería el equivalente en desarrollo de software a esta buena práctica del “sistema de partida doble” puesto que todo se desarrolla con un doble flujo (el de test y el de producción) que se validan el uno al otro.
  • Como desarrolladores profesionales debemos esperar conseguir que el departamento de QA no encuentre errores en nuestras entregas y en caso de que los encuentre debemos esforzarnos en que no pueda volver a pasar ese tipo de error.
  • Debemos liberar código que sabemos que funciona (lo contrario es irresponsable y no profesional).
  • La mejor forma conocida para asegurarnos de que el código que liberamos funciona es seguir la disciplina del TDD en su creación.
  • Debemos buscar tener una cobertura de código del 100%, ese es el objetivo, aunque puede que en algún caso no sea totalmente posible, pero el 100% debe ser lo que se persiga.

En el próximo post terminaremos con las conclusiones de este capitulo...

Monday, October 22, 2012

Resumen Clean Coders capitulo 6: TDD Parte 2 (I)



Continuamos con las acciones de mejora / compartiendo videos cleancoders. En esta ocasión toca el resumen del Capitulo 6 Parte 2


Este capitulo está lleno de detalles interesantes, por lo que voy a hacer varios posts para resumirlos...
Comencemos....

@unclebob, comienza con una sesión (ligera) de diseño de la solución al problema, el la que:
  • Obtenemos el vocabulario del sistema
  • Identificamos los componentes básicos
En la práctica no se sigue el diseño que hemos hecho, se usa como guía o referencia, pero el diseño final será el que emerja mientras resolvemos el problema usando TDD.

@unclebob Comienza con una estructura de test y un test vacío  de forma que se verifica que todo está en su sitio antes de comenzar la sesión de TDD propiamente dicha.

Al principio, cuando todavía no hemos entrado en el problema, podemos identificar los primeros pasos haciéndonos la siguiente pregunta: ¿Qué test tengo que escribir para forzarme a escribir el código que se que quiero escribir?

Es común escribir un test, simplemente para poder escribir cierto código inicial de producción y que luego, según evoluciona la solución, ya no tenga sentido (o no pruebe nada) y se elimine (canCreateGame, canRoll, …)

Nunca escribimos tests que sabemos que van a pasar.

El código de los tests es tan importante como el de producción y tenemos que tener el mismo cuidado con el. Es decir tiene que ser clean code y se debe refactorizar de forma continua.

En muchas ocasiones, desarrollando con TDD, el resultado no se corresponde con el diseño original. Normalmente es más sencillo, puesto que sólo tiene el código necesario para la funcionalidad actual.

Respuestas a las objeciones típicas a usar TDD:

  • Objeción: Se debe de tardar más con TDD, puesto que se escribe mucho código de test... Se tarda mucho menos, puesto que se avanza más rápido trabajando siempre sobre clean code, además se gasta mucho menos tiempo en depuración. No nos pasamos todo el tiempo peleando con código sucio y dificil de entender.
  • Objeción: Los managers no dejarán practicar TDD a los desarrolladores... Es una práctica interna, que no tiene porqué entrar en discusión con los managers.
  • Objeción: Refactorizar es volver a realizar trabajo, seria mejor hacerlo bien a la primera... Asi es la vida... efectivamente es volver a realizar el trabajo, pero lo normal (y adecuado) para trabajos creativos es hacerlo de forma iterativa con pequeños cambios, puesto que es practicamente imposible hacerlo perfecto a la primera.
  • Objeción: Quién/Qué prueba los test... Con TDD disponemos de dos flujos alternativos para una funcionalidad, los tests y el código de producción, por lo que cada flujo testea el otro, los tests, testean el código de producción y al reves.
  • Objeción: Quizás el mantenimiento de los tests es demasiado caro... No tiene que serlo, puesto que los tests, también deben estar correctamente diseñados y deben de ser clean code, por lo que su coste de mantenimiento debe ser bajo.
  • Objeción: Un test puede probar que un bug ya no se produce, pero no puede probar que no existen bugs. Es decir no puede probar que el software es completamente correcto. El objetivo no es estar 100% sino disponer de una red de seguridad que nos elimine el miedo a cambiar el codigo puesto que tenemos una confianza/certeza sobre que el código funciona correctamente muy alta.
  • Objeción: TDD es un disciplina, seguir reglas en vez de pensar y usar la cabeza... Las disciplinas nos ayudan a no tener que realizar las mismas decisiones una y otra vez... Necesitamos que sea una disciplina para poder ser eficientes (tener mecanizado e interiorizada la práctica) lo que no quita para que de vez en cuando nos planteemos como mejorar la disciplina.
  • Objeción: No importa si se hacen los tests antes o después del código de producción... Si se hacen los tests a posteriori, nos parecerán opcionales y se tenderá a no hacerlos o a que no sean completos, por tanto no confiaríamos en ellos. Además, haciéndolos después perdemos la ventaja de que los tests primero nos obligan a hacer nuestro diseño testable (es decir con bajo acoplamiento).

Seguiremos en el próximo post...

Tuesday, September 04, 2012

Resumen Clean Coders capitulo 6: TDD Parte 1


Continuamos con las acciones de mejora / compartiendo videos cleancoders. En esta ocasión toca el resumen del Capitulo 6 Parte 1

Clean Code, Episode 6 - TDD - Part 1

  • Reglas TDD
    • No escribir código de produccion excepto para hacer pasar un test que esta fallando
    • Escribir solo lo suficiente de un test como para demostrar el fallo
    • Escribir solo lo suficiente del código de produccion como para pasar el test
  • Pasos TDD
    • Red
    • Green
    • Refactor
  • Miedo y Descomposición del código (Code Rot)
    • El código y el diseño de un sistema suele irse deteriorando si no lo limpiamos de forma continua.
    • Esto hace que el sistema sea rigido, fragil y dificil de cambiar y que las estimaciones cada vez sea más imprecisas y dificiles de hacer.
    • No lo limpiamos, pq tenemos miedo (de romperlo)
  • Un esfuerzo de limpieza que no sea constante no tiene sentido (normalmente cuesta mucho más y si no tenemos como validar que todo sigue funcionando, suele terminar en desastre).
  • Eliminando el miedo a cambiar el código
    • Gran cobertura de tests
    • Que se ejecutan en muy poco tiempo
    • Que se ejecutan con solo pulsar un boton o escribir un comando
    • Con una buena cobertura de tests, se puede llegar a un estado en el que no se tiene miedo a que si pasan los tests, simplemente se libera la versión.
    • Ventajas de disponer de una buena cobertura de tests
      • No hay miedo para cambiar el código
      • No hay miedo a limpiar el código
      • No hay miedo a liberar una versión
      • Número de bugs muy bajo
  • Usando TDD en su experiencia
    • El proyecto se desarrolla más rápido
    • Nos ahorran tiempo
    • Se desarrolla con mucha mas fiabilidad
    • Muchos menos errores
    • y se dedica menos tiempo a depurar
    • Y la estrcutura resultante es mejor
  • Las tres reglas del desarrollo TDD
    • Es una disciplina y tiene una serie de reglas
    • Las tres reglas
      • No se puede escribir código de producción excepto para pasar un test que está fallando
      • Escribe solo lo suficiente de un test para demostrar el fallo (no compilar es un fallo)
      • Escribe solo lo suficiente del código en producción como para pasar el test fallando
    • El ciclo debe ser de unos pocos segundos... algo de test, algo de código, algo de test, algo de código, …
  • Con TDD, siguiendo estas reglas se obtiene:
    • Tiempo de depuración reducido por un factor de 10
    • Documentación (actualizada y funcional) con ejemplos
    • El código está mucho más desacoplado dado que tiene que ser testeable, es decir un sistema mucho más flexible
    • No tenemos miedo a cambiar el código
    • No tenemos miedo a limpiar el código
    • Es decir, el TDD, evita que el código se vaya corrompiendo

Monday, August 20, 2012

Resumen Clean Coders capitulo 5: Estructura (Form)


Una vez más, siguiendo con la acciones de mejora / compartiendo videos cleancoders, continuamos con los resumenes de los capítulos de Clean Coders
Hoy toca el Capitulo 5

Cap 5 - Estructura / Form

Este capitulo se centra en todo lo que tiene que ver con la estructuración que realizamos del código de nuestras aplicaciones, comenzando con el formateo del propio código fuente y terminando por algunos consejos sobre cómo definir los límites de los diversos componentes y capas de la aplicación, comenzando de esta forma con algunos temas de arquitectura.

Comentarios en código

  • Se deben tener pocos comentarios en código
  • Cada vez que escribimos un comentario es que hemos fallado en en expresar con nuestro código, luego tenemos que trabajar muy fuerte para que eso sólo sea necesario en raras ocasiones (ejemplo una expresión regular complicada, …)
  • Se deben escribir lo más cerca posible del código al que hacen referencia. 
  • Nunca comentarios superfluos que no añadan nada a lo que ya dice el código. 
  • Los comentarios nunca deben ser obligatorios 
  • Nunca comentarios sin código, ni comentarios tipo banner, ni TODOs, ni FIXMEs (somos profesionales y si no está terminado, seguimos trabajando)
  • El código comentado se elimina (sin mirarlo).
  • Comentarios legales: 
    • Copyright
    • Documentación de API publico (con herramientas automaticas) aunque es preferible los APIs que no requieren ni siquiera esa documentación. 

Formateo de código

  • Guía de estilo: 
    • No existe como documento 
    • Todo equipo tiene una 
    • El código del equipo es el ejemplo de la guia de estilo
    • El equipo debe ser consistente y compartir ese estilo (si usa un IDE, debe compartir la configuración para que el estilo sea coherente). 
  • Importante tener una convención para el uso de lineas de separación, el recomienda una linea para separar cada método, cada grupo de variables, etc. Hay que ser consistentes en su uso. Las lineas en blanco son un elemento más de formateo.
  • Logitud de linea. Nunca scrolls horizontales, entre 40 y 80 caracteres... en algún caso se podría ir a 120 caracteres, pero nunca más. 
  • El tamaño de fichero medio, puede ser por debajo de 100 lineas, y nunca superar a las 500 lineas. 
  • Para formateo de Java el usa/recomienda: 
    • Estilo K&R 
    • Indentación por espacios 2 espacios de indentación 

Clases vs Estructuras de Datos 

Las clases nos protegen de nuevos tipos
Las Estructuras de Datos nos protegen de nuevas funciones

Clases

  • Tell don’t ask (con métodos con alta cohesión con respecto a las variables de la clase)
  • Evitando usar getter y setters, si en algún caso es necesario usar un getter es importante ocultar los datos, dando el interfaz más abstracto posible (getPercentFuelRemaining no getGallonsOfGas...)
  • Protegen de nuevos tipos

Estructuras de Datos

  • Sacos de datos con métodos con baja cohesión
  • No se ponen reglas de negocio en este tipo de estructuras
  • Se pueden manipular con switchs si es necesario
  • Protegen de nuevas funciones, pero no de nuevos tipos

Límites (Boundaries) 

Los limites dentro de la aplicación separan las diversas partes, y siempre tienen las siguientes caracteristicas:

  • Una parte tiene una definición abstracta
  • Otra parte es concreta e implementa la definición abstracta de la otra parte
  • Las dependencias de fuentes van parte concreta ---> parte abstracta
  • No existen dependencias de fuentes en el sentido inverso

Los Objetos de dominio y las tablas de BD no son lo mismo, en realidad, ni están fuertemente relacionadas.
Los Objetos de dominio deben estar separados de las tablas de BD mediante una capa de abstracción que debe depender de las abstraciones de la aplicación (la parte con los objetos de dominio) y de las tablas de BD. Los objetos de dominio (y el resto de la aplicación) nunca deben depender de esta capa (y por supuesto, menos de las tablas que están por debajo).

Monday, July 30, 2012

Resumen Clean Coders capitulo 4: Estructura Funciones (Conclusiones)



Siguiendo con la acciones de mejora / compartiendo videos cleancoders, continuamos con los resumenes de los capítulos de Clean Coders.
En este caso, nos toca el Capitulo 4. Como este capitulo es bastante denso es posible que termine haciendo varios posts relacionados, pero de momento, en este post me voy a centrar en las conclusiones más importantes del capitulo.

Cap 4 - Estructura Funciones (Conclusiones)

  • Los prototipos de funciones deben ser pequeños, pocos argumentos (<=3), no pasar booleans, ni usar argumentos que puedan ser null, no argumentos de salida
  • Las funciones se organizan siguiendo la regla de step down, lo publico primero, lo privado después y siempre intentando que las funciones a las que llama cada función estén debajo de la definición de esta primera función y descendiendo cada vez en abstracción.
  • Switch va en contra del paradigma OO e interfiere en el despliegue independiente de componentes (y por tanto en el desarrollo independiente) .
  • Debemos remplazar los switchs por polimorfismo o por lo menos mover los switchs a sitios donde no generen ese problema de dependencias (por ejemplo a una factoria o al main).
  • El Temporal coupling en muchos casos se puede limitar o eliminar usando el patrón de pasar un bloque.
  • Conviene separar las funciones de query (consulta) de las de comando (modificación) (CQS)
  • Tell don’t not ask
  • No hacer cadenas de queries, evitar que una sola linea tenga gran conocimiento de la estructura de la aplicación o de gran cantidad de objetos. Recordando la Ley de Demeter... No se habla con extraños.
  • Limitar el uso o eliminar de salidas de bucle desde dentro (break). Hacen menos entendible el código.
  • Pensar en el control de errores antes que en el código normal
  • Usar excepciones para el control de errores. (no devolver error codes)
  • Las excepciones deben ser de la clase o modulo que las lanzas
  • No check exceptions.
  • funciones o gestionan errores o hacen cosas, no las dos cosas.

Friday, June 01, 2012

Resumen Clean Coders capitulo 3: Funciones

Siguiendo con la acciones de mejora / compartiendo videos cleancoders, continuamos con los resumenes de los capítulos de Clean Coders.
En este caso, nos toca el Capitulo 3


Funciones

  • Las funciones deben ser muy cortas (hasta 4) y hacer una sola cosa.
  • Separar por agrupaciones de operaciones.
  • Separar cosas de distinto nivel de abstracción.
  • En las funciones largas es dónde se esconden las clases.
  • Una función sólo hace una cosa cuando ya no podemos extrar más funciones ni clases de su implementación.
  • Los bloques dentro de una estructura de control, son una oportunidad para encontrar nuevas funciones.

En este caso, en mi opinión,  sin llegar a ser tan extremista como Uncle Bob en cuanto al número de lineas, el código es más mantenible y legible con funciones cortas (de hasta 10 lineas).

Depende de a lo que estemos acostumbrados, nos puede parecer que el tener un gran número de funciones pequeñas y de clases pequeñas, hace que el código sea menos legible, pero creo que es más una tendencia proveniente de una forma de trabajo y que realmente una vez de que tienes interiorizado el realizar un buen nombrado de las funciones / clases y que organizas correctamente tus estructuras, es mucho más sencillo de mantener, con clases y funciones muy pequeñas y que tengan una única responsabilidad.


El resumen de este episodio ha quedado un poco pequeño puesto que gran parte se centra en ejemplos básicos y refactorizaciones... Por otro lado, me parece tan evidente lo que comenta, que poco puede aportar el resumen que yo haga....

Continuamos en el siguiente capitulo.

Tuesday, May 29, 2012

Resumen Clean Coders capitulo 2: Nombrado

Tal y como comente en el acciones de mejora / compartiendo videos cleancoders continuamos con los resumenes de capitulos del Clean Coders.
Esta vez nos toca el Capitulo 2


Capitulo 2 Nombrado

En este capitulo, uncle Bob se centra en enseñarnos cómo debemos usar los nombres (clases, métodos, variables, etc...) que seleccionamos al desarrollar, como una herramienta de comunicación...
  1. Los Nombres son una herramienta poderosa de comunicación... Hay que elegirlos y tratarlos con cuidado
  2. Elige nombres para comunicar tus intenciones. Si tienes que poner un comentario para explicar el nombre, es que no está bien elegido. Si tienes que leer el código para entenderlo, también está mal escogido.
  3. Siempre evitar la desinformación (generada por mal naming o por cambios que hacen que se queden los nombres obsoletos). (Said what it means, means what it says)
  4. Los Nombres deben ser pronunciables.
  5. No usar encoding (no notaciones hungaras, no I para interfaces, …)
  6. Clean Code como prosa. Para Clases nombres, Para Variables nombres, Boolean predicados, métodos verbos, si devuelven boolean predicados.
  7. Scope rules...
    1. Variables con nombres cortos o incluso muy cortos si tienen scope pequeño.
    2. Variables con nombres más largos si tienen scope más largos.
    3. Funciones, métodos, clases
      1. Nombres cortos y convenientes si el scope es grande y su uso muy común.
      2. Nombres más largos y descriptivos si el scope es más corto (métodos y clases privadas, por ejemplo).

Lo más importante:
Any fool can write code that a computer can understand.  Good programmers write code that humans can understand. Martin Fowler

--
Actualización:
31/5/2012 Resueltos algunos problemas de formateo...