Archive for July, 2015



Identifying aggregates

An aggregate is particular kind of entity so first of all we need to know whether the model is an entity or a value object. Once we know it's an entity let's figure out whether it is an aggregate. A transaction should modify a single aggregate instance so the repositories should work with aggregates when possible - retrieve and save aggregates. The aggregate is an entity that may contain other entities and value objects. Some heuristics to discover which objects should be clustered into aggregates:

------ Aggregate A:
------   -  Entity B
------   -  Value D
------   -  Value E
------   -  Value F

  1. Model true invariants - an invariant is a business rule that must be consistent (transactionally or eventually) : If there is a rule saying that Value F = Value D + Value E, we must ensure that D, E and F are persisted together to always preserve that rule.
    "Aggregate is one that can be modified in any way required by the business with its invariants completely consistent within a single transaction".
  2. If we need transactional consistency in A, then although B is an entity, it doesn't make much sense to use B out of A's context, I mean, there is no reason for an entity of kind B to be modified or loaded without aggregate A - Imagine that A is an Invoice and B is an Invoice Line.
  3. Try to design small aggregates despite of the desire for compositional convenience.
  4. "Just because you are given a use case that calls for maintaining consistency in a single transaction doesn't mean you should do that. Often, in such cases, the business goal can be achieved with eventual consistency between Aggregates." 

The truth is that is really hard to model things up-front. Our current approach is to model the minimum we need for an action to be performed and then evolve. However the fact that we tried to identify aggregates in front of the whiteboard led us to a nice Context Map drawing session that provided us with a better understanding of the domain.

Source: Implementing Domain Driven Design - Vaughan Vernon

Cualquiera que esté aprendiendo puede beneficiarse de tener un blog. En la profesión de desarrollador uno aprende constantemente por lo que tener un blog es imprescindible en mi opinión. Es importante que entiendas que estas escribiendo para tí, para tu "yo" del futuro. No escribes un blog para los demás, como lo hacen los bloggers que ya tienen mucha experiencia y ganan dinero escribiendo, al estilo de los periodistas o escritores que tienen columnas en períodicos. Esto de ganar dinero escribiendo no tiene nada que ver con un blog personal. Los objetivos son diferentes. Por tanto las entradas de tu blog no tienen que ser perfectas, son meros apuntes, igual que los que tomabas cuando ibas a clase. A veces tienes más tiempo y entonces son resúmenes más que apuntes, notas sintetizadas. Tienes que ocuparte de escribir solo la información que necesitas para que tú misma/mismo seas capaz de entender lo que querías decir en aquel post de hace 6 meses. Nada más. Asi dejará de preocuparte que los demás critiquen tu blog y tardarás menos tiempo en añadir nuevas entradas.
Digan lo que te digan, tu blog es tuyo y puedes hacer con él lo que quieras. Hace tiempo despubliqué un post de crítica injustificada a Git porque me dí cuenta que no tenía sentido y que causaba confusión, fue un error haber publicado esos pensamientos porque ni me ayudaban a mi ni a nadie. Alguna gente me dijo que no podía despublicar, que eso rompía links y que no estaba bien.... pero es mi blog y hago lo que creo oportuno con él.

Lo ideal es que escribir un post te lleve máximo una hora y si lo puedas hacer en 15 minutos, mejor que mejor. Yo de media tardo unos 30 minutos. Si te va a llevar más de eso entonces te dará pereza escribir y terminarás por abandonar el blog. Es decir, la barrera de entrada que te pones para escribir, debe ser lo mas baja posible.
A alguna gente le funciona convertir notas del Evernote en posts de blog directamente.

Cuando aprendes algo, escribir sobre ello es una de las mejores formas de comprender mejor lo aprendido. Es un gran refuerzo de tu aprendizaje. Además es un tangible, una forma fácil de poner en valor la inversión que haces estudiando. Por ejemplo si lees un libro técnico y escribes un post comentando cada capítulo, asimilarás mejor el libro y tendrás un resumen estupendo al que acudir cuando haya que recordar.
Escribir te obliga a buscar un poquito más de información para despejar pequeñas dudas que no te habias planteado hasta que tienes que explicar lo aprendido.

Como son tus propios apuntes, si en el futuro necesitas recordar cómo se hacía algo que ya resolviste y que documentaste, te será más rápido recordarlo leyendo tus propios apuntes que volviendo a leerte varios hilos de StackOverflow. Yo me he arrepentido varias veces de no bloggear ciertas cosas.

Una vez que escribes sobre una idea ya te la quitas de la cabeza, tu mente se libera de ella y tienes hueco para otras cosas. A veces estoy deseando de escribir un post para que las ideas que me han llegado queden guardadas en algun sitio antes de que se me olviden. Así le dejan hueco a otros nuevos pensamientos y no tengo la mente dando vueltas a lo mismo, una y otra vez.

Intenta escribir tus pensamientos creativos y positivos. Las críticas negativas no te ayudan ni a ti ni a nadie, esto te lo digo despues de equivocarme muchas veces. No obstante lo mejor es que te equivoques tu mismo.

Como efectos colaterales de tener un blog (recuerda que no es el objetivo sino un efecto colateral) a veces conoces gente interesante y en los comentarios del post se producen discusiones muy enriquecedoras. Por eso recomiendo configurar plugins como el de Disqus para que las personas que comentan sean avisadas cuando alguien respnda. Otro efecto colateral es que se te pueden abrir nuevas oportunidades laborales. Te encuentra gente buscando resolver problemas sobre los que tu has escrito. Demuestra que eres una persona que se preocupa de su aprendizaje y que tiene una trayectoria de esfuerzo. Mi blog me ayudó a conseguir mi trabajo en Dublin cuando me fui sin nada, me ayudó más que tener un título universitario según me dijeron los entrevistadores. Pero recuerda! no escribas un blog porque quieres cambiar de empleo! porque no es así como funciona, solo funciona cuando sucede naturalmente. Sino te pillarán vendiendo la moto.
Otra cosa buena es que no tienes que repetirte tanto en ciertas conversaciones, puedes animar a la gente a que lea un post tuyo cuando se trata de un tema que ya estas cansado de hablar.

Para empezar hay muchos servicios gratuitos como Blogger.com o WordPress.org donde en cuestion de dos minutos tienes el blog creado. Mas adelante puedes comprarte un dominio propio e instalarte wordpress o lo que mas te guste. Si estas planteandote programar tu propio motor de blog, está bien, pero hazlo independiente de escribir tu blog, es decir que empieces escribiendo en wordpress mientras te programas tu blog y luego migres. Porque sino puede que nunca arranques a escribir.

Este post parece ser más para los demás que para mí, un poco al contrario de lo que cuento en él... sin embargo el verbalizar por escrito estos pensamientos me hace comprometerme más conmigo mismo a escribir con más frecuencia en mis dos blogs. Verbalizar tus pensamientos en voz alta o por escrito, aumenta tu compromiso contigo mismo, mucho más que si es un pensamiento interno.

Si te animas a iniciar un blog, sientete libre de dejar un comentario en este post con el enlace al mismo, yo me alegraré de saberlo.

Este post seguramente será actualizado con más pensamientos.

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 ... */
  22.  

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 ... */
  15.  

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.