- Think before you start coding: What is it that needs to be implemented? What should the end result look like? Do you know enough details about the use case? What is the benefit for the end user? What do you know about the non-functional requirements? Does similar functionality already exist that you can learn from? If the functionality is big (> 5 days to implement), create a mock-up and discuss it with the product owner. Break down the task down into smaller steps that take 2-4 hours to implement. Arrange the tasks in the correct order, so you have a clear implementation path.
- Identify risks: Do you need to use anything unfamiliar (e.g. a new external library, a complex algorithm, etc)? Ask around to see if another team member has some experiences. In case there is nobody on your team, do a quick research and check the two most promising candidates in more detail (anything useful on Stackoverflow?). Take notes of your decisions.
- Explain the implementation plan to a colleague. Any concerns that require a change of the plan? Is the timeline feasible? Is the functionality worth the estimated effort?
- Start the implementation by thinking about how to test your first step. Usually this results in a unit test. Test-driven development (TDD) has the advantage that you think from a usage perspective and that the implementation becomes easier and clearer to use. And you have a safety net if you do refactorings later.
- Implement until you get the „green light“ of your unit test.
- Check for violations. Any new compiler warnings? Findbugs, Checkstyle, PMD warnings? Any architecture violations? Any metric threshold violations? Is there a critical execution path that is not covered by the test? Does the implementation scale as necessary?
Anything that looks awkward? Any class / method / variable name that does not reveal its true intent? -> Refactor! Anything that looks too complicated? -> Refactor! But try to avoid getting carried away.
- Take a step back and contemplate. Are you still on the right path? Did you learn anything new that changes the rest of your implementation plan? Iterate over the remaining steps of your plan until the implementation is complete.
- Adjust the end user documentation. If you have done step 1, you can re-use a lot of those notes.
- Get feedback. Get a colleague to review the result. Listen carefully to any suggestions and take a break. Sometimes it needs a few minutes for feedback to make sense.
- Present it to the product owner and listen carefully to his feedback, too. Implement the necessary adjustments.
I have worked in a number of projects in the last couple of years, unfortunately I only consider a few of them successful… First of all, what means „successful“?
My definition is: „The project has been completed on time and budget and the customer is happy with the result.“
There are methodic, organizational, technical and social reasons for failures. Here are my 10 favorites:
- Sometimes the success-criteria are not well specified by the customer. That makes it really hard to achieve them…
- Most projects are not off-the-shelf: There are new technologies that need to be mastered, the use cases are not yet clear, the team members have never worked together in the same constellation before. How can you meet deadlines and budget constraints if you don’t have a solid reference for your estimations?
- Complexity: The domain, number of involved systems, hardware, technologies, etc. is hard to understand, manage and control.
- Even with solid planning and a lot of requirements engineering, the customer might figure out half-time that the priorities changed and other use cases need to be implemented. That obviously makes the initial estimations obsolete. It is unlikely that the initial budget will be sufficient.
- Agile methodologies to the rescue? Also short release cycles and quick customer feedback don’t guarantee the correct outcome, if there is no solid roadmap and no frequent adjustment of the goals. I often have the feeling that „agile“ is mis-understood as „no process“, „no planning“, „just coding“. But if done right, it has the same stages as old-school waterfall, just more iterations to align frequently with the customer.
- Project management is no picnic. As a project manager you need good nerves and excellent communication skills to control the egos of the team members. Software engineers are not famous for being socializing experts. Creating a productive atmosphere of joy and energy is essential.
- Software engineers like „toys“ aka new technologies. If there is a new framework that sounds promising, it has to be integrated into the project. Many times, there is no solid evaluation process. If there is no honest answer to the questions „How does the project / product benefits from technology X?“, „What are the other two best alternatives?“, don’t use it.
- Quality is not a defined goal, speed of development has top priority. But if no time is spent to refactor and restructure code, to remove duplication, etc, the speed of development will sooner than later slow down considerably.
- No architecture management resulting in a lack of modularization. If dependencies within the software are not controlled the project will most probably end up in the big ball of mud. If you then discover that a framework is not as promising as it seemed, you cannot easily ditch it, because of all the references to it.
- Bad technical decisions regarding tooling: Wrong IDE, version control system, build management, no wiki to document the goals / terminology / technical decisions / guidelines, etc.
I am Ingmar.
I have been a professional software engineer now for 12 years.
I read this post and thought, it might be a good idea to have my own personal blog about my experiences…
During the web service / SOA hype, I worked with Apache Axis and CXF, JAXB, XML Schema. I touched Complex Event Processing (CEP) during my work for a public funded research project and also worked with JBoss Drools.
Since 2011, I am working for hello2morrow, and we focus on developing tools that help developers and architects to achieve better quality. Sonargraph Architect is a static code analysis tool and can check automatically if the implementation matches the defined target architecture. I extended our SonarQube plugin, created the Jenkins plugin together with a colleague and have been part of the complete re-design resulting in Sonargraph 8.
Sonargraph 8 is an Eclipse RCP app, so I had to learn a lot about Eclipse, SWT and OSGi.
When I am not coding, I present our ideas at conferences (JAX, W-JAX, Jazoon, Devoxx) or different Java User Groups. It is always astonishing, how many people don’t use static code analysis and wonder, why they fall into the complexity trap over and over again. I find it astonishing, because those ideas about modularization, controlling coupling, avoiding cyclic dependencies are 20 years old…