Process and Challenges of Growing a Team - II
Sun, Feb 4, 2018In the first part of this blog post I wrote our problem about the mentoring to junior developers, results of this problem and a solution we wanted to apply. In this part, I write about the details of our solution, some practices and challenges of the process.
Project Management Methodology
One of the advantages of the project is that this project is a replacement project for an already existing system, and I know the business domain well for this legacy system because a few years ago I had worked in a project that’s one of the clients of this legacy system. We decided to manage our development management process in a scrum like way, indeed our complete methodology more like a derivative of eXtreme Programming because we use most of both management and technical practices from eXtreme Programming, I don’t like to say that we use Scrum or XP directly, because there is lot’s of project and team customization in these methodologies, and there is no standard, so I prefer to say Scrum-like or XP like.
Actually at customer side project life cycle is managed with waterfall model. This life cycle consists of classical phases such as analysis, design, development, test(integration, UAT) and deployment. While analysis phase was continued we started to high-level planning and design sessions and 1 week later we started to first development sprint because we knew well the most important parts of the business domain and there was no need to wait.
Business Oriented Cross-Functional Team
There is no standard team organization approach in the company but mostly teams’ core members(developer, tester, analyst) are cohesive. There are business-capability centric teams and activity oriented teams. Some activity oriented teams are analysis, test, quality assurance etc. I value to business-capability centric teams and expecting every team members aware of the business value that team produces. Ideally, I expect from a business-capability centric team behave as a “think-it, build-it and run-it” teams. They do not depend on other teams for these activities. Our project’s full-time members are business-centric although 2 testers belong another named team, test team. Part-time members such as quality assurance, system configuration management, project management(there are 2 different project management role, this one focus on cost and monitoring) are not business centric members of the project.
The team is crowded with the scope of this project. Maybe, we don’t need half of the team. But the project’s main goal for me isn’t scope, cost or time, so this crowd is a challenge but also a chance to touch more people in terms of growing a professional culture with these people.
Evolutionary Architecture
Most projects start with a design phase after analysis phase and produce a huge class diagram or mostly an ER diagram for all project scope. In this project, we don’t do this. We accept the change at each level such as analysis, design, implementation before project start, so we try to don’t do anything that we believe it’s mostly will change later because any up-front effort will be just a waste. So we don’t do a design for all the project’s scope. Firstly we started with the questions and their answers, such as what is our bounded contexts, how should we model a bounded context, how our bounded context communicate with each other, which technologies we use etc. After this decision, we produced our initial domain model for the first 2 bounded contexts and immediately started to implement these 2 bounded contexts.
Evolutionary architecture means everything continuously changes, therefore you have to have some practices or tools that give you guarantee at some level for nothing is broken, included business functionalities and the architectural decisions such as coupling of bounded contexts or coupling inside a bounded context etc. For these practices, we use automated unit tests, integration tests, e2e tests and code review process.
Applying Some Domain Driven Design Concepts
Most projects use Java as a programming language, but they don’t use object-oriented programming as a programming paradigm, and mostly they don’t aware of this. Anemic Domain Model is a common anti-pattern. I’m not purist about object-oriented programming such as Yegor but I believe there is a huge problem with anemic domain model in terms of clean code, readability, maintainability, coupling, cohesion etc. So we decided to think about our domain model and our design more object-oriented way and give the business power to the domain model, not the services, managers, controllers etc. When using technologies such as Spring and Hibernate, giving power to domain model isn’t easy because Spring doesn’t know Hibernate entities but these entities are also my domain model, you have to use aspects etc.
We inspired from some concepts of the Domain Driven Design book of Eric Evans such as ubiquitous language, bounded context, context map, communication between bounded contexts(shared kernel, customer-supplier etc.), aggregate entity, aggregate entity root, service, repository, entity, value object etc.
Test Driven Development
We decided to use the test-first approach as development(or/and design, test) practice. We try to obey three rules of TDD but we couldn’t achieve this all the time and not for all the members of the team. Our unit and integration test coverage is more than %80 but not all tests are written as a test first approach.
We use Spring and Spring Integration in the project and Spring integration flow tests force to us write more integration tests. To run a Spring integration test you have to wait for loading Spring context, and this is a time-consuming activity, it last about 10-15 seconds, and as the code base growth this duration increases. But to do TDD, tests should run with milliseconds durations.
We try to value our test code like production code because we change lots of things every day and our most important guarantee about the stability of the project after these changes is the unit and integration tests. But it’s not an easy mind shift.
Pair/Mob Programming
At the start of the project most of the development and test team members, especially junior ones, know nothing about our domain, technologies that we’ll use, our design approach, our technical practices like TDD, BDD etc. For this reason, we decided to use Mob Programming practice for the first sprint. In a room, with the all development team members, we started a project from the project template(we used SpringBoot) and first lines of codes. One developer wrote code on a computer, others watched. We rotated developer who written code every 1 or 1.5 hours. This was a stressful activity for the most of our junior developers because most of them didn’t like the feeling that 6 people, especially senior one, watch them while coding. But this was the best activity for me to align the team about my design perspective and how we apply technical practices such as TDD. We used this practice later in the project for 2 times for a week but with less developer rotation.
We decided to start project full-time pair programming. Because this is a new project, most of the team members are junior, most of them don’t know the technologies that we use and I couldn’t control the code base for the 6 developers who write code on his own. Of course, there is some disadvantage of using junior-junior pairs, such as more higher time cost, lower learning from each other etc. We rotate pairs for each sprint, so each week. Some of them like this practice some of them don’t.
A few months later we changed to part-time pairing from full-time pairing, we did this because some team members had complained about the pair fatigue, and also we wanted to observe to our velocity effect(at least for short term). After applying part-time pairing our velocity has increased but I feel more findings appear at code review process.
Code Review Process
We use bitbucket as a code review tool. No one allowed to direct commits to the master branch. Master branch only accepts merge commits from a pull request. Therefore If someone wants to merge a new feature, bugfix or refactoring branch to master, has to open a pull request. This pull request has to be reviewed by at least one person, and if every reviewer accepts the pull request then this pull request can be merged to master branch.
I’m the default reviewer for all pull request, first few months I and the other experienced developer reviewed the pull requests, one week we try to use random team members to review each other pull requests. But later most of the pull requests have reviewed only by me, the main reason for this only cost. With a little experience, I can say that using different reviewers always a good thing, with more clean codes.
Behaviour Driven Development
I used BDD as a practice in another project before. I believe it has benefits as a communication practice. I think most important communication is three amigos(analyst, developer, tester) communication in a development team and BDD try to improve this communication. If you align these three roles before the start of the implementation of a feature, you break the code-test-bugfix loop with a valuable rate, and of course, this has a direct effect to cost of the project.
We used cucumber with the Groovy as a BDD tool, three amigos write BDD scenarios before the start of the implementation of a feature, and then tester write the Groovy codes to make executable these scenarios.
Challenges
The most important challenge of the project is trying to apply many technical practices with a team of mostly from junior developers. I’ve been the only one who teaches these technical and management practices, and I’ve been the only one who tries to control any aspect of the project such as clean code, clean architecture, object-oriented design, our architectural decisions, providing people-oriented processes etc. since the project is started. It’s not possible to do enough work about these activities as a one person. It needs a lot of effort and a lot of patience. Managing many trade-offs and not getting enough participation from the team has been my exact position especially at the start of the project. Of course in the progress of time, many things fit together at a slow rate. We’ve started to speak the same language, we’ve started to understand each other well, we’ve started to understand meaning and reason of the practices we try to apply. Junior developers have started to ask for more responsibilities, it’s clear that expecting everything from me is not a sustainable and professional approach. The most important abilities in here are patience, talk about everything over and over again, strong nerves, to over some disappointments.
Some roles have known well their responsibilities and expectations from them but some roles haven’t been aware of their responsibilities, some roles have been in a chaos about their responsibilities. Maybe, we couldn’t describe well responsibilities of some roles such as analyst, project management. And this has an effect me directly and I have tried to do many activities that should be responsibilities of some other roles.
I have been working closely with developers, they understand my mentality well at most points but other roles still can’t understand my mentality enough and this cause disappointment sometimes when I face a situation that’s completely reverse of my mentality. Some examples; who give the estimation of a work, what’s my role in the project, what’s becoming a team, are we a supportive team or every role has a strict definition of responsibilities etc. Sometimes in some situation, I feel I’m completely alone in this project as a mentality, as an understanding of professionalism, as an understanding of team concept. I can’t find a solution other than telling about my mentality over and over again at every opportunity.
Another challenge of the project is spending lots of time because of the comments getting from my code review. Code review is a costly process, because developer does everything, tester tests, then developer opens a pull request to merge to master, then I check the pull request and write lots of findings, and talk with the developer about my findings, developer fixes these findings and updates the pull request, tester tests, I review again, other findings set, the same loop…This is very tiring activity both for me and developers. We try to fix most things before the pull request, I created a checklist of our mentality, our development methodology, practices, about clean code concepts. etc. Still I’m the only reviewer and still many findings appear at code reviews but we move more quickly because of not much communication is needed for the findings, now my expectations are clear enough for many developers. At code review, I check the source code in terms of clean code concepts, our architectural decisions, business requirements etc. Also try to control many technical aspects manually is a tiring and time-consuming process for me.
Another big challenge, every team member has faced, is patience. Every technical practice we apply, BDD, TDD, pair programming, evolutionary architecture, code review need lots of patience for all the team. Have you ever tried TDD? With the three rules of TDD, in a test-code-refactor loop. It’s not an easy process to get used to. Pair programming, coding with someone, every day, sometimes full time, it’s really tiring activity. And benefits of some of these activities appear well in a long-term, maybe in a maintenance phase. And for a junior developer who hasn’t seen anti-patterns, who hasn’t fixed a legacy code without a test, who hasn’t worked in a project that has many codes smells, understanding benefits of these technical practices getting hard.
Some Solutions
I had to align as a mentality about my software development approach and understanding of professionalism with all team members as soon as possible. And this is possible only with talking about these concepts over and over again and enable the team to practice of these concepts. To speak about these concepts more we’ve started to schedule a 1-hour meeting every week, in these sessions I’ve talked about some concepts we use, such as domain driven design, clean code, refactoring, TDD, BDD etc. We’ve done this activity for 2.5 months. The other project teams also asked about to join this meeting and I’ve scheduled another 1-hour meeting every week to talk about these concepts to junior developers from the other projects.
In a progress of time, I have to give some of my responsibilities to the team, I have to increase their participation in the process every day. To make this shift I talk with them many times, “this is your job”, “everything I decided on my own directly affects your life”, “why don’t you try to control your job?”, “To do this, think about your work, talk about your ideas, your solutions”. A few months later they started to be aware of this much and asked more responsibility for themselves, have involved more to the decision process, such as “We want to work firstly our feature design then we’ll talk you about our design and we can continue to implementation after that”. As a result at every opportunity, I try to involve them to process more and more. Ideally, I expect, at some point when I left the team everything should be continued as before.
One or two months later after project start, I felt that I couldn’t control the project architecture. At code reviews I saw that lots of things went opposite of my expectation, at this point I asked for a one-week break. I wanted to work alone on the project one-week. After one-week I couldn’t finish the refactoring and scheduled another week but this time we worked together, one week we did programming together like mob programming but mostly I coded. After this experience, I decided to visualize our architecture and bounded context’s design to make easy to understand. I drew class diagrams for all our bounded contexts, I explained in a draw how we model the inside a bounded context.
To give regular feedback to the team I decided to schedule one-to-one feedback meetings with every team members, but I couldn’t achieve this for one or more months, then at two retrospective meetings the team asked for it, so I scheduled the first sessions of these one-to-one meetings firstly with developers. In this 30-minute meeting, I asked for their feedbacks, opinions, any complaint, and I talked about my feedbacks, expectations, goals etc. I decided to do this one-to-one meeting once a month.
As a result we progress on the classical stages of team foundation, forming-storming-norming-performing, now I think that we are in a loop at storming-norming-performing, but we are mostly at norming stage, sometimes with a decreasing rate we drop to storming and sometimes with an increasing rate we pass to performing stage.