Tag Archives: Clean Code

Performance myths and facts

Recently I came across a few performance experts that turned upside down what little I knew about performance. I thought this is boring, this is low-level, this is better left to some crazy assembler gurus, who think microbenchmarking in the middle of the night is pure fun. Turns out I was wrong on many levels and I want to share the most important things I’ve learned as far.

The subject turned out to be surprisingly exciting and at the same time quite challenging, so I’ll keep writing about this as my learning progresses.

Myth #1. Performance is a trade-off between clean design and low-level ugliness

I’ve always thought about “highly optimized C#” as impossible to understand IL tinkering. According to Martin Thompson that approach might be appropriate for maybe 5% code we write. Most of the time we should simply rely on clean design rules such as single responsibility principle, high-cohesion, keeping our functions small, etc. The things that we really should invest in understanding though, are data structures and algorithms, their characteristics and how they are implemented. Understanding how their choice impacts performance is the single most useful thing we can learn. Martin talks a lot about Mechanical Sympathy and it turns out that it’s possible to explain why clean code is faster when we analyze how modern computers work, especially CPUs and GCs. This knowledge is also very useful when deciding what data structures we will use.

A bit different perspective came from Gil Tene, who made me realize how intelligent modern compilers are, especially JIT compilers (that we have both on JVM and .NET). Knowing how advanced compilers are, Gil advises to not waste our time for trying to compete with them. It’s much better to focus on making our code clean, readable and easy to maintain, because compiler will take care of making it optimized anyway (e.g. it’ll remove redundant variables, inline functions, etc.). Most of the simple “optimizations” turn out to be what compiler would do anyway, so it doesn’t make sense to sacrifice readability for this imaginary “performance improvement”. It might seem otherwise though, because in some settings (e.g. in VS by default) JIT compilation is turned off in debug mode. Of course, it’s useful to understand how all this works under the hoods,  because we can realize which of our pseudo-optimizations are a clear waste of time. Besides, sometimes we might hit subtle issues when compiler tries to optimize our code too much.

Myth #2. Performance optimization is a combination of crazy tricks

Both Martin and Gil talk a lot about “behaving nicely”, being predictable, following best practices and understanding the assumptions underlying the platforms and tools we’re using. Lots of super-smart people work on making our tools intelligent, force them to do all the hard low-level work for us, so if we just understand how we’re supposed to use them, we should be allright most of the time. The crazy tricks might be sometimes useful, but unless we work on a real cutting-edge system probably we won’t need them often.

Again, a lot of those assumptions are related to clean design and simple fundamentals, for example:

– Methods inlining – .NET JIT compiler will inline our function if it’s below 32 bytes of IL (short functions!) and is not virtual (be careful with inheritance!) *;

– Garbage collection – in a “well-behaved” application your objects either live very short (0 and 1 generations) or live “forever” (2 generation). Contrary to what many developers believe, you can have lots of GCs and still have great performance, just make sure they’re not full collections (generation 2).

So before I get to those crazy tricks, that I can talk about over a beer to impress other devs, I’ll spend more time learning about .NET, especially with regard to garbage collection and JIT compilation. I’ll pay special attention to what design choices were made, why, what alternatives were dismissed, how all that impacts me and what expectations it sets for my applications (or in other words, what “well-behaved” application really means).

Myth #3. More threads = faster

I was really amazed when I first learned that all LMAX‘s business logic is executed in one thread. Michael Barker and Trisha Gee showed one of the reasons why it was designed this way. I didn’t realize that the cost of locks is that high and even though the specific numbers might be the result of some bug on MacOS (which Michael noted were very impressive), it left me with a lot of food for thought. Maybe the differences are not that high if bug is fixed, but still it’s not really obvious whether adding threads will make my application faster. What is sure though, is that it significantly complicates design, increases maintanance cost and can result in more bugs.

Right now we talk a lot about parallization, using multi-cores to the maximum, microservices… The hype is high and it’s very natural to pay attention to new, shiny silver bullets. However, it’s useful to keep in mind that most of the things done in really cutting-edge systems, are way more than we need in the old good BLOBAs. Chances are we don’t have to be “as good as Netflix”, simply because our system doesn’t need it. We can’t forget that increasing complexity of our solution significantly increases the cost of maintanance, training people, etc.

While most of the world started talking a lot about how much we really, ReAlLy, REALLY need multi-threaded systems to survive in the current market, the amazing team at LMAX used the completely not fancy approach – they focused on their specific requirements, measurements, architecture, data structures, using known patterns in a fresh way and came up with an amazing result. And they process 6 milions transactions per second on a single thread. Not sure about you, but seems that should be more than enough for what we need in the systems I work on at the moment.

