Archive for the ‘Agile’ Category

Te ayudo a presentar

Vienes al AOS2016? Vamos a coincidir quizás en otro open space? Si nunca has presentado una sesión pero tienes algo que te gustaría compartir con la comunidad y te cuesta un poco arrancar y dar el paso, yo me ofrezco a echarte una mano. Te puedo ayudar a preparar el discursito de presentación de la sesión para que la gente entienda bien la temática y el formato y obtenga votos. Podemos salir juntos a contar la idea. Luego tambien podemos facilitar la sesión juntos (siempre y cuando salga votada), pero necesitaríamos prepararla un poquito antes del evento sobre todo si es un tema que yo desconozco. Sería una especie de "coaching" para facilitar o ser ponente en una sesión. Lo que haría es darte feedback sobre el material y el enfoque, en base a mi experiencia.
He dado muchas charlas y facilitado bastantes sesiones ya en open spaces y en otros formatos de evento. Mi experiencia puede ayudarte a ganar confianza y sentir que no estas sola, o solo. No hay ningún peligro, es un entorno controlado.

Esta idea la he copiado de Lisa Crispin que en su iniciativa de fomentar que haya más mujeres en el sector TIC, invita a ponentes femeninas que nunca han presentado en una conferencia, a presentar con ella.

Simplemente mándame un email, un tweet o un DM y buscamos la forma de preparar de la sesión.

Nos vemos en Santiago!

In my experience a code review must have a goal. Some common goals are:

  • Telling others how you solved a common problem.
  • Warning others about certain perils (i.e race conditions, coupling...)
  • Asking concrete questions. Implementation or design questions.

When you expose some code to your colleagues in a meeting room, you should know exactly what you want to get from that activity. You want to learn, to tech or to warn others basically. Otherwise, if you just open up some code and ask your colleagues what's their opinion about the code, then everyone will say something. Exactly like watching a football match with friends, everyone has his/her opinion on how the coach should manage the team, how players should play... no matter how good the team play, there will be always someone opinionated bullshit. The code review will be frustrating and not very productive.

Remember to prepare a list of questions or tips to tell others, together with the code you want to share, before going to the code review.

So your pair is proposing a route or plan that you don't agree on. Am talking about a refactoring, a redesign or just the way to test drive the next feature. You have told him your reasons no to agree with him and there is no way to get to an agreement. It's perhaps frustrating because you believe his strategy will fail but he definitely wants to proceed that way. What do you do? Argue forever?

I don't think you have to always agree on the path you are going to walk. The important thing is that both understand the plan so that driver and navigator can help each other get there. In those situations I end up saying... I believe this approach is not the best and I would try out something else - something I explained already... but anyway, I'll help you with your idea, let's do it.

Several times my pairs have proven that they were right and the plan was effective. Some other times it wasn't a good idea, but we built a trustworthy relationship, a supportive one.

Learning with Peter

Last week I was lucky to host my good friend Peter Kofler in his visit to Gran Canaria, where he came to facilitate the Glodal Day of Code Retreat and also to work together a couple of days in our biggest project at the moment.

We've been working in the same project for a year now, our team joined the client's team to play several roles, from mentoring to developing features ourselves. Peter's visit was a fantastic learning experience and also a way to bring back principles that wear out as we face recurring issues over time. Even though we started as external consultants, the fact that we've been a year immerse in the project sometimes leading the development ourselves, changes our vision and focus. Peter's fresh vision reminded me of myself a year ago, when the gig started and reinforced my willingness to stick with my principles. Thank you Peter!

