Should we write stupid code that is easy to understand for newcomers? It seems as a good thing to do. But it is the wrong thing to optimise for because it is a rare case. Most of the time you will be working with people experienced in the code base. And if there is a new member, you should not just throw her into the water and expect her to learn and understand everything on her own. It is better to optimise for the common case, i.e. people that are up to speed. It is thus OK to expect and require that the developers have certain domain and technical knowledge. And spend resources to ensure that is the case with new members. Simply put, you should not dumb down your code to match the common knowledge but elevate new team mates to the baseline that you defined for your product (based on your domain, the expected level of experience and dedication etc.).
Posts Tagged ‘opinion’
Posted by Jakub Holý on March 6, 2016
Posted by Jakub Holý on March 4, 2016
Defensive programming suggests that we should add various checks to our code to ensure the presence and proper shape and type of data. But there is one important rule – only add a check if you know that thing can really happen. Don’t add random checks just to be sure – because you are misleading the next developer.
The Are No Silver Bullets: Which Error Handling Style to Pick For a Given Configuration of Constraints?
Posted by Jakub Holý on February 18, 2015
Kent Beck in his Patterns Enhance Craft Step 3: A Few Good Solutions highlights an important fact about software development:
We encounter repeating configurations of forces/constraints that have only a handful of “solution families” and the optimal solution(s) depend on the relative weights of these constraints.
For example when deciding what error handling style we should choose when calling an unreliable rutine:
Depending on whether readability, reliability, automated analysis, performance, or future maintenance are most important you could reasonably choose any one of:
- Return value plus errno
- Exceptional value (e.g. Haskell’s Maybe)
- Success and failure callbacks
So there is no single perfect error handling style to rule them all.
Kent further explains that the forces shaping most design decisions are generated internal to the process of design, not by external constraints: whether we’re building a barn or an airport, the list of forces influencing the roofing decision is the same – snow, wind, etc. – but their relative strengths may be different. Internal forces in SW development include use of the same bits of logic repeatedly, code made for/by people, etc.. F.ex. the forces influencing naming a variable do not depend on what SW we are building but on its purpose, lifetime, etc. We encounter some configurations of these constraints again and again and a catalogue of design patterns representing the “solution families” mentioned above can guide us towards the most suitable solution for given weights.
When designing a solution, it is helpful to think in terms of these forces and their relative strengths. There is no single superior solution (a.k.a. silver bullet) as different configurations of forces and their weights might be best suited by radically different solutions. Keeping this on our minds might prevent design discussions from dengenerating into an argument.
Posted by Jakub Holý on January 26, 2015
James O. Coplien has written in 2014 the thought-provoking essay Why Most Unit Testing is Waste and further elaborates the topic in his Segue. I love testing but I also value challenging my views to expand my understanding so it was a valuable read. When encountering something so controversial, it’s crucial to set aside one’s emotions and opinions and ask: “Provided that it is true, what in my world view might need questioning and updating?” Judge for yourself how well have I have managed it. (Note: This post is not intended as a full and impartial summary of his writing but rather a overveiw of what I may learn from it.)
Perhaps the most important lesson is this: Don’t blindly accept fads, myths, authorities and “established truths.” Question everything, collect experience, judge for yourself. As J. Coplien himself writes:
Be skeptical of yourself: measure, prove, retry. Be skeptical of me for heaven’s sake.
I am currently fond of unit testing so my mission is now to critically confront Coplien’s ideas and my own preconceptions with practical experience on my next projects.
I would suggest that the main thing you take away isn’t “minimize unit testing” but rather “value thinking, focus on system testing, employ code reviews and other QA measures.”
I’ll list my main take-aways first and go into detail later on:
Read the rest of this entry »
Posted by Jakub Holý on January 10, 2015
Are you tired of days spent in front of the screen, with no results to show? Have you once again engaged in yak shaving? Today, after having failed previously, I have finally managed to solve a problem while avoiding this trap by following rigorously two guidelines preached by grandmaster programmers. Be warned: Following this approach, you will get a working solution – but you won’t like it. It will be ugly, stained by compromises, far from the elegant solution you wish for. But if your resources are limited and you want to avoid death by too many yaks, this is your only option. But first, what are these guidelines?
One: Maintain a laser-sharp focus. A great programmer is constantly aware of what she is trying to achieve and never strays far from it. If the path leads away, she backs up. If something else pops up, she writes it down for later and gets back to the job. This is essentially about deciding what not to do. (Many thanks to Kent Beck for sharing his focus secret!)
Posted by Jakub Holý on November 10, 2014
A post for those who want to see what an iterative, MVP-driven development of a feature looks like.
@lukew: Start with the simplest version you can. It’s much easier to add complexity than to remove it.
Once upon time, there was a webshop portal with hundreds of partner webshops displayed on the front page. Potential users wanted to find out if their favorite webshops or a particular type of goods were available, existing users wanted to find a shop quickly. Therefore it was decided to implement search. But how to do that?
Posted by Jakub Holý on March 17, 2014
A post about development practices, speed, and frustration.
My wife has mentioned that she likes my passion for doing things right in software development. That made me thinking, why do I actually care so much and do not just enjoy the coding itself? It boils down to that I am not happy until my code is in production. Seeking the satisfaction of having my code used by and helping people while trying to eliminate all unnecessary mental drain is behind all the practices that I embrace and evangelize. It’s a drug I like to take often, in small doses.
practices = f(max(delivered value), min(mental energy))
So how does this relate to DevOps, Continuous Delivery, testing, single-piece-flow, Lean Startup, Clojure? It is simple.
Posted by Jakub Holý on February 23, 2014
The most important lesson I have learned in 2013 is that I won’t change anything by writing critical blog posts and talking to like-minded people. Fostering the “we vs. them,” we who are right vs. them idiots sentiment is ineffective, even destructive. To be able to achieve anything, I have to talk to the people with opposite opinions and understand them. They are rarely ***holes and typically have good reasons for their opinions. Only by understanding those reasons and the background, history, and emotions they stem from – and hopefully helping the “opponents” understand some of my reasons and context – we can find a common ground and common goals that we can build upon to go further – perhaps not in harmony but still together rather than against each other.
Talking to people is difficult. Having my dearly hold beliefs exposed to discussion and criticism is painful. Trying to find a common ground with people with totally different needs, experiences, and ideas about the best way to do software development in a particular context is challenging. But only by doing so, and by being open to changing my own stance, I can hope to influence the stance of other “stakeholders” and thus bring a positive change to a project or organization.
Side note: It’s funny that the more I learn about IT the more I realize that the main challenges and solutions we encounter are not about technology, but about the fundamentally human in us. Also the approach advocated here – seeking understanding and respect in spite of disagreement instead of the radically adversarial “we vs. them” thinking – is crucial not just for IT, but also for building a better society. So far it unfortunately seems that politicians – especially in the US but not just there – tend to prefer the wrong approach. And also the willingness to expose one’s beliefs to discussion and the openness to change are important not only for talking to people, but for being able to keep developing mentally and spiritually, as put so well by M. Scott Peck in The Road Less Traveled.
I’d like to thank to Markus Krüger for showing me the power of talking to people and to Marshall B. Rosenberg’s Nonviolent Communication: A Language of Life for being so inspirational on this path.
You might enjoy also other posts on effective development.
Posted by Jakub Holý on February 17, 2014
If you ever need to persuade management why it might be better to deploy a larger change in multiple stages and push it to customers gradually, read on.
A deployment of many changes is risky. We want therefore to deploy them in a way which minimizes the risk of harm to our customers and our companies. The deployment can be done either in an all-at-once (also known as big-bang) way or a gradual way. We will argue here for the more gradual (“stepwise”) approach.
Big-bang or stepwise deployment?
A big-bang deployment seems to be the natural thing to do: the full solution is developed and tested and then replaces the current system at once. However, it has two crucial flaws.
Posted by Jakub Holý on December 31, 2013
Do we not think enough when coding? Do we jump to the first solution without really considering the problem, without trying to analyze and decompose it and understand the components and orthogonal forces invovled? Is that the cause of bad code (together with time press) and the reason why we typically see a “patchvolution” rather than evolution (of design)?
For example I want a certain item on my list shown grayed out because it has been marked for removal or is currently being edited and I therefore add a flag called isDisabled. But if I really thought about it, I would likely call it based on the purpose rather than display, e.g. isBeing Edited. And I have often observed that I/we tend to jump to the first acceptable solution without trying to consider other, (radically) different and perhaps better alternatives. That is easily explained with our inborn intelectual laziness and we certainly can agree that we should not overthink things and that we need to ship but still, shouldn’t we try to think a little more?
The Clojure community has been very inspiring for me in this regard. There is a strong focus on spending more time on the problem than the solution to really understand it, and on separating the different concerns involved and adressing them separately, as well as on achieving simplicity. One of the manifestation is the strong preference of small, focused, composable libraries over frameworks. F.ex. it took couple of years for Clojure to get support for named arguments – but the result – destructuring – is something much more powerful, that now pervades the whole languages (of course, this is a language, not an app). When you listen to Rich Hickey talking f.ex. about core.async (vs. actors, Reactive Extensions etc.) you see that the man thought deeply about the problem, alternatives, and their pros and cons.
May be we should spend little more time with our problems before jumping to solutions, no matter how much we like to solve things. Perhaps we would end up with a much better code than we typically have, and thus considerably lower maintenance costs.
You might enjoy also other posts on effective development.