Myth #4. First get your application working then uglify optimize

It’s been my experience that performance is treated as an after-thought. We only talk about performance when something bad happens, but not many teams really monitor it on regular basis or are even aware what is needed. Sometimes we have requirements that specify that system should handle specific number of requests per second under whatever load and this is the best I’ve seen as far. But as Gil Tene said many times, even when we have some “requirements”, very often they are either not precise enough, we fall prey to common misconceptions regarding measurement or we simply ignore “all the rest” that is not part of our current requirement (such as 99th percentile).

All performance experts agree that we have to start design with a clear idea what do we need. So it’s virtually impossible to design application without having precise expectations regarding the worst case scenarios and unacceptable behaviours and at least some rough estimates of important numbers (e.g. how many users we might expect, what are their expectations, what would happen if performance would be bad for a few people but most of the time it’s excellent, what metrics matter for us, how will we collect them). It’s also useful to determine at the very beginning what are the real limits and start formulating requirements from there (e.g. network latency, performance of other applications we integrate with, industry “best examples”).

Gil in his presentation noted that without having an understanding of what we really need, we use tools in inappropriate ways and waste time optimizing things that already are good enough or try to optimize them in a completely inappropriate way. Sometimes the good solution might be completely counterintuitive, such as to sacrifice performance, deliberately make it worse in some places, in order to guarantee that our system meets SLAs even in “exceptionally bad” moments. What I understood by that, is that performance is not a binary quality – our system’s performance is not just either good or bad. Moreover, there are no silver bullets and simple answers, what is good for one system and one team, doesn’t have to be good for another. In most cases there’s no one single way to improve performance, there’re plenty of them, each with their own advantages and problems. I need to understand their trade-offs and verify why my system doesn’t perform well. Maybe the problem is in architecture, maybe in data structure, maybe in a language construct, maybe the array doesn’t fit cache, maybe I need to tweak GC settings, introduce pooling for big objects or upgrade hardware. Very often I can solve the problem in multiple ways, each allows me to achieve my goal, but comes with different trade-offs.

All of this sounds very complicated and I think it really is in the beginnig. Just like everything in programming. There’s a lot of conflicting advice, experts disagree or find problems in standard approaches, there’s a lot of jargon or referring to concepts I don’t understand very well.  Last but not least, every system is different and I can’t simply blindly follow somebody’s solution, without first understanding the problem. What is easy is to use a random tool, follow “Getting started” tutorial, without spending too much time trying to understand what I’m actually doing and whether my optimizations are even required. So for me the lesson is that it’s important to know your application, have data regarding expectations and requirements, but also constantly collect information about performance in production and in test environments. That sounds like a lot of work, but without it the best I can do is count on my luck.

I really recommend to see slides from Gil’s presentation, he explains the issue with performance requirements (slides 15-29) and discusses the common problem with measurement tools (slides 30-46).

Myth #5. Microbenchmarks are the most basic tool

I thought that the first thing I should learn about performance are microbenchmarks, how to create them correctly and when they are really useful. But it turns out they’re not that important. This article concerns Java, but summarizes nicely what I’ve read in a few different places.

Seems that although microbenchmarks might be valuable from time to time, it’s way less often than I expected. They are prone to errors due to JIT optimizations (which most likely will be different for production and test environments), hardware differences, unrepresentative inputs, etc. It’s still useful to understand how to construct a meaningful benchmark, but definitely it should be used with caution and only when we’re really sure we need them and nothing else would do.

* Note there’re more rules than I mentioned, but those are most obviously related to clean code recommendations.

Why should you facilitate Code Retreat?

Less than a week ago was another Global Day of Code Retreat. Few thousand people in few hundred cities spend a whole day working on improving their skills. That part doesn’t seem strange anymore, devs are doing such things all the time.

But during after party one of the participants asked me why am I doing it? Why spend a lot of time and effort on something nobody pays you to do? Participants have obvious benefit – they get better developers, they learn. Some openly admit that they treat it as a free training. But what about organizers and facilitators?

That question caught me off guard. I just wanted to organize this Code Reatreat for a while, even since I moved to New Zealand. But why?

1. Teaching (or facilitating) is a great learning tool

Some people think that teacher or trainer or even random CR facilitator has to be an expert and surely knows more than people who are “just” attending the event. That might be true, but more often it is not.

There is a good reason why it is said that if you want to truely learn something you should teach it to somebody else. Facilitators learn a lot during the day. Maybe sometimes even more than participants, because they have more time to observe and analyze approaches of multiple pairs. They see various approaches, compare them, think about them, try to come up with good questions.

