Lessons learned from 3 years in a single project

Jakub Dzikowski
SoftwareMill Tech Blog
8 min readJun 10, 2019

--

I just finished a 3 years long project in a complex business domain where I was developing a large B2B platform from scratch. I was a member of a team of three developers, however I was the only one who worked in the project from the beginning. That significant amount of time allowed me to observe how the project has been evolving and and taught me insights on best practices in software development process.

Our culture of work

We are a fully remote company and we do not work on-site. Usually we provide small teams of 2–5 people in quite a short to medium term projects of 6–18 months. We get our job done, implement features, improve the performance or code quality of the existing projects. The client is happy and we leave. But there are obviously some projects that take more time.

Since we have small teams with no managers, the developers are responsible for the contact with the client. No bottlenecks, we speak with clients directly. Besides that, we at SoftwareMill, hire only advanced professionals from Poland. (Note: If you worked in the industry for a few years already and you think your expertise is below that level — there is actually a good chance you’re an advanced professional — you know what you don’t know. Socrates would be proud of you.)

Each one of our developers has slightly different technical background, preferences, habits and different career history. However, we have common standards regarding quality of code and software engineering process, that might not be so obvious for developers working in other companies (like CI, testing, pair programming, code reviews etc.).

Because of small teams and highly experienced developers, with no exceptions, we have no pre-set hierarchy in teams. Some of us feel better in particular technology, some of us are better in getting things done, some of us are better with talking with the clients. But, basically, we are more-less equal regarding experience and skills.

All of these results in great autonomy in work process. In a few projects there are some technical stakeholders that impose some practices, nevertheless, in most cases, the decision is ours. In the project I worked in for the last three years we had the full autonomy regarding the software engineering process. Our client required the working software only.

The communication with the client

Clients are often busy. They need the features we implement, but simultaneously they have their own companies, their own businesses to run, what consumes almost all ot their time. There are obviously cases when a client is represented by dedicated Product Owner or by the person who is technically involved in the project. Then the communication is more fluent. However, in my project, we were talking directly with one of the company owners, and he is a really busy person.

Basically, I have three pieces of advice here:

  1. Insist on face to face meetings.
  2. Do, whatever it takes, to have regular meetings.
  3. Adapt. You cannot change everything.

The face to face meeting changes everything. When you work remotely and you have meetings on Skype or Google Hangouts/Meet, your communication is limited. You cannot take advantage of most non-verbal signals, because they are disturbed or hidden by the medium you communicate through. You cannot really feel the other person intentions, recognize real goals and attitude. After face to face meeting you just understand each other better.

Regular meetings are about coordination of software development process. You need to verify that you are going in the right direction on a regular basis. The sooner you will find out some misconceptions, the easier you will fix them.

Since our client was a really busy man, meeting during standard business hours was almost impossible. We had to constantly reschedule and eventually cancel meetings, what led to frustration and gaps in our understanding of the domain and business requirements.

After few weeks we agreed to schedule meetings twice a week at 8:00 PM and it was one of the best project decisions we made. That was it. We had regular meetings. We had regular feedback. We felt that our work was meaningful.

We cannot involve our client in the business analysis to the extent we wanted, but hey, we were senior developers, we were able to handle it. We just gathered the ideas and high-level requirements, formalized them, made some assumptions about the things we were not sure of, but we got it. We adapted. Regular meetings, twice a week, was enough to confront our assumptions with the reality and gather feedback about working features. We were able to carry on.

Source: Know Your Meme

The code quality

Some agile practitioners argue that there are no compromises on code quality. The reality is different. Probably in most cases an enterprise application will require better quality than a startup, when you want to check whether a feature is desired by your customers. As a senior developer you need to know what tradeoffs you can make. You will eventually take some technical debt. You just need to keep low interest rates.

At the end of the day your client pays for the features delivered. You don’t need to build microservices when the monolith is sufficient. You don’t need to test every edge case in Selenium tests. You don’t need sophisticated architectural patterns when the simple solution works.

