The Importance of Having a Healthy Chapter

At Skroutz, every product engineer belongs both to a product team and a chapter. A product team contains people from all crafts and is responsible in delivering new features to our users. A chapter on the other hand contains only engineers of a certain craft and is responsible for all technical aspects of a project.

The mobile team has two chapters. One for Android engineers and one for iOS. Both chapters have weekly meetings where we inform each other on what we are doing and discuss ways to move our codebase and project forward.

As you can probably guess, for a big project like this, a meeting once a week is not enough to keep it scalable, maintainable and up to date. This is a constant effort which requires organization and most of all good communication. This is were a healthy chapter shines. This is what our Android chapter is!

The example

In a recent PR I noticed that we keep using the following convention:

class CampaignTracking(
  val tag: String,
  val trackableActions: List<ActionType>
) : RootObject {

  fun shouldTrackClick(): Boolean = trackableActions.contains(ActionType.CLICK)
  fun shouldTrackImpression(): Boolean = trackableActions.contains(ActionType.IMPRESSION)
}

where we add a helper method for each supported enum.

This, in my opinion, violates the open close principle since every change in the ActionType will require a change in CampaignTracking too. The thing is that because I feel comfortable with the team I am in I didn’t just thought of it, I shared my thoughts in our slack channel. The main argument for having the convention was readability so I even argued that, in Kotlin, something like this

if (TrackableActionType.IMPRESSION in campaign.trackableActions) {
...
}

is readable too!

Soon after my comment a discussion started where a colleague suggested a simple and elegant solution:

class CampaignTracking(
  val tag: String,
  val trackableActions: List<ActionType>
) : RootObject {

  fun isActionTracked(type: ActionType): Boolean = trackableActions.contains(type)
}

which fixes both the initial problem and the one that I introduced by removing the methods all together.

You see, by having a method like isActionTracked we hide implementation details like the fact that we use a list for trackable actions. Exposing something like this makes the code hard to change/scale.

This example might seem trivial and the solution simple but imagine having lots of these small changes every day. The project will self heal in no time! And all that because we, as a chapter, are not afraid of suggesting things.

A healthy chapter

In a healthy chapter every member is trusted, is not afraid to ask questions, can express an opinion and, above all, listens to the other team members. In such an environment ego comes last and knowledge/information flows through the team ending up in having all decisions shaped and accepted by everyone.

The fact that we are such a team has helped in applying certain practises that allow the project, and us, to grow both in a day to day base and in a long term:

Day to day

Having a group of talented and capable engineers is not enough if they don’t communicate.

This is why we have adopted two rules in our chapter:

  1. Don’t remain stuck for more than a couple of hours, ask! The project is big and chances are that the problem you are facing has already been solved so, ask! Someone will either point you to the proper file or will search / pair with you and help you solve it. At the end of the day, the team can be an excellent rubber duck. Try forming the question and an answer might pop up on its own!

  2. If you feel that you want to challenge a decision, do it! As we saw from the example above both the project and the team will benefit from it.

Long term

Our project is old and the codebase big so for keeping it up to date we need to have a plan and make small steps through a long period of time. This is why we have a board where we add, discuss and monitor our long running tasks.

Tasks that aim to help the project move forward but cannot be resolved by one person or in one “sprint”. Tasks like the migration from Java to Kotlin, the migration from callbacks to coroutines, moving from the deprecated onActivityResult to something that suits our needs (spoiler: we ended up creating a tiny library for that) and many more.

The process has four steps:

  • Every new idea and suggestion is added in an inbox. Nothing detailed. Just a small description like “Usage of Hilt” or “Introduction of Jetpack Compose”.
  • If there is someone that wants to investigate the proposed task she assigns the task on her and delivers a proof of concept to the chapter.
  • With the POC in hand the chapter discusses if its worth moving forward or not.
  • If the suggestion gets accepted we fine grain the proposed change and extract a detailed action plan.

A simple process for sure but it can work effectively only when having a healthy team:

  • No fear for criticism ends up in having these ideas and suggestions
  • Feeling trusted ends up in stepping up and taking the initiative to do the investigation and propose a solution
  • Expressing freely our opinions ends up in having solid and structured plans

The mobile apps have changed a lot during the last couple of years and managed to close the gap with mobile web offering to our users a great and complete experience. All that, while still maintaining a proper codebase, wouldn’t be possible if the chapter didn’t have such professional engineers that love their craft.

Stay tuned, more to come!

feature image: unsplash