We know there is more than one good way to solve a problem, but unless we have a big group of people working on the same task, we don’t realize how different ideas people have. Then we can discuss and compare multiple solutions, see their strenghts and weaknesses. This does not happen often at work, because we don’t give the same tasks to multiple groups.

Being a good facilitator is not easy, you have to practice asking smart questions – those kind of questions that guide, but don’t give away the answer. Also by trying to help people you have to organize your knowledge better. You are deepening your understanding of familiar concepts. You see them in a completely new contexts. You have to explain the same thing over and over, in various ways and by doing so, you discover what really matters, you get to the essence. In short – you deepen and distill your knowledge.

Apart from technical aspects, facilitators also have to learn basics of teaching, such as “crowd control” (make sure one person does not dominate the whole retro, try to encourage shy attendants to speak up), clearly explaining new concepts (might seem trivial unless you actually give it a try), providing encouragement, helping to get “unstuck” when somebody just sits there and stares at the screen, finding the middle ground between people “just doing it” and giving the answers away (also called proper guidance).

2. Moving the industry forward

Contrary to what is told, still too many developers seem to finish their education when they leave university. Some need to keep up to date with newest frameworks and buzzwords, but it still amazes me how many people in our industry never encoutered the basics such as proper testing or working in pairs. This is something we are not taught at the uni and not all companies pracitce it.

At every CR there are some people who never wrote tests or don’t feel comfortable with them (yet). It is really amazing that after just 5-6 sessions they say that it was easier than they expected. They discover the benefit of having more confidence in the implementation and are keen to introduce those concepts at work (or just practice it more diligently).

For some this is the first opportunity to try pair programming. Those people are very excited about the collaborative approach, they feel inspired by seeing in how many ways the same problem might be approached by different people, they discover that when they cooperate, the end result is way better.

Many participants commit to promote those two practices at their workplaces.

3. Bringing companies and communities together

In some cities companies are not eager to cooperate. Sometimes they say that if we work with X, they do not want to have anything to do with us. On the other hand, there are some companies that never got involved in community events, but if you ask them they are very keen to participate. Maybe nobody ever asked them, maybe they simply never thought about it. In such a case that might be the way to get them more involved in other activities as well.

For example one of our current sponsors insisted on booking few spots for people from their company. Now they are very keen to organize similar events. Since a few of their employees attended, they are in a very good position to make it happen.

The other thing I really like about Code Retreats is that they are technology agnostic. You meet people using C#, Java, Ruby, Clojure, Python, Haskell, JavaScript… Sometimes that means you just have a quick exposure to different paradigms and make a few interesting observations, but sometimes it inspires you to learn a completely new thing or become a member of another community group. It definitely broadens your horizons.

4. Spreading hunger

A while ago Steven Jobs gave a really great graduation speech. In it he encouraged people to “stay hungry, stay foolish”. I think this is a great state to live in. Always on the lookout to learn a few new things, to get better, to make world a better place. People do not always are lucky enough to be in a job where they have great role models, but they are very likely to meet fantastic people at event like CR.

Sometimes attending such an event opens up a completely new world for somebody. It turns out to be a first step in a very long journey towards mastery. It might be this tiny event that “awakes a hidden software craftsman within”.

Some time ago somebody inspired me and helped me to make that step. I never looked back. Now I want to give it back and share this experience with as many people as possible. I believe organizing CRs is one of the ways to make it happen.

P.S. If you’re thinking about organizing or facilitating the CR, but don’t know where to start, feel free to ask in comments or on Twitter. I’d be more than happy to help!

DDD Ultra-Lite

Some people say that DDD is heavy and expensive and as such must be used with care. Some teams adopt so called “DDD Lite”, which means they use “tactical patterns”, but don’t do much in terms of strategic design (or in plain English – they use software design patterns described by Eric Evans in the blue bible, but ignore the ideas that are considered truely important).

Truth be told, I’ve never worked on a “real DDD” project (yet!). However, DDD inspired me and I believe it made me a better developer. I used bits and pieces, most of them wouldn’t be recognized as “real DDD practices”, but I remember exactly where the inspiration came from.

I believe that the true value of what Eric Evans wrote years ago lies in the fact that virtually anybody can use some of the things he proposed. They don’t require any special tools, money, approval or reorganization. Those are simple things that you can start doing from next Monday (or tomorrow). I call those ideas “DDD Ultra-Lite”. Some of them are not new, but I believe Evans did a really good job of finding words and metaphors that stick and he certainly provoked a few AHA moments.

So here they are (in random order):

1. Listen to what business is saying

I’m not joking. The advice is probably as old as programming itself, but Evans has an interesting perspective.

He said that if business experts don’t understand your models or think they are awkward, then it means that you have to work more on that. Sometimes business people don’t openly oppose your idea, but you can see that they’re not very enthusiastic about it and that something bothers them, maybe they are confused or maybe they simply say that it doesn’t feel right.

