Last week I had the chance to attend an Agile Developer Skills Workshop in Berlin.
The 3 day workshop is, next to a Scrum Master or PO Certification, a prerequisite for the Certified Scrum Developer, short CSD.
I was very excited about the ADS workshop and I found it an intersting approach to hold a workshop which focusses on developers rather than on the management side of scrum. Especially as in my experience all the other scrum workshops mainly concentrate on the rituals, artefacts and organisation of Scrum, without giving answers on how to develop high quality software.
The ADS Workshop concentrates on the 5 cornerstones of agile Development, trying to give an answer on how to build a stable software in an ever changing (agile) environment.
During the 3 days we would start off with a coding kata (in pairs) each morning, followed by a short introduction of one of the main agile developer skills, followed by 2,5 hours of practicing the introduced developer skill in a sprint-like setup. The goal of that setup apparently was for us to practice the development techniques as well as the scrum rituals.
Now let me give you a short summary of the main developer skills which were introduced during the workshop.
Most of the projects nowadays have to deal with requirements that change very quickly. It is important to be able to deliver working software packages at the end of each sprint, so that we are able to get rapid feedback, not only on the quality of our software, but also on the customer acceptance of new features.
Along with that most of the times we have several teams involved in complex software projects, for example the project I am working on right now consists of 7 scrum teams, which requires to minimise the side effects of code changes and bugs.
As the risk and the effort of integrating software in such an environment only at the end of the project would be extremely high, continuous integration is essential for the success of agile software development. This means that every time a code change is completed it is immediately committed, and announced to the other developers.
To avoid conflicts and side effects on other developers or teams, the following steps are required for CI:
- Get the latest version of the code before merging the local changes
- Merge the local changes in to the code
- Run all tests
- Only commit the local changes after you have made sure that all tests are green, and you have the latest version of the software
- After committing the changes make sure the software still runs (integrate and test)
Fortunately we have many high quality tools available, which help us to reduce the effort of continuous integration significantly.
Unfortunately apart from Git as a distributed version/source control system and gradle (a build automation tool) those tools were not introduced during the workshop, which was a little surprising to me considering that the general setup suggested that it was aimed towards developers who have only few agile developer experience, who could highly benefit from those tools.
Anyhow for those of you who have further interest in those topics I can recommend the following blog posts and talks:
- One Click Deployment with Jenkins
- Improving your workflows and awareness in the team with tools
- test first: Before starting to write new code, add a test first
- run all tests and see if the new one fails: Thus making sure that the test has some value and does need new code to pass
- write some code: Write some (simple) code that will make the test pass
- rerun the tests: Now it should be green
- refactor the code: At this point we can clean up our code, remove any duplication and make it more elegant, without changing the behaviour of the codes (can be guaranteed by rerunning the test)
- repeat: Write a new test and repeat the circle in order to push forward the functionality
- Obvious implementation
- Fake it, t’il you make it
- Duplicated Code, increases the cost of changes and is more prone to defects
- Long Methods, large classes
- Comments, whenever you have to comment your code in order to be understandable,
it is a sign that refactoring is needed
- Divergent Change, meaning that one class is commonly changed for different reasons. In this case probably Two Objects would be the better solution
- Shotgun Surgery, the opposite of divergent change, meaning that for small changes you have to adept code in various classes
- Feature Envy, when it seams that a method is more interested in another object rather than the class it belongs to, e.g. if a method invokes many getting methods on other objects
- Single responsibility principle – One Object should only have a single responsibility
- Open/closed principle – Software entities should be open for extension, but closed for modification (correlates with divergent change)
- Liskov substitution principle – Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program
- Interface segregation principle – Many client-specific interfaces are better than one general purpose interface
- Dependency inversion principle – Depend upon abstractions. Do not depend upon concretions
- KISS – Keep it Simple, Stupid!
- DRY – Don‘t repeat yourself.
- Continuous Integration: Improving Software Quality and Reducing Risk – Paul M. Duvall & Steve Matyas & Andrew Glover
- Lean Architecture: For Agile Software Development – Dean Leffingwell
- Lean-Agile Acceptance Test-Driven Development: Better Software Through Collaboration – Ken Pugh
- Refactoring: Improving the Design of Existing Code – Martin Fowler & Kent Beck & John Brant & William Opdyke & Don Roberts
- BDD mit Behat – Alberto Assmann
Working as an efficient team is essential for Scrum and agile software development, and you can actually discover that two of the four main principles of the agile manifesto deal with collaboration:
Individuals and interactions over processes and tools
Customer collaboration over contract negotiation
I can‘t stress the importance of customer collaboration enough, but the ADS Workshop did not give any answers on this topic so for this post I will confine myself to the collaboration within a scrum team.
So why is collaboration such an important issue when it comes to successful software projects? As I mentioned before software projects become ever more complex, and we often have a huge number of people involved in such projects. In my experience one of the main reasons for software projects to fail (or be delayed) is poor communication and collaboration, not only within a scrum team, but also between developers and customers.
I guess there are not many industrial sectors that consist of so many strong willed individuals as the IT sector. And as team work only gained popularity in the last couple years we often find our self surrounded with colleagues to whom it is more natural to work on their own and who are used to being in total control of there daily work, without having to collaborate with anyone. You might be surprised how many developers who have never had (the chance) to work in a team, being the lone star in their company, are still out there.
So is it really a good idea to focus so much on team work in a sector which is, let‘s say, not known for its social competence?
It definitely is! There are many good reasons to focus on the team rather than on the individuals, not the least of which are reliability and scalability.
I had the chance to interview several developers, and I noticed more than once that often applicants with years and years of developer experience, but working on there own, didn‘t perform as good as developers who worked in a team for only a couple of years. For me it is obvious that the knowhow transfer which is achieved in good teams is most valuable and in the long run every project benefits more from a good performing team than from high performing (and mostly overworked) individuals.
Scrum has several tools and rituals which are meant to improve the collaboration within a team like Daily Scrum Meetings, reviews, retrospectives and collective code owner ship. The ADS workshop mainly focussed on pair programming.
Pair programming means that all the work like testing, coding, design and architectural decisions is done by two developers who sit side by side at one computer. The benefits being better code quality, less defects, less staffing risk and better technical skills, amongst other things.
During the ADS Workshop we had the chance to do a lot of pair programming, changing pairs and learning from each others skills. I appreciated this experience very much, as in my daily work we only seldom use pair programming for knowhow transfer and huge problems.
But I have to admit that it was very exhausting at times, especially when two of those strong willed individuals worked together :) So I guess we won‘t introduce pair programming as default methodology, but we are actually using this method more often since the workshop.
Test Driven Development
As we already learned when talking about Continuos Integration, tests are vital for our software quality. Without a good test coverage costs of changes, new features and refactoring will explode within a project’s life span. In addition agile software development does not only propagate a complete test coverage of your software but also suggests to write your tests upfront.
In detail this means that in order to develop test driven you:
Next to the complete code coverage and therefore the higher trust in the code itself, the benefit of using TDD is that it can lead to more modularised and extensible code, which will reduce the cost of new features in the future.
As an approach to implement TDD the following methods were introduced during the ADS workshop:
While I would never challenge the importance of full test coverage, I have to admit that using the strict TDD approach during the workshop felt too fabricated and overly complicated most of the time. Part of this was definitely owed to the simple code examples we used, so I can see the benefit of using TDD for complex code, but personally will not be using it when solving trivial problems.
I mentioned the need to refactor your code several times in this post, and I am sure most of you have refactored lots of code, but it still seems that a lot of developers do not fully understand the meaning. So I want to give you at least a short overview of the true nature of refactoring.
Martin Fowler describes Refactoring as followed:
Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure. It is a disciplined way to clean up code that minimizes the chances of introducing bugs. In essence when you refactor you are improving the design of the code after it has been written
Another important thing you should know about refactoring, and which was stressed in the workshop as well, is that it is not a one night stand but rather a life long relationship, meaning that you do not only refactor your code once, but constantly.
Furthermore something which Martin Fowler doesn‘t mention in his quote is that you do not only refactor bad code and code smells, but also high quality code when the requirements change in a way that makes it impossible to implement them without either refactoring old code or writing bad code.
You can summarise that you should constantly refactor your code in order to increase the quality and lower the cost of existing programs.
The ADS workshop introduced some of the common code smells which cry for refactoring:
During the workshop we didn’t get much further information on how to actually refactor source code in a good way, except from the strong advice that the tests shouldn‘t fail after refactoring. For those of you who are interested in this topic, there are many recommendable books out there on refactoring code, and on how to deal with legacy code, some of which are listed at the end of this post.
Architecture And Design
At first glance it seems hard to fit architecture and design in an agile and iterative process like Scrum. But this of course is not the fact, good architecture and design is as vital in agile development as it is in common software development.
The only difference is that the architecture of our software is not something which is statically implemented upfront and never changes, but rather a vision of our architecture that evolves as the project proceeds.
We are used to have software architects which will fix the design and architecture of a software before the actual development starts. This of course can‘t work in an agile environment. Instead a good approach is to have the architect knowledge within the team, and let the design emerge from within the team through design sessions and constant refactoring.
Good design in an agile world should be as simple as possible and easy to understand.
According to the ADS Workshop the following principles should be satisfied:
In summary I have to say that the workshop addressed less scrum experienced developers, making it for those of us who have been practicing scrum for a while now quite dull at times. But I still liked the idea and after all there were a few things I learned, not the least of which were about my own personality.
For one thing it was interesting to see how even in a workshop with fake stories and sprints we were taken over by something that has to be described as feature panic when we realised that during the sprint planning we didn‘t take the time pair programming and TDD would cost into account. I have to say I was both shocked and surprised how even in such an artificial scrum environment the open tasks at the end of a sprint would make me feel uneasy, giving me a very hard time to fight the urge to disregard the teaching points and finishing the tasks instead.
Since I had my share of „Kamikaze“ projects with last minute feature requests, late hours and weekend work in the past, I thought I came a long way, having realised that last minute refactoring never pays off, considering the technical depts and defects in the long run. But I guess I haven‘t evolved as much as I‘d liked to, so this is definitely something that gave me a lot to think about and which itself made the workshop worth attending for me.
I also liked the coding katas and the chance to practise pair programming with developers that I haven‘t worked with (at least that close) before, this definitely was a good opportunity to learn from each other’s skills.
After all I can say that I am grateful for the experience, but regardless wouldn‘t recommend the workshop for experienced scrum developers (at least if you don‘t have a specific need for the certificate) as there was hardly any new knowledge to be gained.