When people talk about Agile Software Development people will often cite how important having an Agile Mindset is to the success of any Agile project or team. But I’ve never heard a great definition of what an Agile Mindset is. It’s always a mix of personality traits and problem solving goals that no one can seem to precisely describe.
Part of it is clearly an Growth Mindset and that has been well defined and analysed. But it’s more than just that so I’ve been thinking about what that more actually is.
It’s been about 10 years since I got my Agile training from James Grenning and started an Agile Pilot with my team. Right from the start I was super keen and got people practicing TDD and Pair Programming even though I didn’t really know if that effort would pay off. I just knew we had lots of problems with the old way so I wanted to embrace the new.
So I’d run my own little sessions with the broader team in Sydney sharing Agile concepts and ideas. Giving us a chance to discuss things and keep learning long after James had left. But often I would present new ideas and a few people in the group would respond “oh of course, that’s just common sense”. Initially I thought it was great as they were embracing these ideas as valuable even though it was not what we were doing before. But after a while I started to get frustrated because they we’re not really listening. If some small part of a concept fit nicely with their “common sense” then they took that on and ignored the rest.
If you have a career as a software engineer at some point you’ll be asked to diagram a software system. It might be a system you plan to build. It might be to help explain/document a system that has already been built. Or it might be part of an interview question. These days most people seem to have given up on UML and will create a wild mix of arrows, boxes, circles and words. But there’s a lot of other methods that are useful and the best results usually involve a mix. So here are the techniques I’ve found useful in a super quick way.
One of my favourite things to do with software engineers is to practice together. I like it because often we’re not trained to collaborate and it can be a difficult adjustment. If we throw people into collaborative techniques they can struggle as they try to navigate their way through the process while protecting their reputation. I’ve seen teams so nervous about suggesting a “wrong” idea that they will struggle to suggest anything when presented with a trivial problem. So I like to get teams to practice on something that feels a bit like a game.
I first got to experience an Architecture Kata at the Aglie 2018 conference in San Diego. I got to attend a workshop my Martin Salias on Architecture Kata with Tarot Cards. In his workshop we formed into groups of 3-4 and selected a kata exercise from Ted Neward’s Heroku App – we got some kind of medical advice service. We then got 10 minutes to work on our first release. The Katas ask for a lot so you immediately have to consider what to prioritise so you get that real feeling of a sprint plan being executed even though you’re just drawing out a design.
I will also include some warning smells along the way. Things that will give hint your design is not testable.
1. Dependency Injection
This is one of the first things you’ll learn in doing TDD. It doesn’t matter if you’re doing London Style or Chicago Style you will eventually hit cases where you need to swap out the real item. It may be because that real object would touch the file system, a database or a network. Or it may be because it forms a convenient seam between your code and something more complex.
Smell: Singletons and classes that new their dependencies.
In a recent assessment of people applying for graduate and intern positions at my work we wanted a way to quickly assess them as a group. Ideally we wanted to see their individual skill at work, how well they worked with others and all in under an hour for groups of up to five. So I suggested we get them to do some Mob Programming on a Kata exercise. It wasn’t something we tried before but the idea wasn’t completely out of the blue.
My team has a challenge that I haven’t run into before. We all want the code to be better quality that it is now. However we don’t agree on what “better” is.
Even simple things can lead to long discussions and debates so it was a struggle to get some serious progress. Reviews could get bogged down because a refactoring someone did triggered a debate on its merit. We needed a format to allow us to work through some of the fundamentals and find where there was consensus. So I booked us in to do some mob programming together except we were not going to write new code. We were going to focus on only refactoring.
Do you do any of these? Do you see these habits in others. Clean code is when you look at code and think “of course you would do it that way”. It’s simple, elegant, and straight forward. Once you look at it you can’t think of a better way to do it. It seems ‘obvious’ but only with the power of hindsight. But it’s not something you’ll get much of from these programmers
The Hoarder – “I’ll add/leave this function because it may come in useful” litters your code with commented out code and unused functions that rot and bloat your code
Over-Complicator – “I’ve built an xml like nested config value loader to read in my three values instead of using a constant” yeah thanks. And when it turns out to have a bug we’ll spend weeks trying to figure out how it all works and why you wasted company time (and money) writing it.
Rewriter – “This 3D library doesn’t quite fit my needs. I think I’ll write my own and call it DirectY” and you waste weeks on it, it turns out buggy, has very little hardware support but by the time we find out the entire company is building on it and feels committed to keeping it.
Obscurer – “MiscValues init function runs ReadStream to setup the CoreFactory” this is not abstract this is waffle
The Secret Recipe – “Oh it crashed because you have to call unloadAllSettings before you let the class run the deconstructor. But make sure you call close first” so basically no one can use your code without mysterious and random crashes. Thanks for your contribution.
Programming 101 states: Don’t copy and paste code. If you find yourself doing something repetitive then do it right so you can reuse the same code. Functions, classes and even separate files all serve this end.
Now that I’m writing tests all the time I often find myself creating Mocks. Mocks are where you tell code to use a pretend version of some functionality instead of the real one. It could be because the real one does something you don’t want in your tests (writes files, reads a database) or it could be that you’ve got some messy legacy code you can’t to pull into your tests (yet). There’s other reasons too but you get the idea.
So if I make a Mock version of a class it makes sense to try and share that with everyone else that might be trying to test with that same class. Or does it?