Record of experiments, readings, links, videos and other things that I find on the long road.
Registro de experimentos, lecturas, links, vídeos y otras cosas que voy encontrando en el largo camino.
Sunday, December 31, 2017
Interesting Talk: "Cultivating Collaboration: Don't Be So Defensive!"
Interesting Talk: "How to build a company where the best ideas win"
Interesting Talk: "¿Tienes un #bug? Tus tests unitarios no están bien planteados"
Saturday, December 30, 2017
Interesting Talk: "Sobrevive al inframundo de los tests end to end"
Tuesday, December 26, 2017
Books I read 2017
- Vencidos pero vivos (Vaincus mais vivants), Maximilien Leroy and Loïc Locatelli Kournwsky
- El Boxeador: la verdadera historia de Hertzko Haft (Der Boxer: Die Überlebensgeschichte des Hertzko Haft), Reinhard Kleist
- Vuelo a casa y otras historias (Flying Home and Other Stories), Ralph Ellison
- Rendezvous with Rama, Arthur C. Clarke
- Treasure Island, Robert Louis Stevenson
- Agile Principles, Patterns, and Practices in C#, Robert C. Martin
- Atonement, Ian McEwan
- En una piel de león (In the Skin of a Lion), Michael Ondaatje
February
- El gigante enterrado, Kazuo Ishiguro
- The Time Machine, H.G. Wells
March
- JavaScript Patterns: Build Better Applications with Coding and Design Patterns, Stoyan Stefanov
- Slack: Getting Past Burnout, Busywork, and the Myth of Total Efficiency, Tom DeMarco
- El minotauro global (The Global Minotaur: America, the True Origins of the Financial Crisis and the Future of the World Economy 2nd edition), Yanis Varoufakis
- La sonrisa etrusca, José Luis Sampedro
April
- Howards End, E. M. Forster
- A Wizard of Earthsea, Ursula K. Le Guin
- Las tumbas de Atuan (The Tombs of Atuan), Ursula K. Le Guin
- En tierras bajas (Niederungen), Herta Müller
- How to Love, Thich Nhat Hanh
- La costa más lejana (The Farthest Shore), Ursula K. Le Guin
- Tehanu, Ursula K. Le Guin
- Obliquity: Why our goals are best achieved indirectly, John Kay
- Tales from Earthsea, Ursula K. Le Guin
- The Other Wind, Ursula K. Le Guin
- Metaphors We Live By, George Lakoff and Mark Johnson
May
- Are Your Lights On? How to Figure Out What the Problem Really Is, Gerald M. Weinberg, Donald C. Gause
- Bird by Bird: Some Instructions on Writing and Life, Anne Lamott
- Nonviolent Communication: A Language of Life, Marshall B. Rosenberg
- Mañana. Una revolución en marcha (Demain. Un nouveau monde en marche), Cyril Dion
- Thinking in Systems: A Primer, Donella H. Meadows, Diana Wright
June
- So Good They Can’t Ignore You, Cal Newport
- The Man Who Would Be King, Rudyard Kipling
- A Few Lessons From Sherlock Holmes, Peter Bevelin
- El dios de las pequeñas cosas (The God of Small Things), Arundhati Roy (2nd time)
- What Did You Say?: The Art of Giving and Receiving Feedback, C. N. Seashore, G. M. Weinberg, E. W. Seashore
July
- Pride and Prejudice, Jane Austen
- La Meta (The Goal), Eliyahu M. Goldratt
- Structured Design: Fundamentals of a Discipline of Computer Program and Systems Design, Edward Yourdon and Larry L. Constantine
- The Tartar Steppe (Il deserto dei Tartari), Dino Buzzati
- Getting It Done: How to Lead When You're Not in Charge, Roger Fisher, Alan Sharp
- Humble Inquiry: The Gentle Art of Asking Instead of Telling, Edgar H. Schein
- Occupy, Noam Chomsky
August
- Sinuhé, el egipcio (Sinuhe egyptiläinen), Mika Waltari (2nd time)
- La mejor oferta (La Migliore Offerta), Giuseppe Tornatore
- Programming Beyond Practices, Gregory T. Brown
- Clojure Polymorphism, Paul Stadig
- Why Don't We Learn from History?, B. H. Liddell Hart
- Usable Software Design, Alexandru Bolboaca
- Decline and Fall, Evelyn Waugh
- La Casa Infernal (Hell House), Richard Matheson
September
- Clojure for the Brave and True, Daniel Higginbotham
- For Two Thousand Years (De două mii de ani), Mihail Sebastian
- How We Learn: The Surprising Truth About When, Where, and Why It Happens, Benedict Carey
- A Tale of Two Cities, Charles Dickens
- Filters against Folly: How to Survive despite Economists, Ecologists, and the Merely Eloquent, Garrett Hardin
- Better: A Surgeon's Notes on Performance, Atul Gawande
- One Day in the Life of Ivan Denisovich (Один день Ивана Денисовича), Aleksandr Solzhenitsyn
October
- The Yiddish Policemen's Union, Michael Chabon
- Invisible Man, Ralph Ellison
- The Moon Is a Harsh Mistres, Robert A. Heinlein
- Gentlemen of the Road, Michael Chabon
November
- The Final Solution: A Story of Detection, Michael Chabon
- Turn the Ship Around!: A True Story of Turning Followers into Leaders, L. David Marquet
- The Mysteries of Pittsburgh, Michael Chabon
- The Big Sleep, Raymond Chandler
- The Plague (La Peste), Albert Camus
- Jude the Obscure, Thomas Hardy
December
- 70 haikus y senryûs de mujer, Suzuki Masajo, Kamegaya Chie, Nishiguchi Sachiko
- Lord of the Flies, William Golding
- The Masque of the Red Death, Edgar Allan Poe + The Three Strangers, Thomas Hardy
- Kokoro (こころ), Natsume Sōseki
- The Five Dysfunctions of a Team, Patrick Lencioni
- La ciudad de la niebla, Pío Baroja
Saturday, December 23, 2017
Wednesday, December 20, 2017
Interesting Talk: "Tbd (Test Bridle Development)"
Tuesday, December 19, 2017
Interesting Talk: "En mi equipo esto funciona pero no se por qué"
Saturday, December 16, 2017
Interesting Talk: "Continuous Delivery for Architects"
Interesting Talk: "Attitude Determines Altitude, Engineering Yourself"
Friday, December 15, 2017
Third open TDD Training in Barcelona (in spanish)
En vista del éxito que habían tenido los dos cursos abiertos de TDD que habíamos hecho este año en Barcelona, nos decidimos a hacer un nuevo curso abierto en Noviembre. Los cursos en abierto me hacen especial ilusión porque fue en uno de estos cursos abiertos dado por Carlos Blé en 2011 donde tuve la oportunidad de empezar a aprender sobre TDD.
En principio ibamos a dar el curso Luis y yo, pero, desgraciadamente, contraje el síndrome de Miller Fisher, y al final Luis tuvo que dar el curso en solitario.
Asistieron ocho personas, de las cuales siete venían de la misma empresa, Systelab. ¡Muchas gracias por confiar en nosotros y kudos especiales para las personas que se pagaron el curso de su bolsillo!
El hecho de que casi todo el mundo viniese de la misma empresa hizo que no hubiera tanta variedad de lenguajes como en otros cursos en abierto: todos usaron Java. Las katas salieron de forma bastante fluida y el feedback que recibimos fue bastante bueno.
Finalizado el curso de TDD de @codesaidev facilitado por @luisrovirosa con la mochila de conocimientos a reventar y con enormes ganas de aplicar lo aprendido. Muuuuuuuuuyyyy recomendable!!!!!
— Fernando Monferrer (@Ferniter) 21 de noviembre de 2017
2017 ha sido un año muy fructifero en lo que se refiere a los cursos en abierto de TDD en Barcelona. Hemos tenido la suerte de hacer tres cursos (ver posts sobre el primero y el segundo) y de conocer a un montón de gente estupenda. Muchísimas gracias a todos las personas que asistieron.
Para finalizar quería dar las gracias a Magento, a Ángel Rojo, a Fernando Monferrer y a nuestra compañera Dácil por toda la ayuda que nos prestaron para que estos tres cursos llegaran a suceder.
Publicado originalmente en el blog de Codesai.Thursday, December 14, 2017
Interesting Talk: "Rich Hickey on Clojure Spec"
Wednesday, December 13, 2017
Interesting Panel: "Clojure Remote Panel: Web Development in Clojure"
Tuesday, December 12, 2017
Interesting Talk: "What We Actually Know About Software Development, and Why We Believe It’s True"
Interesting Talk: "Using Clojurescript to launch iOS/Android apps to 1M users"
Wednesday, December 6, 2017
Saturday, December 2, 2017
TDD Trainings at Merkle Comet
Last October Luis Rovirosa, Jordi Anguela and I had the pleasure to give three TDD trainings at Merkle Comet’s impressive offices in Barcelona. Merkle Comet is a consulting company distributed worldwide which is very committed to deliver not only value but also high quality software to their clients.
We worked with three groups comprised of people from different teams. This mix was challenging but also rewarding because the members of each team brought with them different set of problems, skills and practices, which lead to interesting discussions and opportunities to learn. All in all, I think we managed to satisfy the expectations they had about our training.
I delivered two of the trainings with Luis, and Jordi and Luis the other one. Every time it’s possible we try to give our trainings in pairs because we think it makes them much better. Being two we can devote more time to give feedback and help each person with their doubts while they are working through the katas. It also helps us monitor our audience better so that we can adapt our message to their needs.
We loved working with such great people. We’d like to thank them all for the great time we had. We’d also like to specially thank Nelson Cardenas for having contacted us to work with them. We’d love to continue collaborating with this great team in the future.
Published originally in Codesai's blog.Thursday, November 30, 2017
Interesting Talk: "Functional Programming with Effects"
Sunday, November 26, 2017
Interesting Talk: "Domain Invariants & Property-Based Testing for the Masses"
Interesting Talk: "Thermodynamics of Software"
Interesting Talk: "Side Effects are a Public API"
Friday, November 24, 2017
Kata: Fractions in JavaScript ES5 using the Function as Object pattern
We usually do it in Java, but last week Antonio and I did it in JavaScript ES5 using the Function as Object pattern. This is a very interesting pattern to create objects that you can use in any language with first-class functions and closures. In Codesai we use and teach this pattern when working in projects using ES5.
We had a great time doing this kata in several short sessions that are also helping me in my recovery process.
These are the tests we wrote:
and this is the resulting code:
See all the commits here if you want to follow the process. You can find all the code on this GitHub repo.
Interesting Talk: "Cultivating Your Design Heuristics"
Wednesday, November 22, 2017
Interesting Talk: "How to make your code sustainable - what they don’t teach you"
Tuesday, November 21, 2017
Interesting Talk: "Lean and Functional Programming"
Friday, November 17, 2017
Native/Browser SPA versions using ClojureScript and re-frame talk at SCBCN17
I talked mainly about how re-frame's effects and coeffects, re-frame's subscriptions and modelling a UI as FSMs place you in a pit of success, i. e., a design that, according to Jeff Atwood, "makes it easy to do the right things and annoying (but not impossible) to do the wrong things".
It was my first talk in a big conference and I had some technical problems, so I was very nervous at the beginning. After a while I relaxed and felt better. In the end I received more questions than I expected and very nice feedback.
I'd like to thank Modesto for lending me his computer when mine crashed just before the talk and helping me relax.
This is the video of the talk, (thanks Autentia for recording all the talks and for being so kind to me when I was having technical difficulties). I hope you'll find it interesting:
and these are the slides that I've improved after the talk using Modesto's feedback (thanks!!): .
Thanks to Francesc and all the people in Clojure Developers Barcelona Group, Green Power Monitor and Codesai that contributed to improve the talk with their feedback. Also thanks to my colleague Antonio for "persuading" me to give a talk in a conference.
Finally, I'd also like to thank Software Craftsmanship Barcelona 2017 conference organizers for giving me the opportunity to talk at such a great conference and for all the effort they put to make this conference better, edition after edition.
Wednesday, November 15, 2017
Course: Purely functional Scala
It's a challenging course in which we learned about type classes, functors, monadic APIs and composition of effects. It's tough but very interesting, and I discovered a very flexible and robust way of designing software which goes beyond what you can achieve using ports and adapters in OO.
Habla Computing's team explains these concepts in a very creative and accessible way that gently takes you from what you already know from OO (separations of concerns, ports and adapters,...), into the monadic APIs, so that you can see the need for the new patterns and how they come to be, without losing yourself in too much mathematical jargon.
I wanted to do this course since I met Juan Manuel Serrano in the first Lambda World in Cádiz two years ago, and when I finally had the chance to attend it, I loved it. Juan Manuel is the CTO of Habla Computing and he is doing a great work in making functional programming more accessible (I've posted several of his talks in this blog). I really recommend Habla Computing's course to anyone that would like to enter the world of functional programming.
Thanks a lot to Habla Computing's team for this great course!
Monday, November 13, 2017
Recovering
It has affected my sight, arms and legs. Let's say that the latency of my nerves is a bit too high at the moment. I'm much better thanks to the medication. I can walk again, even though my equilibrium is not very good. My brain has to work extra to compensate the lack of information it receives, so walking and/or standing for a while makes me exhausted. I'm walking everyday and with physiotherapy sessions this will improve soon. What will take longer is recovering my sight because the nerves that control eye movement are more precise. I was told it'll take between 4 and 6 months to see well again. At the moment I see double and a bit fuzzy.
To avoid seeing double I'm using eyepatches that I alternate so I use each eye half of the day. I'm starting to read, write and/or draw 20' with each eye everyday to practice. It's also a bit tiring but I'm improving day by day.
If everything goes well with the physiotherapy sessions, I hope to be able to work 4 hours a day by January. Let's see.
I'd like to thank my family for their support, especially María, who was by my side through the worst of it, and my parents, who have moved to Barcelona to live with us while I recover. I'd also like to thank all my friends and colleagues for visiting me and for their messages of support. Finally, I'd like to thank the professionals of the CAP Les Corts and the Hospital Clínic for healing and taking care of me so well. We really appreciate it. I'm very happy and proud that we have a public health system in our country. Let's protect it.
Wednesday, October 18, 2017
Interesting Talk: "Generative Integration Tests"
Sunday, October 15, 2017
Wednesday, October 11, 2017
Friday, September 15, 2017
Interesting Talk: "Leading your teams with maps"
Monday, September 11, 2017
Interesting Talk: "Unidirectional data flow architectures"
Sunday, September 3, 2017
Data clumps, primitive obsession and hidden tuples
I had wondered in the past why we use a similar refactoring to eliminate both primitive obsession and data clump smells. Thinking about them from the point of view of connascence has helped me a lot to understand why.
I had also an alternative and curious reasoning to get to the same conclusion, in which a data clump gets basically reduced to an implicit form of primitive obsession. The reasoning is as it follows:
The concept of primitive obsession might be extended to consider the collections that a given language offers as primitives. In such cases, encapsulating the collection reifies a new concept that might attract code that didn't have where to "live" and thus was scattered all over. So far so good.
From the point of view of connascence, primitive obsession is a form of CoM that we transform into CoT by introducing a new type and then we might find Connascence of Algorithm (CoA) that we'd remove by moving the offending code inside the new type.
The composing elements of a data clump only make sense when they go together. This means that they're conceptually (but implicitly) grouped. In this sense a data clump could be seen as a "hidden or implicit tuple".
Having this "hidden collection" in mind is now easier to see how closely related the data clump and primitive obsession smells are. In this sense, we remove a data clump by encapsulating a collection, its "implicit or hidden tuple", inside a new class. Again, from the point of view of connascence, this encapsulation reduces CoM to CoT and might make evident some CoA that will make us move some behavior into the new class that becomes a value object.
This "implicit tuple" reasoning helped me to make more explicit the mental process that was leading me to end up doing very similar refactorings to remove both code smells.
However I think that CoM unifies both cases much more easily than relating the two smells.
The fact that the collection (the grouping of the elements of a data clump) is implicit also makes it more difficult to recognize a data clump as CoM in the first place. That's why I think that a data clump is a more implicit example of CoM than primitive obsession, and, thus, we might consider its CoM to be stronger than the primitive obsession's one.
A curious reasoning, right?
Saturday, September 2, 2017
Interesting Talk: "Rethinking All Practices: Building Applications in Elm"
Interesting Talk: "Beyond Continuous Improvement"
Wednesday, August 30, 2017
Books I read (January - August 2017)
- Vencidos pero vivos (Vaincus mais vivants), Maximilien Leroy and Loïc Locatelli Kournwsky
- El Boxeador: la verdadera historia de Hertzko Haft (Der Boxer: Die Überlebensgeschichte des Hertzko Haft), Reinhard Kleist
- Vuelo a casa y otras historias (Flying Home and Other Stories), Ralph Ellison
- Rendezvous with Rama, Arthur C. Clarke
- Treasure Island, Robert Louis Stevenson
- Agile Principles, Patterns, and Practices in C#, Robert C. Martin
- Atonement, Ian McEwan
- En una piel de león (In the Skin of a Lion), Michael Ondaatje
February
- El gigante enterrado, Kazuo Ishiguro
- The Time Machine, H.G. Wells
March
- JavaScript Patterns: Build Better Applications with Coding and Design Patterns, Stoyan Stefanov
- Slack: Getting Past Burnout, Busywork, and the Myth of Total Efficiency, Tom DeMarco
- El minotauro global (The Global Minotaur: America, the True Origins of the Financial Crisis and the Future of the World Economy 2nd edition), Yanis Varoufakis
- La sonrisa etrusca, José Luis Sampedro
April
- Howards End, E. M. Forster
- A Wizard of Earthsea, Ursula K. Le Guin
- Las tumbas de Atuan (The Tombs of Atuan), Ursula K. Le Guin
- En tierras bajas (Niederungen), Herta Müller
- How to Love, Thich Nhat Hanh
- La costa más lejana (The Farthest Shore), Ursula K. Le Guin
- Tehanu, Ursula K. Le Guin
- Obliquity: Why our goals are best achieved indirectly, John Kay
- Tales from Earthsea, Ursula K. Le Guin
- The Other Wind, Ursula K. Le Guin
- Metaphors We Live By, George Lakoff and Mark Johnson
May
- Are Your Lights On? How to Figure Out What the Problem Really Is, Gerald M. Weinberg, Donald C. Gause
- Bird by Bird: Some Instructions on Writing and Life, Anne Lamott
- Nonviolent Communication: A Language of Life, Marshall B. Rosenberg
- Mañana. Una revolución en marcha (Demain. Un nouveau monde en marche), Cyril Dion
- Thinking in Systems: A Primer, Donella H. Meadows, Diana Wright
June
- So Good They Can’t Ignore You, Cal Newport
- The Man Who Would Be King, Rudyard Kipling
- A Few Lessons From Sherlock Holmes, Peter Bevelin
- El dios de las pequeñas cosas (The God of Small Things), Arundhati Roy (2nd time)
- What Did You Say?: The Art of Giving and Receiving Feedback, C. N. Seashore, G. M. Weinberg, E. W. Seashore
July
- Pride and Prejudice, Jane Austen
- La Meta (The Goal), Eliyahu M. Goldratt
- Structured Design: Fundamentals of a Discipline of Computer Program and Systems Design, Edward Yourdon and Larry L. Constantine
- The Tartar Steppe (Il deserto dei Tartari), Dino Buzzati
- Getting It Done: How to Lead When You're Not in Charge, Roger Fisher, Alan Sharp
- Humble Inquiry: The Gentle Art of Asking Instead of Telling, Edgar H. Schein
- Occupy, Noam Chomsky
August
- Sinuhé, el egipcio (Sinuhe egyptiläinen), Mika Waltari (2nd time)
- La mejor oferta (La Migliore Offerta), Giuseppe Tornatore
- Programming Beyond Practices, Gregory T. Brown
- Clojure Polymorphism, Paul Stadig
- Why Don't We Learn from History?, B. H. Liddell Hart
- Usable Software Design, Alexandru Bolboaca
- Decline and Fall, Evelyn Waugh
- La Casa Infernal (Hell House), Richard Matheson
Monday, August 28, 2017
Interesting Talk: "Beyond PEP 8, Best practices for beautiful intelligible code"
Wednesday, August 23, 2017
Notes on OCP from Agile Principles, Practices and Patterns book
- OCP -> "Software entities (classes, modules, functions, etc) should be open for extension but closed for modification <- [Martin's definition. The origin of the principle comes from Bertrand Meyer that gave it a slightly different definition]"
- "When a single change to a program results in a cascade of changes to dependent modules, the design smells of fragility" <- [related with violating Beck's Local Consequences principle from Implementation Patterns] OCP advises us to refactor the system so that further changes of that kind will not cause more modifications. <- [related with Cockburn's & Larman's Protected Variations] If OCP is applied well, further changes of that kind are achieved by adding new code, not by changing old code that already works"
- "It's possible to create abstractions that are fixed and yet represent an unbounded group of possible behaviors"
- "[A module that uses such abstractions] can be closed for modification, since it depends on an abstraction that is fixed. Yet the behavior of the module can be extended by creating new derivatives of the abstraction"
- "Abstract classes are more closely associated to their clients than to the classes that implement them" <- [related with Separated Interface from Fowler's P of EAA book]
- "[Strategy and Template Method patterns] are the most common ways to satisfy OCP. They represent a clear separation of generic functionality from the detailed implementation of that functionality"
- Anticipation
- "[When a] program conforms to OCP. It is changed by adding code rather than by changing existing code"
- "In general no matter how "closed" a module is, there will always be some kind of change against which it is not closed"
- "Since closure can't be complete, it must be strategic. That is the designer must choose the kinds of changes against which to close the design, must guess at the kinds of changes that are most likely, and then construct abstractions to protect against those changes."
- "This is not easy. It amounts to making educated guesses about the likely kinds of changes that the application will suffer over time."
- "Also conforming to OCP is expensive. It takes development time and money to create the appropriate abstractions. These abstractions also increase the complexity of the software design"
- "We want to limit the application of OCP to changes that are likely"
- "How do we know which changes are likely? We do the appropriate research, we ask the appropriate questions, and we use or experience and common sense. And after all that, we wait until the changes happen!" <- [relates with Yagni, also talking about learning about your domain] "We don't want to load the design with lots of unnecessary abstractions. <- [related with Metz's The Wrong Abstraction] Rather we want to wait until we need the abstraction and then put them in"
- "Fool me once"
- "... we initially write our code expecting it not to change. When a change occurs, we implement the abstractions that protect us from future changes of that kind."
- "If we decide to take the first bullet, it is to our advantage to get the bullets flying early and frequently. We want to know what changes are likely before we are very far down the development path. The longer we wait to find out what kind of changes are likely, the more difficult it will be to create the appropriate abstractions."
- "Therefore, we need to stimulate changes"
- "We write test first" -> "testing is one kind of usage of the system. By writing tests first, we force the system to be testable. Therefore, changes in testability will not surprise us later. We will have built the abstractions that make the system testable. We are likely to find that many of these abstractions will protect us from other kinds of changes later <- [related with Feather's The Deep Synergy Between Testability and Good Design]."
- "We use short development cycles"
- "We develop features before infrastructure and frequently show those features to stake-holders"
- "We develop the most important features first"
- "We release the software early and often"
- "Closure is based on abstraction"
- "Using a data-driven approach to achieve closure"
- "If we must close the derivatives [...] from knowledge of one another, we can use a table-driven approach"
- "The only item that is not closed against [the rule that involves] the various derivatives is the table itself. An that table can be placed in its own module, separated from all the other modules, so that changes to it do not affect any of the other modules"
- "In many ways the OCP is at the heart of OOD."
- "Yet conformance to [OCP] is not achieved by using and OOP language. Nor is it a good idea to apply rampant abstraction to every part of the application. Rather it requires a dedication on the part of the developers to apply abstraction only to those parts of the program that exhibit frequent change."
- "Resisting premature abstraction is as important as abstraction itself <- [related with Metz's The Wrong Abstraction]"
Tuesday, August 22, 2017
In a small piece of code
In a previous post we talked about positional parameters and how they can suffer from Connascence of Position, (CoP). Then we saw how, in some cases, we might introduce named parameters to remove the CoP and transform it into Connascence of Name, (CoN), but always being careful to not hiding cases of Connascence of Meaning, (CoM). In this post we’ll focus on languages that don’t provide named parameters and see different techniquess to remove the CoP.
Let’s see an example of a method suffering of CoP:
In languages without named parameters (the example is written in Java), we can apply a classic[1] refactoring technique, Introduce Parameter Object, that can transform CoP into CoN. In this example, we introduced the ClusteringParameters object:
which eliminates the CoP transforming it into CoN:
In this particular case, all the parameters passed to the function were semantically related, since they all were parameters of the clustering algorithm, but in many other cases all the parameters aren’t related. So, as we saw in our previous post for named parameters, we have to be careful of not accidentally sweeping hidden CoM in the form of data clumps under the rug when we use the Introduce Parameter Object refactoring.
In any case, what it’s clear is that introducing a parameter object produces much less expressive code than introducing named parameters. So how to gain semantics while removing CoP in languages without named parameters?
One answer is using fluent interfaces[2] which is a technique that is much more common than you think. Let’s have a look at the following small piece of code:
This is just a simple test. However, just in this small piece of code, we can find two examples of removing CoP using fluent interfaces and another example that, while not removing CoP, completely removes its impact on expressiveness. Let’s look at them with more detail.
The first example is an application of the builder pattern using a fluent interface[3].
Applying the builder pattern provides a very specific[4] internal DSL that we can use to create a complex object avoiding CoP and also getting an expressiveness comparable or even superior to the one we’d get using named parameters.
In this case we composed two builders, one for the SafetyRange class:
and another for the Alarm class:
Composing builders you can manage to create very complex objects in a maintanable and very expressive way.
Let’s see now the second interesting example in our small piece of code:
This assertion using hamcrest is so simple that the JUnit alternative is much clearer:
but for more than one parameter the JUnit interface starts having problems:
Which one is the expected value and which one is the actual one? We never manage to remember…
Using hamcrest removes that expressiveness problem:
Thanks to the semantics introduced by hamcrest[6], it’s very clear that the first parameter is the actual value and the second parameter is the expected one. The internal DSL defined by hamcrest produces declarative code with high expressiveness. To be clear hamcrest is not removing the CoP, but since there are only two parameters, the degree of CoP is very low[7]. The real problem of the code using the JUnit assertion was its low expressiveness and using hamcrest fixes that.
For us it’s curious to see how, in trying to achieve expressiveness, some assertion libraries that use fluent interfaces have (probably not being aware of it) eliminate CoP as well. See this other example using Jasmine:
Finally, let’s have a look at the last example in our initial small piece of code which is also using a fluent interface:
This is Mockito’s way of defining a stub for a method call. It’s another example of fluent interface which produces highly expressive code and avoids CoP.
Summary.
We started seeing how, in languages that don’t allow named parameters, we can remove CoP by applying the Introduce Parameter Object refactoring and how the resulting code was much less expressive than the one using the Introducing Named Parameters refactoring. Then we saw how we can leverage fluent interfaces to remove CoP while writing highly expressive code, mentioned internal DSLs and showed you how this technique is more common that one can think at first by examining a small piece of code.
References.
Books.
- Refactoring: Improving the Design of Existing Code, Martin Fowler
- Growing Object-Oriented Software Guided by Tests, Nat Pryce and Steve Freeman.
- Refactoring Ruby, Jay Fields, Kent Beck, Martin Fowler, Shane Harvie
Posts.
- Refactoring Ruby: Bad Smells in Code, Jay Fields, Kent Beck, Martin Fowler, Shane Harvie
- Builders vs option maps, Kyle Kingsbury
- Refactoring tests using builder functions in Clojure/ClojureScript, Manuel Rivero
- Remove data structures noise from your tests with builders, Carlos Blé
- Two examples of Connascence of Position, Manuel Rivero, Fran reyes
- About Connascence, Manuel Rivero
Footnotes:
Friday, August 18, 2017
Interesting Talk: "re-frame your ClojureScript applications"
Thursday, August 17, 2017
Interesting Talk: "Testing Stateful and Concurrent Systems Using test.check"
Tuesday, August 15, 2017
Notes on SRP from Agile Principles, Practices and Patterns book
Lately I've been doing some study on object-oriented concepts doing an effort to get closer to the sources. These are the resulting notes on Single Responsibility Principle I've taken from the chapter devoted to it in Robert C. Martin's wonderful Agile Principles, Practices and Patterns in C# book:
- "This principle was described in the work of [Larry Constantine, Ed Yourdon,] Tom DeMarco and Meilir Page-Jones. They called it cohesion, which they defined as the functional relatedness of the elements of a module" <- [!!!]
- "... we modify that meaning a bit and relate cohesion to the forces that cause a module, or a class, to change"
- [SRP definition] -> "A class should have only one reason to change"
- "Why was important to separate [...] responsibilities [...]? The reason is that each responsibility is an axis of change" <- [related with Mateu Adsuara's complexity dimensions]
- "If a class has more than one responsibility the responsibilities become coupled" <- [related with Long Method, Large Class, etc.] <- [It also eliminates the possibility of using composition at every level (functions, classes, modules, etc.)] "Changes to one responsibility may impair or inhibit the class ability to meet the others. This kind of coupling leads to fragile designs" <- [For R. C. Martin, fragility is a design smell, a design is fragile when it's easy to break]
- [Defining what responsibility means]
- "In the context of the SRP, we define a responsibility to be a reason for change"
- "If you can think of more than one motive for changing a class, that class has more than one responsibility. This is sometimes difficult to see"
- "Should [...] responsibilities be separated? That depends on how the application is changing. If the application is not changing in ways that cause the [...] responsibilities to change at different times, there is no need to separate them." <- [applying Beck's Rate of Change principle from Implementation Patterns] "Indeed separating them would smell of needless complexity" <- [Needless Complexity is a design smell for R. C. Martin. It's equivalent to Speculative Generality from Refactoring book]
- "An axis of change is an axis of change only if the changes occur" <- [relate with Speculative Generality and Yagni] "It's not wise to apply SRP, or any other principle if there's no symptom" <- [I think this applies at class and module level, but it's still worth it to always try to apply SRP at method level, as a responsibility identification and learning process]
- "There are often reasons, having to do with the details of hardware and the OS [example with a Modem implementing two interfaces DateChannel and Connection], that force us to couple things that we'd rather not couple. However by separating their interfaces, we [...] decouple[..] the concepts as far as the rest of the application is concerned" <- [Great example of using ISP and DIP to hide complexity to the clients] "We may view [Modem] as a kludge, however, note that all dependencies flow away from it." <- [thanks to DIP] "Nobody needs to depend on this class [Modem]. Nobody except main needs to know it exists" <- [main is the entry point where the application is configured using dependency injection] "Thus we've put the ugly bit behind a fence. It's ugliness need not leak out and pollute the rest of the app"
- "SRP is one of the simplest of the principles but one of the most difficult to get right"
- "Conjoining responsibilities is something that we do naturally"
- "Finding and separating those responsibilities is much of what software design is really about. Indeed the rest of the principles we discuss come back to this issue in one way or another"
Other posts in this series:
Saturday, August 12, 2017
Interesting Talk: "Repl Driven Development"
Monday, July 31, 2017
Two examples of Connascence of Position
As we saw in our previous post about connascence, Connascence of Position (CoP) happens when multiple components must be adjacent or appear in a particular order. CoP is the strongest form of static connascence, as shown in the following figure.
A typical example of CoP appears when we use positional parameters in a method signature because any change in the order of the parameters will force to change all the clients using the method.
The degree of the CoP increases with the number of parameters, being zero when we have only one parameter. This is closely related with the Long Parameters List smell.
In some languages, such as Ruby, Clojure, C#, Python, etc, this can be refactored by introducing named parameters (see Introduce Named Parameter refactoring)[1].
Now changing the order of parameters in the signature of the method won’t force the calls to the method to change, but changing the name of the parameters will. This means that the resulting method no longer presents CoP. Instead, now it presents Connascence of Name, (CoN), which is the weakest form of static connascence, so this refactoring has reduced the overall connascence.
The benefits don’t end there. If we have a look at the calls before and after the refactoring, we can see how the call after introducing named parameters communicates the intent of each parameter much better. Does this mean that we should use named parameters everywhere?
Well, it depends. There’re some trade-offs to consider. Positional parameters produce shorter calls. Using named parameters gives us better code clarity and maintainability than positional parameters, but we lose terseness[2]. On the other hand, when the number of parameters is small, a well chosen method name can make the intent of the positional arguments easy to guess and thus make the use of named parameters redundant.
We should also consider the impact that the degree and locality of each instance of CoP[3] can have on the maintainability and communication of intent of each option. On one hand, the impact on maintainability of using positional parameters is higher for public methods than for private methods (even higher for published public methods)[4]. On the other hand, a similar reasoning might be made about the intent of positional parameters: the positional parameters of a private method in a cohesive class might be much easier to understand than the parameters of a public method of a class a client is using, because in the former case we have much more context to help us understand.
The communication of positional parameters can be improved a lot with the parameter name hinting feature provided by IDEs like IntelliJ. In any case, even though they look like named parameters, they still are positional parameters and have CoP. In this sense, parameter name hinting might end up having a bad effect in your code by reducing the pain of having long parameter lists.
Finally, moving to named parameters can increase the difficulty of applying the most frequent refactoring: renaming. Most IDEs are great renaming positional parameters, but not all are so good renaming named parameters.
A second example.
There are also cases in which blindly using named parameters can make things worse. See the following example:The activate_alarm method presents CoP, so let’s introduce named parameters as in the previous example:
We have eliminated the CoP and now there’s only CoN, right?
In this particular case, the answer would be no. We’re just masking the real problem which was a Connascence of Meaning (CoM) (a.k.a. Connascence of Convention). CoM happens when multiple components must agree on the meaning of specific values[5]. CoM is telling us that there might be a missing concept or abstraction in our domain. The fact that the lower_threshold and higher_threshold only make sense when they go together, (we’re facing a case of data clump), is an implicit meaning or convention on which different methods sharing those parameters must agree, therefore there’s CoM.
We can eliminate the CoM by introducing a new class, Range, to wrap the data clump and reify the missing concept in our domain reducing the CoM to Connascence of Type (CoT)[6]. This refactoring plus the introduction of named parameters leaves with the following code:
This refactoring is way better than only introducing named parameters because it does not only provides a bigger coupling reduction by going down in the scale from from CoP to CoT instead of only from CoP to CoM, but also it introduces more semantics by adding a missing concept (the Range object).
Later we’ll probably detect similarities[7] in the way some functions that receives the new concept are using it and reduce it by moving that behavior into the new concept converting it in a value object. It’s in this sense that we say that value objects attract behavior.
Summary.
We have presented two examples of CoP, a “pure” one and another one that was really hiding a case of CoM. We have related CoP and CoM with known code smells, (Long Parameters List, Data Clump and Primitive Obsession), and introduced refactorings to reduce their coupling and improve their communication of intent. We have also discussed a bit, about when and what we need to consider before applying these refactorings.References.
Talks.
- Connascence, Fran Reyes & Alfredo Casado (slides)
Books.
- Refactoring Ruby: Bad Smells in Code, Jay Fields, Kent Beck, Martin Fowler, Shane Harvie
Posts.
- Ruby 2 Keyword Arguments, Ian C. Anderson
- The problem with code smells, Kevin Rutherford
- A problem with Primitive Obsession, Kevin Rutherford
- About Connascence, Manuel Rivero
Footnotes.
:Friday, July 21, 2017
Interesting Talk: "Coaching Nightmares: Insights We Can Learn from Gordon Ramsay"
Sunday, July 9, 2017
Sunday, July 2, 2017
Kata: LegacySecurityManager in Java
This is the original version of the code (ported from C# to Java):
This is the final version of createUser after a "bit" of refactoring:
which is using the CreatingUser class:
The before and after code is not so interesting as how we got there.
You can also find all the code on GitHub.
Interesting Talk: "Functional architecture. The pits of success"
Friday, June 30, 2017
Interesting Talk: "Theory of Constraints"
Monday, June 26, 2017
Second Open TDD Training in Barcelona (in spanish)
El mes pasado Luis y yo hicimos un curso abierto de TDD en Barcelona. Fue una edición muy interesante en la que probamos algunos cambios en el contenido del curso, y en la que participaron algunos conocidos de la comunidad de Barcelona.
En las últimas ediciones del curso, nos habíamos dado cuenta de que el ejercicio de outside-in TDD, la Bank Kata, que hacíamos el segundo día le estaba resultando muy difícil a los alumnos. En outside-in TDD se usan los dobles de prueba como herramienta de diseño y exploración de interfaces, lo cual resulta muy complicado cuando una persona aún no ha acabado de entenderlos y manejarlos con soltura.
Esta dificultad estaba suponiendo un obstáculo para que acabaran de entender los dobles de prueba. Por ese motivo, decidimos mover el ejercicio de outside-in TDD al principio de un curso más avanzado de TDD que estamos preparando, y hacer otro ejercicio más sencillo en su lugar que les ayudase a asimilar mejor los conceptos.
El nuevo ejercicio que elegimos fue la Coffee Machine Kata. Es una kata muy interesante que ya había probado en un dojo de SCBCN. Creemos que nuestro experimento funcionó bastante bien. Usando esta nueva kata se entiende de forma más gradual y menos traumática cómo y cuándo aplicar cada tipo de doble de prueba. Acabamos muy satisfechos con el resultado de nuestro pequeño experimento y el feedback que recibimos.
Esta edición fue la segunda que hacíamos en lo que va de año, y hubo más gente que en la edición anterior. Esto se debió en gran parte a que vinieron desde Zaragoza cuatro personas que trabajan en Inycom. Muchas gracias por confiar en nosotros.
También nos gustaría darle las gracias a todos los asistentes por su entrega y ganas de aprender. Finalmente, agradecer a Magento, especialmente a Ángel Rojo que nos hayan acogido de nuevo en sus oficinas y toda la ayuda que nos prestaron, y a nuestra compañera Dácil por organizarlo todo.
Publicado originalmente en el blog de Codesai.Friday, June 23, 2017
Testing Om components with cljs-react-test
This is the code of the test:
All the tests follow this structure:
- Setting up the initial state in an atom, app-state. This atom contains the data that will be passed to the control.
- Mounting the Om root on the container. Notice that the combobox is already expanded to save a click.
- Declaring what we expect to receive from the commands-channel using expect-async-message.
- Finally, selecting the option we want from the combobox, and clicking on it.
Interesting Webcast: "CS Education Zoo interviews David Nolen"
Sunday, June 18, 2017
Interesting Talk: "Desorientados a objetos"
Saturday, June 17, 2017
Course: Introduction to CSS3 on Coursera
Sunday, June 4, 2017
Kata: Luhn Test in Clojure
This is a very interesting problem to practice TDD because it isn't so obvious how to test drive a solution through the only function in its public API: valid?.
What we observed during the dojo is that, since the implementation of the Luhn Test is described in so much detail in terms of the s1 and s2 functions (check its description here), it was very tempting for participants to test these two private functions instead of the valid? function.
Another variant of that approach consisted in making those functions public in a different module or class, to avoid feeling "guilty" for testing private functions. Even though in this case, only public functions were tested, these approach produced a solution which has much more elements than needed, i.e. with a poorer design according to the 4 rules of simple design. It also produced tests that are very coupled to implementation details.
In a language with a good REPL, a better and faster approach might have been writing a failing test for the valid? function, and then interactively develop with the REPL s1 and s2 functions. Then combining s1 and s2 would have made the failing test for valid? pass. At the end, we could add some other tests for valid? to gain confidence in the solution.
This mostly REPL-driven approach is fast and produces tests that don't know anything about the implementation details of valid?. However, we need to realize that, it follows the same technique of "testing" (although only interactively) private functions. The huge improvement is that we don't keep these tests and we don't create more elements than needed. However, the weakness of this approach is that it leaves us with less protection against possible regressions. That's why we need to complement it with some tests after the code is written to gain confidence in the solution.
If we use TDD writing tests only for the valid? function, we can avoid creating superfluous elements and create a good protection against regressions at the same time. We only need to choose our test examples wisely.
These are the tests I used to test drive a solution (using Midje):
Notice that I actually needed 7 tests to drive the solution. The last four tests were added to gain confidence in it.
This is the resulting code:
See all the commits here if you want to follow the process. You can find all the code on GitHub.
We can improve this regression test suit by changing some of the tests to make them fail for different reasons:
I think this kata is very interesting for practicing TDD, in particular, to learn how to choose good examples for your tests.
Sunday, May 28, 2017
Interesting Talk: "The Past and Future of Domain-Driven Design"
Wednesday, May 17, 2017
Friday, April 28, 2017
Books I read (January - April 2017)
- Vencidos pero vivos (Vaincus mais vivants), Maximilien Leroy and Loïc Locatelli Kournwsky
- El Boxeador: la verdadera historia de Hertzko Haft (Der Boxer: Die Überlebensgeschichte des Hertzko Haft), Reinhard Kleist
- Vuelo a casa y otras historias (Flying Home and Other Stories), Ralph Ellison
- Rendezvous with Rama, Arthur C. Clarke
- Treasure Island, Robert Louis Stevenson
- Agile Principles, Patterns, and Practices in C#, Robert C. Martin
- Atonement, Ian McEwan
- En una piel de león (In the Skin of a Lion), Michael Ondaatje
February
- El gigante enterrado, Kazuo Ishiguro
- The Time Machine, H.G. Wells
March
- JavaScript Patterns: Build Better Applications with Coding and Design Patterns, Stoyan Stefanov
- Slack: Getting Past Burnout, Busywork, and the Myth of Total Efficiency, Tom DeMarco
- El minotauro global (The Global Minotaur: America, the True Origins of the Financial Crisis and the Future of the World Economy 2nd edition), Yanis Varoufakis
- La sonrisa etrusca, José Luis Sampedro
April
- Howards End, E. M. Forster
- A Wizard of Earthsea, Ursula K. Le Guin
- Las tumbas de Atuan (The Tombs of Atuan), Ursula K. Le Guin
- En tierras bajas (Niederungen), Herta Müller
- How to Love, Thich Nhat Hanh
- La costa más lejana (The Farthest Shore), Ursula K. Le Guin
- Tehanu, Ursula K. Le Guin
- Obliquity: Why our goals are best achieved indirectly, John Kay
- Tales from Earthsea, Ursula K. Le Guin
- The Other Wind, Ursula K. Le Guin
- Metaphors We Live By, George Lakoff and Mark Johnson
Sunday, April 16, 2017
Saturday, April 15, 2017
Interesting Talk: "Freecoin: Complementary currency toolkit"
Wednesday, April 12, 2017
JavaScript Training at Velneo (in spanish)
El pasado 7 y 8 de marzo de 2017 estuvimos Manuel Rivero y yo, impartiendo un curso de JavaScript para la empresa Velneo, en sus oficinas de Gijón. Estuvimos 10 personas tanto de Velneo, como de otras empresas del grupo.
Este post no sería más que una nota de nuestro día a día, si no fuera porque el empujón definitivo para escribirlo vino de una noticia que salió esta semana. VisualMS (el grupo al que pertenece Velneo) fue reconocida como el mejor lugar para trabajar de España, primer premio Best Place to Work 2017, en la categoría de empresas de 50 a 100 empleados.
Y no nos extraña en absoluto, se nota que tienen una relación especial entre ellos, disfrutamos muchísimo ese par de días compartiendo tiempo y espacio con un grupo de personas fantástico.
¿Qué es Velneo? Pues con mis propias palabras. Velneo es un entorno para crear ERPs. Sus clientes son empresas de desarrollo que configuran, adaptan y amplian, el producto para un cliente final. Puede ser una fábrica, una administración o una compañía de seguros. Han visto que su punto más valorado es la comunicación en español y tienen una fuerte presencia tanto en nuestro país, como en Latinoamérica.
Hablando ahora un poco del curso, fue interesante porque hicimos un contenido ajustado a sus necesidades basado en JavaScript ES5. Actualmente el motor que tienen integrado en el producto no soporta ES6, pero no vimos problema, pues en Codesai somos muy fan del patrón módulo o del patrón Function As Object, por ejemplo.
El curso fue una combinación de teoría y práctica en forma de katas usando TDD. Era un equipo que nunca lo había practicado y se notó que lo pasaron en grande, programando en parejas, pensando los ‘baby steps’, y consiguiendo unos verdes preciosos.
La valoración del curso en general fue muy alta (nos pusieron un 9 de media, ¡gracias!), y además nos dieron un feedback muy valioso. A destacar nos comentaron que hubiesen sacado más chicha de las katas si el tema fuera más alineado con su negocio, pues tardaban demasiado en comprender lo que se quería conseguir. Usaremos este conocimiento sabiamente.
Hemos recopilado la bibliografía que usamos para crear el curso y que también sirve para ampliar conocimientos. Está disponible aquí: Bibliografía del curso
También recopilamos todos los ejemplos que usamos en este repositorio de Github.
Gracias a todo el equipo de Velneo por esta gran experiencia y esperamos coincidir pronto en otros proyectos.
Publicado originalmente en el blog de Codesai por Antonio de la Torre.