There’s the opposite situation too. Sometimes when you finally find a good model and you communicate your idea to business expert he looks at you as you were the stupidest person in the world. Yeah, you are right, that’s obvious, what took you so long to understand this simple concept? That indicates that you finally got it right.

2. Do just enough design

Both over- and under-engineering are problems. Finding the balance between deep design and just “shipping features” is not a trivial task. Evans gives us a few tips that I found very useful:

  • Use the simplest possible model that allows for solving current problem. Don’t try to model reality, you will fail.
  • Remember about clean code, make your code and design easy to change and improve in the future. If your project is successful then you will change your design many, many, many times. As such, you don’t have to get it perfect first time (and probably even can’t).
  • If code starts getting in the way and you notice that making changes becomes more and more difficult, it might be a sign that your problem has outgrown the current model. Time for re-design of this piece.
  • Redesign small pieces of the system as need arises. Again, strive for the simplest model that solves the new problem.
  • Collaborate. Go for a coffee with a group of devs and/or architects. Discuss your problem with them, brainstorm, sleep it over and go back for another session.
  • Don’t make it heavier than it needs to be. Evans suggests multiple iterations, short discussions (1-1,5h), lots of learning and humility.

3. Ask powerful questions

Sometimes I work on a new feature or modify the existing one and the design starts getting ugly. It was just fine right before this change, but suddenly it becomes very complicated or just looks bad. This is a sign that the design should be changed, nothing special there. However, in Evans book I found a couple of questions that helped me on few occasions: Am I missing some domain concept? Does this change introduce or uses a concept that doesn’t match the existing model?

In other words instead of adding a few more if-s here and extra helper class there, maybe it’s time to revisit the design and find something more robust, more general or simply different. Something that explicitly caters for this new concept that just crashed our beautiful model. This is especially true if you know that there are more upcoming changes in this area or you work on a piece of code that is modified frequently.

4. Don’t reinvent the wheel

Evans encourages seeking external inspiration multiple times in the book. He mentiones browsing through patterns calatogs, to find out whether we can use one of them (possibly with modifications). He encourages investigating how similar problems are solved in other contexts (e.g. in other industries).

What still surprises me is that I haven’t experienced this approach in many places. I know some people look for solutions on the internet, browse through blogs, watch presentations from conferences, but as far I haven’t heard anybody say “I read it in XYZ book”. Usually the “design” sessions I attended were pretty much random brainstorming meetings, few people even prepare for them or know what exactly the problem is (e.g. has numbers describing non-functional requirements). Then months later we come across some random presentation and it turns out that we could have used something else and avoid a few problems.

I know that people talking at conferences and scientists make extensive use of solutions used in other industries. They try to find common issues and adapt solutions to specific needs. However, I think that in “real-life” very often we rely on personal experiences in other industry (e.g. in previous job) rather than extensive research.

The improvement I personally made is to make the “research” phase more organized and extensive and to revisit some “classics”. Blogs and presentations are extremely valuable, don’t get me wrong, but books tend to be better organized and contain more time-proved material. Not to mention that some of the “brilliant” articles are just plain wrong and relying on random Google search for unknown subject is not a good idea. If it’s written by a respected expert that should be all right most of the time. But even experts disagree and don’t always explain their unique context when describing solution.

If I remember something that might be useful I go back to the source of this information to refresh my memory. I try to find related articles, books, presentations or case studies. If I absolutely have no idea where to begin, then there are a few alternatives that proved useful for me: going back to the theory (I’m still surprised how valuable that is), browsing through the catalog (e.g. design or analysis patterns), while focusing on context and problem descriptions or finding a good “domain guide” for IT professionals for a specific industry.

That might sound trivial but I encourage you to really try it “as you meant it”. You might be surprised (I definitely was:)).

It doesn’t work that way in enterprise

This title immediately caught my attention. Due to the recent work-related frustrations, I’m on the constant lookout for how to make things better. Peter Smith’s talk “It doesn’t work like that in enterprise” seemed promising. But to tell the truth, I was dissapointed. I think it’s important to sometimes have a rant or a good laugh, share the painful daily frustrations and simply vent the steam, so there’s a place in this world for Dilberts and Expert Beginners. But I’m a bit worried that while many people agree on what the problems are, there’s not much content when it comes to solutions. Contrary to the popular belief, there are some and at the end of the post I recommend my four favourite resources. Check them out!

I dream about the day when conferences will be full of practical advice and sucess stories about influencing change. I want to hear about tools that I can use in various settings, backed by facts and solid research. After all, change is pretty important in the Agile world. But before we get there, the most popular advice remains, obviously…