Notes that I wrote down during working sessions:

  • Code metrics is exactly what we need now to show everyone the health of the code base. We have enough code already and we must improve the readability of some tests, reorganise dependencies, clean up namespaces and some other things we know are important. A tool like Sonar of something like that will provide us with metrics to measure the improvements over time. It's definitely the time to visualize code metrics
  • Dependencies diagrams are another type of metric that we should use now that. A quick overview of how the various namespaces are related to each other.
  • There are certain areas of the hexagon suffering from "primitive obsession" code smell. We want more objects within our business domain, and less primitives.
  • More information in commit's comments. Apart from the refactoring we apply or the name of the tests turning green or red, I'll try to explain shortly what is the benefit of every single commit. The reason to change the code. I've found myself searching for particular design decisions in the commits' history and realized that the information in the comments was not enough to find out what I wanted. Example: why I moved a method to a class, extracted a class... the "why" is not in the code so it's a good idea to add it in the form of comments in the version control system.
  • I want to learn how to work with Visual Studio without the mouse, because it's faster with the keyboard only. This is an old resolution that I want to approach now.
  • I realised that our style of "mob programming" is different to the original style proposed by Woody Zuill and his team. In the original proposal, the driver is mostly "keyboarding", focusing on typing what the navigators tell him to do. Our approach is different, we have the discussion and the person who clearly sees how to translate the idea into code jumps in the keyboard and expresses it in code, no one says to the driver what should be written. The driver leads the session when he is at the keyboard. It's sometimes easier to express an idea writing some code or pseudo-code, than trying to explain how the code is going to look like, and I think this has to do with the fact that talking constantly exhausts me. It also has to do with focus, the driver is the person who can implement the discussed idea faster, who knows the code better. Whenever the driver is stuck, the navigator who knows how to carry on, asks for the keyboard and becomes the driver. I find dictating awkward and sometimes irritating. So we are not following their rule: "for an idea go from your head into the computer it MUST go through someone else’s hands.". We try not to talk whilst the driver is typing just like in pair programming, because we want the driver to be able to listen what navigators have to say, and I can't type and listen at the same time. Perhaps we are not doing mob programming at all. But it works for us.
  • In order to keep the good energy and motivation in a mob or pair prog session, it's better to give up or take a break than working without feeling like it. I need to feel that my colleagues feel like working and thus I must feel like doing so too.
  • I really like the way Peter summarized the Hexagonal Architecture, focusing on the direction of the dependencies. A simple diagram with two boxes joined by an arrow pointing from one to the other, was enough for people to understand it. Also the onion was a good idea.

Regarding the Global Day of Code Retreat, there are a bunch of things I learned from Peter and from the day itself:

  • If there are no sponsors buying food, I want to buy food myself for me and for all the participants. This year I brought the food in the afternoon but I should have brought it in the morning, when people were hungry. Next time I'll arrive in the morning with breakfast for everyone. I missed the relaxing moment of the morning break sharing some fruit and coffee or tea.
  • Whenever I talk very serious aiming to remark something important, I look like I am rude. I don't realize that until I see people's faces and by then I feel bad about it. To avoid this situation I'll think twice before sending the message. I must be quiet, talk more slowly, think from a positive angle and use positive words. Words like "no" or "not" or "don't" may be negative. I want to read about Non Violent Communication and practice it.
    As an example, during the retreat in one iteration's retrospective I said that the facilitators (Peter and me) were not there to teach. My aim was to encourage people to learn from themselves rather than expecting some kind of master class or demo from our side, but the way I said it was understood as ... "I am not here to help you, or I don't care about you" as some people told me afterwards. It had a negative impact in some people's motivation.
  • At the end of the day, after the final retrospective, in the pursuit of feedback and appreciation I talked in such an unfortunate way that made people feel in debt with us. But again I didn't realise until I saw people's reaction. My aim was to discover what benefits did participants find out during the day, what did they take away so that next time I could maximize it with specific actions or exercises.
    When it's obvious that I've dedicated time and energy working for others, I must be very careful not to express that explicitly because it will make people feel in debt which is not what I wanted.

Several friends have spoken to me about Non Violent Communication (NVC) in the last 5 years or so, I believe Diego Rojas was the first one, working with Peter was a trigger point for me to really start digging into the subject. Thank you for the recommendation Peter and for this excellent video by Marshall Rosenberg, the father of NVC:

XP Team Building

Let the team walk its path

Every team walks at its own pace and I haven't found a way to speed it up myself, I don't think there is one regardless of whether you are an external coach or a regular member of the team. Trying to push the team will screw up the work environment, the pressure may introduce interpersonal conflicts and severe damages in the quality of the product. I mean, people will do stuff they do know it's wrong because of the sense of emergency. On the other hand trying to pull the team away will give its members the impression that they are not trusted professionals, again causing problems among people and discouraging them from being proactive and willing to learn.
The only way we can help the team progress is to help them walk their own path, removing impediments along the way, answering questions when asked to do so.