But that doesn’t mean you don’t care about the code quality. Different domains require different quality. It is OK to have some parts of the code better covered with tests, and test the happy path in the other parts. The crucial thing is to determine when the better quality is required.

But you cannot do it by yourself only. You need a different perspective.

Code review is a must. Internal discussions about the tech and business domain is a must. Pair programming is sometimes useful, however I don’t think it’s crucial.

Those techniques are useful not only in ensuring required code quality, but also in dissemination of knowledge among the team. They build better understanding of the project with all its complexity. They also lead to better coherency in the code and the architecture.

The Conway’s law works, even within such small teams. Everyone has different way of thinking and different coding patterns. It is good to take some actions to unify them. If you don’t, you may end up with chaotic code, duplication and lack of common understanding.

It is very useful to have some kind of automatic code formatting tool (regardless of an IDE). For the backend code we had Scalafmt (and, unfortunately, no linter, like for example WartRemover). We had ESLint with Airbnb rules for the frontend.

Funny thing is that at the beginning, when we introduced Airbnb rules for ESLint, we had about 550 ESLint errors that couldn’t have been fixed automatically. Way too much to fix it manually, we had to deliver business features. Instead we added a linter step in our CI environment what verified that there are no more ESLint errors than 550. We were following the Boy Scout Rule to fix them and constantly decreased the number of allowed errors. After a few months we got rid of over a half of it.

Finally, you need to be careful with the Boy Scout Rule. Don’t over-scout. Your client pays for the working software. You must find a balance.

Working on the tasks

In order to keep your momentum, you need to have constant gratification for your work. You need to have a sense of progress.

During the project I had some tasks that took few weeks. Sometimes, it was a nightmare. I stuck with implementation of a large feature or significant refactoring and I kept doing it day after day with no end in sight.

Too big feature? Poorly defined task? Maybe. But it happens and you need to find a way to handle it.

Checklists are useful. You can do it inside Jira issues, GitHub issues, Trello cards and probably in many other tools. When you feel you loose your focus, have a look at the checklist. Or make one.

Nevertheless, prefer short tasks over long ones. Divide. Work in sprints to have regular evaluation of the work done. From my experience Kanban with sprints was way more efficient than pure Kanban. We just wanted to have a story finished before the end of the sprint. It worked not because we spent more time on the tasks (we didn’t). It worked because of better focus.

There was obviously other techniques from various methodologies that improved our engineering process:

  • Retrospective meetings from time to time (typically every 3–4 months). They are crucial in long projects to keep your attitude fresh and change the things you don’t like. You should end this meetings with action points written down.
  • Planning meeting at the beginning of the sprint (typically every 1–3 weeks). It helps you focus on the project goals and create common understanding of the project.
  • Casual discussions about the tech and the domain. Again, to create common understanding of the project.

All of these meetings and techniques help you focus and follow the right direction, they are useful, but not sufficient. When you work in a project for such a long time, you are susceptible to burnout.

There is a good chance you like your work, your project and the tech stack you use. But those are only feelings. And feelings eventually fade away.

In the long run the routine matters more than the late coding. You need to keep going. Small steps towards the right direction are the key to make constant progress, avoid burnout and keep your private life intact.

Recap

  • Clients are often busy. You should adapt and insist on regular meetings to get to know the client and to get feedback.
  • You cannot make the code perfect, because you don’t have infinite time. However, you need to keep some standards and build common understanding of the code among the team.
  • In the long run the routine matters more than the late coding.

Bonus: Side projects to the rescue

If you work for a long time on a single project you may get bored of the tech stack you use. I had that feeling in many projects.

I think it is important to work on side projects. You don’t need to ship it, you don’t need to spend a lot of time on it. Just do it. It will keep your mind fresh. It will remind you that there is another professional life out there. Not just the project you work on.

--

--