Get real, stop whining, just deal with it

“If you’re like most people, you face several influence challenges that have you stumped. For instance, at work you’re fighting an uphill battle. You’ve given your heart and soul to a quality-improvement program, but your best efforts to make quality part of the everyday culture have yielded no improvements whatsoever. None. (…) And you can’t fix any of this. (…)

Fortunately you’ve learned to follow the words of a well-known prayer: Every day you ask for the serenity to accept the things you cannot change, the courage to change the things you can, and the wisdom to know the difference. Somehow that gets you through.

And that’s the problem. It’s everyone’s problem. (…) We tell ourselves that we’re not influencers, and that it’s time to turn our attention to things that are in our control. We seek serenity.” 

(from “Influencer: The New Science of Leading Change”)

It’s hard for me to believe that somewhere in the world are developers that use USB stick as a CVS. I feel sorry for them. So what? Should I lower the bar, stop striving for more and be content with where I am now, just because we use Git? Shouldn’t we, as an industry, strive for more? Learn and share the ways to make things better? Constantly get better as professionals and as people?

It’s not only that I believe in the latter. I just can’t be “reasonable”. When I try, I am miserable. My productivity drops. My life sucks. I’m unhappy. So I gave up on praying for serenity long time ago. It just doesn’t work for me. Serenity might make me come to terms with conditions, that I deep inside never will accept. When I get in my “be reasonable” mode, usually after a few days I’m so miserable, that I inevitably go back to my “let’s change something” mode.

I’ve tried it and it didn’t work

The other common theme are experiences of very smart people, who tried, they did their best and yet, they failed. Let’s be honest, changing the world is hard. Changing the way people work is hard. Influencing organizations is extremely hard. It’s natural that people resist changes, because even change on a personal level is hard.

Most people that attempt influencing changes get discouraged, they become disilusioned and bitter, they give up. Instead of trying to change something, they move on and find a place where there’s no need for constant fights. If you’re in this situation, lucky you, that’s probably the best position to be at.

But those kinds of places are quite uncommon and hard to find, it might take a lot of time before you get there. Sometimes it looks good from the outside, but is less appealing when you’re on the inside. Sometimes the stakes are too high and you simply can’t afford to change jobs. Avoiding less-than-perfect places and people sounds good in theory, but is not that easy to apply in practice and you can never guarantee that “moving to a better place”, wasn’t a mistake after all.

But there’s hope

Next time you see a need for change don’t get angry or discouraged when people resist (yeah, I know it’s easier said than done, believe me:)), don’t take it personally. Accept this reaction as a fact, it’s expected. Instead of fighting, prepare for it. Go to the bookstore or open your favourite browser. But this time don’t laugh at the latest Dilbert strip. Don’t look for consolance and understanding. Look for solutions. Somebody already solved all your problems (and more).

We like to believe that we’re unique. We’re unique as people, our work places are unique, our society is unique, finally, our problems are unique. This is true to some extent, but most “unique” parts don’t matter that much. Common themes in problems with management or motivation or leading change are the same, independent of industry, culture or language. You need to adapt each technique to your specific situation, but you can use it anywhere.

Even if you stick to your “I’m different” argument, I think you will agree that most of our/your problems are not as difficult as taming HIV epidemic in Thailand, getting rid of Guinea worm or resocializing ex-gang members. Yet, all those problems were already solved by somebody, somewhere.

Some people (already) know how to do it

“[Looking for serenity] would be a good tactic were it not for the fact that the problems we’ve listed (…) can be and have been resolved by someone somewhere. That’s right. There are actual people out there who – instead of contually seeking the “wisdom to know the difference” – have sought the wisdom to make a difference. And they’ve found it. They’ve discovered that when it comes to changing the world, what most of us lack is not the courage to change things, but the skill to do so.”

(from “Influencer: The New Science of Leading Change”)

I’ve been on a lookout for practical advice when it comes to change for quite a long time. Most of the material is purely motivational, hard to apply. Here I want to recommend four resources that I find most valuable and practical, I’ve learned a lot from them and every time I go back, I still learn something new. Some tips are very easy to apply, others might take years to master, but as far everything I’ve tried worked and helped me.

#1. “Influencer: The New Science of Leading Change” and other VitalSmarts resources

Those resources are not tied to any specific industry or type of organization. The techniques will work for professional settings as well as dealing with teenagers or issues with a local community.

The most important take-away for me was understanding how many areas we need to take into account, when planning any change (motivation and ability on personal, social and structural level). You can have a quick look at this concept and useful questions at  Influence Change Planner handout. If you focus only on one of the six areas, there’s a high risk that your impact will be too weak to influence a lasting change. Remember, change is hard. We should analyze inhibitors in multiple dimensions and use multiple sources of influence to maximize our odds of success.