I've learned that it's not possible to develop a software product at the speed that I'd like whilst mentoring people. I have to choose either to be a trainer or to be a developer but not both things at the same time because the goals are different. When working as a trainer the goal is that people learn effectively and the best way, for us humans, to learn is by making mistakes that let us learn from ourselves. As a mentor I must combine small theoretical explanations, recommendations and practical examples with time for people to practice and to make their own decisions. They must have the chance to fail and discover. If they don't recognize the failure my mission is to provide feedback and explain why is this or that a mistake and what are the consequences. Deep lessons are learned with pain - success is fantastic but it doesn't teach. However this style of mentoring takes a lot of time, it's probably the top most time consuming way. It's a company wide commitment, an effort for everyone.

Often companies ask us to join them for a new project that must deliver value within a tight schedule and at the same time they want to build up a team of XP developers with people that have never been exposed to XP. I must say this is completely impossible in my experience. If the quality of the product needs to be excellent and deadlines are tight, the best thing the company can do is to hire a seasoned high-performing XP team whose members have been working together for years. On the other hand, if the actual goal is to build up a team, this is an investment that lasts several years. According to my experience, a group of 6 to 8 developers become an XP team after 2 years of training, guidance, reviews and practice. It requires several training courses during the various stages of the transition, practical examples, guidance and moreover it requires small failures (hopefully reversible ones). People have to have the margin to fail and learn from their mistakes. During this period some people will very likely leave the company and some new people will join.

I know the word quality is too abstract, we don't have a definition for what quality is but I am actually talking about well-known maintenance issues. A common mistake beginners make is to write brittle and hard to maintain tests that with time impede developers changing or adding features. Those tests are eventually deleted. It's waste unless you consider this to be another stage in the team's learning curve.
Nobody writes perfect code anyway, every team makes mistakes so the point is not to aim for perfection. The point is to avoid or minimize the amount of things we do know are waste, basically because we have failed in the past.
Hiring seasoned external consultants means they won't make the same mistakes they did in the past although they'll make new mistakes. Every team is different as well as every project.
As a consultant I won't prevent the team from making mistakes when the goal is to train them, instead I'll try to keep the cycles small enough so that mistakes can be fixed soon and cheap. But it's up to the team to ask for feedback and review, my job is not to control the source code - it's to support the team!

In some situations it could be beneficial that a small group of experts write the "walking skeleton" with the first group of product features in order to define architecture, style and conventions that others can follow. It serves to explore risks and exposes an example that others can follow. There are several perils of this approach though. I'd be careful with it - sorry don't feel like writing about these drawbacks now.

Notes from Socrates 2015