A big “AHA!” was for me realizing that sometimes change can be really easy, if we focus on the right area. For example, it doesn’t matter how motivated people are, if there’s a structural obstacle to change. Moreover, most of the time we can attempt change in mutliple ways, but some solutions are more effective/cheaper/easier/faster than others. I vividly remember the example where cooperation problems between chefs and waiters were solved by removing the need for direct communication. All they needed was a metal spindle (read the story “William Whyte ‘s 50 Cent Metal Spindle”).

#2. Jurgen Appelo’s books and Happy Melly project

Jurgen is focusing more on management in the context of IT, but also takes quite broad approach. If nothing else, he’s an excellent aggregator of high-quality resources. I found my #1 resource recommended in one of his books.

I think the most imporant things I’ve learned from Jurgen is that – like it or not – we’re all managers to some extent. We don’t need an official title to be leaders and we all are responsible for how our organizations operate. We can cry and whine, we can deny it or we can learn to use it for our (and other’s) benefit.

I also find very valuable the fact that he fully acknowledges that management and leadership are complicated. He looks for inspiration and solutions in various places, focusing on tools that have some scientific background (especially complexity theory). Here’s very practical, so if you are short on time and hate all those strictly “inspirational” pieces, “Management 3.0” might be your new favourite.

#3.  Esther Derby, Don Gray, Johanna Rothman and Gerald M. Weinberg “Essays on Change Artistry”

I haven’t finished reading that one yet, but I’ve already tried to put into practice one tip. It’s basically impossible to influence change if you enter the group as an “outsider” that always knows better and critizes everything, before even they understand the context and get familiar with the people.

Sometimes it’s very hard to resist the urge to call everbody idiots and just assume that actually, in this situation, we for sure know better. The problem is that even if that’s true, we’ll lose opportunity to share what we know with others. First, we have to take care of the basics. Get to know the group members, get accepted by them, learn about their history and context, make sure that we share the common goals and look for ways to contribute to achieving common goals and priorities.

It sounds so obvious and simple, yet, I don’t know many examples when people really followed this advice. I’ve also realized that I’m not too good at it and since then pay more attention to this area. Even if I can’t wait to share my new super idea, I take a few deep breaths and spend some time learning about the current solution and its context. Sometimes it turns out that my solution wouldn’t fit the constraints that currently are in place. Sometimes it turns out I didn’t understand the problem well, before coming up with a solution.

Well… That was just what I’ve learned from one of thirty essays in this book.

#4. Sandro Mancuso “Software Craftsmanship: Professionalism Pragmatism Pride”

Last but not least, I want to recommend my latest discovery. This is the resource completely focused on software development (obviously:)), but is looking at the subject in very broad terms. Sandro took good care of organizing the content and using phrases that stick. Although I was familiar with most of the concepts even before I read that book, I’ve learned a lot. Some concepts were taken to new depths, others were enriched with new insights and specific tips or new examples.

Two parts of the book, that I found especially valuable were related to recruitment strategy and saying no. Taking responsibility for estimates and project success is a hard topic, controversial. I think that Sandro’s take on this matter is excellent, he skilfully tackled the most common myths and provided tips for dealing with hard situations, that most of us encountered in some form.

Wrap up

Influencing change, be it using new tools, changing processes or modifying communication patterns is a huge, difficult subject. You can pray for serenity, in the end I think that is the easier option. But you can also believe that influencing change is a learnable skill.

If at any point you feel frustrated or simply tired of hearing that “it doesn’t work that way” wherever you are at that moment, open one of those books, watch author’s presentations or read their blogs. You’ll find hope and lots of practical tips, that you can start using straight away.

Even if other people tell you otherwise, remember, there’s nothing wise in giving up. Don’t get discouraged when you fail in your attempts. You will fail one way or another, in one or many of them. That’s a normal learning process. Get up, learn more, practice, adapt and try again. Then share your experiences. I can’t wait to hear about it.

Pair programming – is it worth it?

I was recently tasked with creating a “quality improvement” strategy for one of our projects. One of the controversial propositions turned out to be pair programming. How are we going to justify this cost to the client? That question caught me off guard. I didn’t even think that might be an issue. I didn’t even think about mentioning it to the client, too. For me it’s just a natural part of my work, like using CVS. I never had to justify doing that to anybody. In fact, it used to be quite the opposite.

Stage 1: I hate it

For me personally, pair programming was very challenging. It was the least favourite part of my work. I am a perfectionist (luckily, recovering one) and ever since I can remeber, I hated people looking over my shoulder when I was working on something. Even when I was in primary school and my mum wanted to check how my essay is progressing, I got aggressive. That’s the main reason why I always insisted on not having anybody sit behind my back. I hated the idea of somebody staring at my screen. What if they saw me doing something very dumb?

Over time, I got pretty good at using various avoidance techniques, altering aggression with jokes and plain refusal. Of course, I could got away with this behavior at home, but it wasn’t professional to say the least. Pair programming was not only allowed, but strongly encouraged by my team-lead when I worked at VSoft. I’ve also heard a lot about its benefits. Like it or not, since everybody around me was doing it from time to time (and I couldn’t really say no, every time they wanted to pair on some task), over time I simply got used to it.

Stage 2: I learn a lot

My first “real” pair programming experience was slightly over two years ago and I can’t believe how much has changed. I don’t mind other people looking at my code. I love it. Getting feedback is awesome. I like getting new ideas to improve my code during reviews. I got comfortable with criticism, use it to learn about different approaches and coding preferences. At the same time, I learned to defend my point of view, discuss the motivation behind the decisions I made and be ok with changing my mind, when reviewer points flaws in my thinking.

I can’t recall specific words, I don’t remember all of those small and big ideas I learned through pairing with other people. Some of them applied only to the situation at hand. But there were a few that I benefit from today, such as testing untestable code (thank you Lukasz for being such a pain in the neck about it, now it’s second nature:)), getting familiar with all the crazy shortcuts, learning about new tools, etc. I’m also much better in giving feedback to sb’s code and learned a lot by thinking hard how their code might be improved or why something “didn’t feel quite right”.

Overall, once I got over this irrational “don’t you dare look at my code” attitude, my rate of learning went up significantly. Besides, I think that my productivity was higher, when I worked in a pair, because I was fully focused on a task at had. There was no email checking or talking to colleauges. I did my best not to waste somebody else’s time. Unfortunately, I don’t have any hard data to support that claim.

Stage 3: It’s not a silver bullet

When people ask whether pair-programming is good or not, I think the only honest answer is (of course) “it depends”. There are some people I can’t pair with. When we tried working together it was simply counterproductive, because we just kept arguing and nothing got done. Working with some others was challenging, but I learned a lot. Finally, when working with some people I felt that magical synergy, we were more effective together than each of us working separately, because our working styles and our typical focus areas were complementary.

So it depends to large extent on whom we work with. It’s good to get out of our comfort zone, but I think that pushing through, just for the sake of activity when it’s clearly not working, doesn’t make any sense.

Then it depends on the task at hand. When the task is a no-brainer or we’re very familiar with the area of codebase we’re working on and we’ve done similar tasks before, then pairing might be a waste of time. For me it was most beneficial when I worked on something very new or especially complicated. I could have asked for a review afterwards, but pairing seemed to be more efficient way than stopping every now and then to discuss my idea with a colleague.

Stage 4: It’s hard to work otherwise

There are two situations when pairing seems to be great, irrelevant of other factors. The first is introducing a new person to the project. I can’t understand why people don’t see how wasteful it is to give a vaguely described task to the newbie and instructing them to “ask when they need anything”. Even if they are experienced developers, it takes some time to understand business requirements and be able to understand the impact of every decision on other areas. We lose opportunity to make sure early on that they follow our interal standards and practices. Not to mention the frustration they experience, when they happily announce their task is finished, only to be told that they have to re-do it because of some stupid catch they were unaware of (happened to me recently a few times, extremely frustrating experience).

The other situation is making significant changes or working on some complex piece of logic. It’s beneficial to discuss our design ideas, pay close attention to implementation, make sure we don’t make stupid mistakes, that can be avoided by using second pair of eyes.

For me the main benefits of pair programming are exchange of knowledge between the devs (both domain specific and regarding tools and skills) and avoiding painful surprises during reviews or testing (Oh, how could you miss that edge case? How could you not know about this email I sent to XYZ half a year ago? Why don’t you know about our super-secret document, where all this is described? How can you not know that some external app relies on this file being in that location?).

At this moment, I can’t think about any more efficient and sustainable practice for continuous quality improvement and spreading knowledge among team members.

Stage 5: Back to square one

So how do you justify to your client not doing it? Is there any more efficient way for achieving the goals I’ve just mentioned (improving quality, mentoring, sharing knowledge, avoiding bugs)? Is pairing something one should discuss with the client? Should client be allowed to make such decisions for us?

For me the only honest answer is that I can’t justify not doing it. The other ways for konwledge sharing and keeping high standards that I know, are not as effective (e.g. workshops, presentations). Code reviews should be enough for ordinary tasks in an experienced team, but even for them, I think the two situations mentioned in Stage 4 are still relevant. When it comes to clients I believe that it’s my job to be the best professional I can be and client shouldn’t decide on standards in our industry.