The 5th Socrates Conference in Germany has been my first continental Socrates Conference (I've been to UK twice plus another one in the Canaries). What a mind blowing unconference! I got even more value from Socrates than I expected! this has been the biggest in size ever with almost 190 people. There were so many people that it felt like there were 3 conferences going on at the same time. Even in my last couple of hours in the venue I still found new faces, people I thought I didn't see before. Despite of so many people the atmosphere was excellent as usual and the organization brilliant. Congratulations to the organisers! everything was organised with German precision! Danke schön 😉
Unfortunately Andreas - one of the founders - couldn't join us but I am glad he is recovering well.

I've learned many things, met old friends (although I wanted to spend more time with them!) and made new ones.

I have to thank my friend Ivan (@istepaniuk) for being our host and guide in Amsterdam and for driving us to Soltau. Thank you Imo (@kabomi), Juan (@_jmgomez_) and Adrian (@eidrien) for your fantastic company.

Thank you Pierluigi Pugliese (@p_pugliese) for your excellent job as facilitator and the conversation/coaching we had during lunch time.

  • Twitter hashtag was #socrates15
  • Really like the idea of the world cafe on Thursday to get people thinking on what they would like to happen the next days.
  • There are so many proposals that is hard to remember some sessions when looking at the panel, that makes it even harder to choose sessions. Next time I'll write down in paper exactly the minimum and most effective sentences I'll need to present my proposal so that I'll just have to read when the time arrives. Talking to the mic is a bit unconfortable when not used to it.
  • I'll book more time to spend with my friends and specially with my colleagues.
  • In the sessions intended for me to ask questions, to be taught something or to have a discussion is not necessary to have slides but it's worth preparing the session. It could be a script, a few examples to discuss on, a set of questions... something to facilitate the session and an idea of what to achieve with it.
  • Some of the most valuable moments happen out of the scheduled time table or in those with a small group of people. Next time I'll plan to spend about half of each day out of the rooms, talking and coding with people or even coding on my own in places where others can see me and join.
  • I will propose maximum one session per day, then I'll feel more relaxed and free to change plans.
  • Sleeping enough is key to enjoy the event until the end, otherwise I am already a zombie at the end of the first day. Nightly discussions are super interesting, I'll probably oversleep in the morning at least one day to be fresh and ready for the night.
  • Socrates is an open space where I can go without any session prepared, people are so amazing that there will be for sure a lot of stuff to learn.
  • The idea of workshops on Sundays is brilliant we'll do the same in Socrates Canaries. I've learned many things on Sunday working on a walking skeleton and solved many doubts regarding DDD. Special thanks to Bardford (@gruebelinchen), Björn, Felipe (@felipefzdz), Martin (@md42), Dimitry (@dimitrypolivaev), Ivan and all the people that stepped in and out during the workshop.
  • It's the right time for our team to embrace ES6 and use it in the project we are starting from scratch. Thank you Wolfram (@wolframkriesing), Marco (@marcoeimrich) and Christian (fonzygruen) for all the insight and information. Thank you also for ES6Katas and Ramda.js - we're gonna use both. Thank you also for valuable resources like NodeSchool and the refactoring kata (refactoring to functional style using Rambda) proposed by Marco.
  • Property-based testing is definitely something I want to try. Thank you for the insight and opinions on when to use it and when not to use it, specially to Pawel  (@pawelduda) and Kuba.
  • The theory of type systems is super interesting, I would like to get the slides from Ivan (@ikusalic) and compare how Type Classes in Scala are different to generics in C#.
  • Informal discussions like "Developer Ethics" are perfect to be hold during lunch time. I'll propose topics for lunch time like in this conference, so that I'll know what to talk about with people I don't know but who share a common interest. Unfortunately tables were not big enough this time to join some lunch discussions.
  • I really like the metaphor of the power lifting in pairs to explain pair programming, thank you Houssam (@houssamfakih) for sharing your experiences along these years of practise.
  • I want to learn more about Event Sourcing and CQRS. This is the second conference where people recommend Event Storming and I haven't used it in a real project. It's on my to-do list.
  • Thank you Tobi (@tpflug) and Chris (@c089) for organising the Power Point Karaoke once again and the variants. Thank you Adrian, Pawel, Christian (@dertseha) & company for such hilarious nights. I plan to play the PP Karaoke on the New Year's eve with family and friends.
  • Choose the blue route in the GPS, not the red one - although Germany is beautiful.
  • 30 mins Gym + 30 mins sauna after the sessions is a must. German get naked in the sauna no matter if there are men and women mixed.

Among other qualities good tests should be easy to read, quick to understand. When the test requires complex data structures to be sent to the SUT or to be part of a stubbed answer, it takes longer to read. Moreover those structures use to evolve as the production code does causing too many changes in the tests in order to adapt them. An indirection level in between the test and the production code helps improve readability and ease of maintenance. Builders come to the rescue. I often overload builder methods to support several data structures and then apply the conversions internally.

As an example, this is the setup of one of our tests before the final refactor:

  1. [Test] public async void
  2. raise_multiple_choices_event_on_equipment_selection () {
  3. SetupViewModelWithMockService();
  4. var selectedEquipment = new Equipment { Code = "PR" };
  5. var oneEquipment = new Equipment { Code = "PR1"};
  6. var otherEquipment = new Equipment { Code = "PR2"};
  7. var equipments = new List<Equipment>{ selectedEquipment, oneEquipment, otherEquipment };
  8. var multipleChoices = new List<CompulsoryCombinationChoice> {
  9. new CompulsoryCombinationChoice(new List<CompulsoryCombinationItem> {
  10. new CompulsoryCombinationItem(oneEquipment.Code, CatalogItemTypes.Equipment)
  11. }),
  12. new CompulsoryCombinationChoice(new List<CompulsoryCombinationItem> {
  13. new CompulsoryCombinationItem(otherEquipment.Code, CatalogItemTypes.Equipment)
  14. })
  15. };
  16. ACatalog.MockingDependenciesOf(vm)
  17. .WithEquipments(equipments)
  18. .ResolvingCompulsoryCombinationsAs(multipleChoices)
  19. .Configure();
  20. /* act ... */
  21. /* assert ... */

Imagine how ugly it was before the "ACatalog" builder. And this is the test after the builder was overloaded to supply a more comfortable API:

  1. [Test] public async void
  2. raise_multiple_choices_event_on_equipment_selection() {
  3. SetupViewModelWithMockService();
  4. var theEquipment = "PR";
  5. var equipment1 = "PR1";
  6. var equipment2 = "PR2";
  7. ACatalog.MockingDependenciesOf(vm)
  8. .WithEquipments(theEquipment, equipment1, equipment2)
  9. .ResolvingCompulsoryCombinationsAs(
  10. MultipleCompulsoryCombinationChoices(
  11. equipment1, equipment2))
  12. .Configure();
  13. /* act ... */
  14. /* assert ... */

Productive Pair Programming

The title of this post is redundant, pair programming is already a productivity technique. That's my understanding or pair programming not just two people sitting together. Two people may code together for learning or mentoring purposes, however we pair for productivity reasons - productivity in the long term.
Like any other XP practice, this one aims to promote the values:
When I pair I get immediate feedback about my design and ideas. The communication is direct and the conversation provides us with simplicity. Good pairs respect each other and have the courage to split when necessary.

In my experience, it takes quite a lot of time to become a productive pair because one needs to learn how the other think. You need to know when the other person is focused not to break her flow. The navigator should never perform the role of the IDE, we obviously don't interrupt to say... "you missed a bracket in there" as the IDE is already highlighting the mistake. We wait until the driver is not typing to ask questions, propose changes or take turns. Nevertheless waiting for the silence in order to start up a discussion is not enough. When I am the driver, I need my pair to realise that sometimes I need silence to think, specially when my flow is appropriate. The fact that I am not typing does not mean I am ready to talk about other levels of abstraction. As the driver, when this happens I ask the navigator for a few seconds of patience and trust. Flow is one of the most important principles when it comes to TDD and Pair Programming to me. If the flow is interrupted continuously, pairing is frustrating. As a navigator part of my mission is to discover when the driver is ready to listen to me. Although a healthy pair is talkative, silence is necessary. The amount of silence depends on the context. If the navigator is a junior (means that he lacks some knowledge - domain or technical) then as a driver I need more time to demonstrate my points. I need to conquer little milestones with code to later explain the underlying rationale with words. In this case, talking about written code that works, feels easier to me.
I've learned recently that sometimes I just need to ask the navigator to be quite and write down notes that we can discuss some minutes later. Although I used to be open to discussion at anytime, I've learned to prioritize flow. If the navigator is a senior then his comments will be practical and direct and so continuous discussion feels more natural.

The silent moments I am talking about last between 30 seconds and 3 minutes. Being quite for more than 5 minutes might be a sign that the pair is not working well. So yes, there is a conversation which is not the same as thinking out loud. My recommendation is that the navigator always has some paper notes to avoid thinking out loud half baked ideas. Discussing half baked ideas is OK as long as the driver is not typing. If I am typing I can't listen to my pair.

Pairing is also about adding the right amount of pressure to the other. The driver should engage the navigator to avoid the "back-seat" driver syndrome. Taking turns help. Alternate often when the pair is well-balanced. Consider taking longer turns when there is a junior. Be careful, if the pressure trespass a certain threshold part of the intellectual capacity is cancelled. We can't think properly under high pressure.

There are different kinds of interruptions from the point of view of the abstraction level. Low level abstraction comments are easier to handle than high level ones. For instance, say the driver has stopped typing and she is observing the code she's just written, the navigator could say.... "that method should be private, rather public". The level of abstraction of that comment is very likely compatible with the current thoughts of the driver, she can easily accept the change and still focus on the TO-DO list. However, something like "how would you implement that in Clojure" might kill the flow. That comment is OK once the driver is open to discuss. Having a TO-DO list or some kind of little roadmap that is created at the beginning of the pairing session is important to focus on the right level of abstraction.

There is a lot to write on pair programming, this post contains just a few ideas related to my recent experiences. I like this funny list of ways to hate pair programming - the challenge lies in getting to know your pair enough to notice when you are pairing badly.



We were part of CukeUp! 2015

I had the pleasure of speaking at CukeUp! this year (2015), the fifth edition of Cucumber's conference which is more about BDD than Cucumber itself, although there are always updates on the state of the tool (this year Matt released version 2.0 during his talk!)

Borja and I

Borja and I

It's been a great conference, I've learned a bunch of things, met friends and new people. My colleague Borja Navarro accepted the challenge of co-presenting with me and that made our session fun, a least for me, a had a lot of fun. We engaged the attendees with a couple of examples together with questions and answers on how to write user stories with acceptance criteria and scenarios. The attendees were very helpful and active. This is the recorded session, although the sound is quite bad.

Thank you Borja, you rock mate!

These are my conference picks:

  • A mature XP team don't need to have people exclusively for testing and QA purposes. If every developer has testing skills and every pair is responsible for quality then people just play the two roles but there is no such distinction between testers and developers. There will be people with stronger development skills and people with stronger testing skills, experts on each area. Well, this is my understanding from Rachel's and Aimy's keynote.
  • They don't have a staging environment, they release directly into production, performing some smoke testing live with some "testing" user accounts. I find this technique specially interesting when the new features can be deployed just on a few servers so that only certain users get to exercise the new code whilst the others keep using the previous version for a while. Exploratory testing and other tests are performed on the development environment. The maturity level of the team has to be very high, sounds like a nice goal to reach at my current project.
  • I participated in Paul Rayner's useful workshop,  specially nice because I got the chance to share table with Steve Tooke and Gáspár Nagy, experts on the subject. My pick is that any technique that could help with discovery during the analysis stage is welcome. One of the suggested techniques was Event Storming, which I am going to trying as soon as I can. Since we are using DDD in our project, Event storming sounds like a great technique to combine analysis and modeling.
  • From Seb's talk there are many ideas to take away, it's worth reading the slides. I already listened to his talk in a previous event in London and I want to read the recommended books. Take a look at this map on how to split user stories.
  • Konstantin Kudryashov, creator of Behat, gave an interesting talk on how to explore and exercise the domain model from Gherkin scenarios, the slides are here. My understanding was that he uses domain objects within the step definitions as if these steps were unit tests. The approach is a bit different from the one we are using where the step definitions invoke actions on application services rather than objects from the inner hexagon. Although we use application services we usually stub out or spy on repositories aiming for fast tests. Another technique he employs is to mark a few scenarios as critical making them run end-to-end through the UI so as to make sure all pieces integrate with each other. It's good to know the techniques that are working for other people and see how they are different to the ones we currently use.
  • The keynote by Dan North was full of insight, I highly recommend watching it. I didn't watch it live as I prefer to chat with people whilst talks are being recorded - at that time I took the chance and enjoyed listening to Chris Matts in the bar. To me, the most interesting tip is the experiment Dan is conveying where every team member's board has to have Kaizen tasks, Discovery tasks and Feature tasks. Brilliant, isn't it?
  • The workshop by Chris Matts and Richard Warner was full of insightful ideas. I liked the exercise on "Left Shifting" company's culture. On the other hand they explained their discovery process when it comes to feature analysis. The three keys to discover new features are "Customer needs and wants", "Target group" and "Outcome". The workshop was recorded, it's worth watching that part of the session which was more of a talk than a workshop. My understanding is that they are not using user story mapping at all. It was really nice to share table with Nat Pryce during the workshop, he was very active and fun, I am glad I got to know him in person finally.
  • Matt Wynne's workshop was one of my favorite ones. I really like the password strength exercise to illustrate the difference between acceptance criteria (rules) and examples. See these slides for more details. The other pick is "Example mapping" a technique where the colors end up making obvious what we know and don't know about the context in order to write good user stories. I also realised that the examples used for exercises may work better when they are fun, when we add some humor to them. Writing user stories for a boring domain is not as engaging as writing them for some fun domain with curious situations.

At the end of the conference there was a panel with the experts, the creators of BDD. As a result Dan North came up with this initiative on explaining BDD by example. I want to contribute to those examples. By the way, Dan said he found John Ferguson's book very good, I have to check it out.

CukeUp brought me more value than I expected, I am glad I was part of it. Thank you organisers, you made a great job!


Este post habla de dos de los valores de XP: Simplicidad y Feedback. Fundamentales y habitualmente olvidados.

Cuando escribimos software o dibujamos una interfaz de usuario, estamos dando forma a una solución concreta de las muchas que puede tener un problema. Al elegir una solución automaticamente descartamos las demás porque nunca damos marcha atrás para escribir otra solución distinta si la que tenemos ya “funciona”. Por esto hay que reflexionar constantemente sobre la complejidad de la solución que hemos elegido. Lo mejor es hablarlo con los compañeros, discutirlo. A menudo exponiendo la idea descubrimos que podemos conseguir lo mismo de una manera más sencilla.

La clave para poder simplificar es tener en cuenta cuál es el objetivo (qué problema fundamental estamos resolviendo) de negocio. Pero no el objetivo del software a largo plazo sino de la release actual. Lanzamos releases frecuentes en ciclos cortos para obtener feedback y cada una tiene el objetivo de aprender algo concreto del negocio o de los usuarios. Cada release ofrece alguna caracteristica nueva o un cambio que les ayude en su día a día pero sin querer abarcar demasiado de un golpe. Me gusta que la lista de features y cambios de una release me quepa en la cabeza, que pueda contar con los dedos de una mano sin necesidad de documentos. Y que haya un objetivo predominante.

Para simplificar hay que tener en mente cuál es el objetivo de la release actual, que no es el mismo que la release que haremos dentro de 3 meses. De aquí a 3 meses habremos cambiado buena parte del código, a veces mediante refactoring y a veces porque nos damos cuenta de que hay otras necesidades. La vida cambia en 3 meses y en menos.

Conviene darle más de una vuelta a la solución, hay que “resimplificar” todo lo posible. Lleva poco tiempo hacerlo y tiene un beneficio muy grande en el medio y largo plazo. "Vale ya funciona, ahora vamos a echarle una pensada para ver si lo podemos simplificar, a ver si podemos borrar la mitad del codigo y que siga funcionando".

El código tiene que quedar fácil de entender y su simplicidad es más importante que el uso de patrones. No tenemos por qué aplicar el patrón MVVM en absolutamente todas las partes de la capa de presentación, a veces su complejidad no se justifica. Por cierto, recordemos que un ViewModel es una representación de la vista y no un DTO, un ViewModel es una especie de "controller".

La soluciones deben ser lo más abiertas posibles para poder dar margen de maniobra al usuario y aprender cual es su forma preferida de trabajar. Hay que identificar limitaciones innecesarias que estemos introduciendo tanto a traves de al interfaz de usuario como a nivel del código para poder evitarlas. Una solución abierta se centra en el problema a resolver, en el “qué” y permite cambios de forma con facilidad, poder pivotar hacia otras cosas.

Por ejemplo, imaginemos que hay 3 acciones fundamentales que el usuario puede realizar en la aplicación. No hace falta que las realice en un orden concreto, el objetivo de negocio es que pueda realizar las acciones A, B y C cuando mejor le convenga. Entonces no hagamos que para ejecutar la acción A, tenga que hacer primero la B. Eso es introducir una limitación innecesaria.

Ahora un ejemplo de complejidad excesiva: Imaginemos que queremos mostrarle al comercial la disponibilidad de un determinado modelo de vehiculo, es decir, si está en stock. El objetivo de negocio es que sepa si puede vender ese modelo o no. ¿Para qué vamos a contar cuántos vehículos hay disponibles de ese modelo? Le da igual si hay 24, solo necesita saber si tiene una unidad disponible para la venta o no la tiene. Para darnos cuenta de este exceso de complejidad tenemos que recordar el objetivo de la release. Recordar el propósito de la release actual.

Cuanto menos software escribamos mejor. La linea que no falla es la que no está escrita. Cada linea que escribimos es un compromiso que hay que mantener, hasta que alguien venga y la borre. Cuanto vamos justos para cumplir con el objetivo de la release (en el mundo del software esto es siempre), debemos recortar en alcance (funcionalidad) y nunca en calidad. Hay que hacer todo lo posible por respetar los tiempos de entrega previstos, consiguiendo el objetivo a base de quitar características menos importantes en el momento actual.