I think this is true not only for software. For example, I don’t go to the dentist and tell him he shouldn’t have an assistant, because I have to pay more for the service. I trust that they do their job well and that this is the best industry practice. I also suppose that if they worked alone, the overall cost would be much higher, they would do the same task longer with more mistakes and caused me more discomfort. Better service for less money? Even if not true in every case, I think this is more common than most people realize.

Legacy Code Retreat

Recently we  (together with Seb) organized a Code Retreat event in our company. It was not the typical event you see during Global Day of Code Retreat, for a few reasons. First of all, it was internal, only people from our company were present. Therefore, the diversity of tools and languages was not as high as usually. Then, it was organized during work hours. Finally, it was a Legacy variant.

What exactly was the point?

Some people might question, whether organizing internal company event of this type makes any sense. After all, one of the fundamental rules of retreats is attending them in your free time, only because you strive to improve your skills, not because your employer requested it. In our case there were a few reasons for choosing that format:

  • We knew there are a few skills that devs from our company needed to improve (refactoring, following simple design rules, writing tests and testable code, etc.). We knew exactly what issues come up in various projects and decided that getting familiar with those basics is the first step towards making our codebase better.
  • We didn’t have any training budget, therefore we couldn’t hope for getting a professional trainer. Even if we did, probably it wouldn’t be worth spending that money for learning the basics we intedned to cover.
  • Many people work long hours, so asking them to do something extra in their free time seemed a bit too much. Even then, getting some people out of a project even for one day turned out to be extremely difficult, so we needed an official, approved event to allow people to spend some time learning.
  • We wanted to provide opportunity for people to practice new skills. Making a presentation, organizing a “Lunch and learn” or anything of that kind, for sure wouldn’t work for us.

What did we do?

  • We’ve got source code for JBrains’ Trivia game from here. We paired with Seb for one hour to get GoldenMaster done, in case some people don’t finish it during first session (proved to be useful:)).
  • We organized a short intro to Git a day earlier (especially useful for short refactorings session).
  • We run sessions, each 45 min., followed by a retrospective and break. Since retros between sessions were very short, not everybody had to answer questions.
  • In the end we asked every person to share what they learned, which session they liked the most and what will change in their work from next Monday.
  • After that we hit the pub for a quick beer:)

How did it go?

We were surprised and very glad when people said how many new things they learned from each other. Without any suggestions on our side, a few people said exactly the things we wanted to address, regarding changes in how they would work from now on. People also got very excited about what they learned, some encountered new tools that their colleagues were using, seems like the event left them hungry for more (which was one of our two main goals).

Of course, work is much harder than what we do during reatreat, in reatreat we don’t have databases, codebase is tiny, we don’t worry about deadlines and pressure from management.  So I’ll follow up on this, want to see whether people managed to implement those new ideas at work and what challenges did they hit.

Detailed description of sessions:

Session 1 : Golden Master – Create a test for the game, changing as little code as possible and covering the largest possible number of cases (challenge – change only one line). Keep the tests and use them in later sessions.

Retrospective questions:

  • How much did you change?
  • How many test cases did you cover?
  • What challenges did you hit? How did you deal with them?

Session 2: “Make the code better” – Using whatever techniques you’re familiar with make the code look better (whatever that means to you)

  • What do you think about this codebase? What problems did you hit?
  • How did you change code (e.g. extracting methods, extracting classes, removing duplicates)?
  •  How many tests did you add?

Session 3: Pure functions – Extract methods that do not have any side effects and state.

Retrospective questions:

  • How many methods did you extract?
  • What methods did you extract?
  • How many tests did you add?

Session 4: Single responsibility principle – Make sure each class has a single responsibility.

Retrospective questions:

  • How many classes did you extract?
  • What classes did you extract?
  • How many tests did you add?

Session 5: Short refactorings – There’s an imposed 3 min. limit for refactoring and covering your change with a test. If you don’t manage to finish before time elapses, revert your changes.

Retrospective questions:

  • How many refactorings did you manage to finish?
  • What did you learn in this exercise?
  • Did you use Resharper and keyboard shortcuts?

Session 6: No mouse or short methods or eliminate conditionals – Pick one of the three tasks (or combine them:)): either do not use mouse or eliminate conditional statements from your code (ifs, switches, loops) or make your methods shorter than x lines.

Retrospective questions:

  • Which task did you choose?
  • How many conditionals did you eliminate?
  • What techniques did you use (popular ones are using dictionaries or modulo function)?
  • How many methods did you add?
  • In the end, how many of your methods were longer than x lines?
  • How many tests did you write?