As an individual developer working on a personal project, you tend to have a very clear vision and understanding of what you’re working on but the moment another developer joins, everything changes. You are suddenly faced with the challenge of making sure that this new developer understands as much as you do and that they get the whole picture.
Non-trivial projects are built by teams and the challenge of ensuring that everyone on the team understands the vision and goals of the project is what shared understanding is all about. You can also refer to shared understanding as the “why”, “what” and “how” of a project.
What is Shared Understanding
In a paper title “Shared Understanding within Military Coalitions: A Definition and Review of Research Challenges” by Paul R. Smart et al. defines shared understanding as:
“Shared understanding is commonly seen as essential to the success of coalition operations. Anecdotal reports suggest that shared understanding enables coalition forces to coordinate their efforts in respect of mission goals, and shortfalls in shared understanding are frequently cited as the reason for poor coalition performance”
Though the definition above talks about military operations it generally relates to any kind of team operation. Software teams also have “coalition operations” (software development activities), “mission goals” (e.g. release version 1.0) and “shortfalls in shared understanding” lead to “poor coalition performance” (in other words, frequent re-work, failed projects).
Why Shared Understanding is Important to Software Teams & Barriers to Achieving it
A team is made up of several people that share a common goal. Failure to buy into this common goal, whatever it may be, leads to failure in the achievement of the goal. This is why having a shared understanding across the team is very important to software teams or any type of team for that matter.
Achieving shared understanding across a team may sound simple and straight forward but in practice it is a lot harder to achieve. Here are some reasons:
Differences in the backgrounds of team members and the level of exposure to the domain for which a problem is being solved significantly influences the shared understanding of the team. Another thing which is closely related to this is the assumptions that people make about certain things when building a mental model of a problem or a solution.
A Constantly Shifting Context
I doubt there is any industry in which the context changes so frequently as with software development. In other engineering practices the context defined at the start relatively remains unchanged throughout the lifetime of a project. A building project to erect a 3-bedroom duplex hardly ever changes into building a 3 storey structure.
In software development though, the context of a project may change as frequently as weekly or even daily. This is the reason why the waterfall approach to software development often fails because unlike other fields of engineering, you may start out building a photo sharing app but pivot and end up building an artificial-intelligence-based-plant-disease-detecting app. The challenge here is that the shared understanding of the team about the context of the project has to evolve at the same rate for everyone including other stakeholders, which is easier said than done.
When working alone, the lone developer is the client, product owner, architect, business/system analyst, UI/UX designer, scrum master, cross-functional developer, tester, technical writer and project sponsor all in one. It can literally take seconds from when a new feature is imagined to when the first UI wireframes are created. It could be just a few minutes before the first lines of code are written and less than a day for the feature to hit production.
As a team a lot of the roles listed above are found in numerous individuals. Whereas it can take a lone developer less than a day to release a single feature, it could take weeks before a team is able to get the first UI wireframes done for the same feature. The main reason this happens is due to the layers of communication (which are unnecessary most times). Typically a team will appoint someone to relate with the client and understand their needs before relaying that information to the team but as with the popular party game of Chinese Whispers (see an interesting video about this here) demonstrates, a lot of vital information gets lost in transit and the understanding the team members get differ from what the client intended. Team members who get the briefing later or are located in a different geographic location get a skewed version of the understanding. In short, the much important shared understanding is not achieved.
Location of Team Members
With co-located teams, it is a little easier to deal with all the issues listed above. Things become harder when you sprinkle remote team members in to the mix. Achieving shared understanding becomes much harder mainly because remote teams are almost always informed after the fact or never at all and critical bits of information tend to fall off.
5 Ways to Achieve Shared Understanding
At this point you may be wondering how does one achieve shared understanding across a software development team. Here are a few suggestions on how to achieve this:
1. Get Everyone in the Room
Try as much as possible to get everyone in for project related activities such as meetings with the client. The reason why this helps in achieving shared understanding is because it flattens communication channels. When the developers hear the what the client needs directly they tend to get a better understanding of what is required and may even see better ways of getting things done. Recording important meetings also helps.
2. Consciously Develop a Shared Language/Vocabulary
When communicating about how to solve problem within a team, it is important to eliminate vagueness. To do this, the key things that are repeatedly talked about, entities, and domain concepts need to be defined by a single agreed-upon word or phrase. These words/phrases should be made available to all team members (for example, sticking to the agreed words or phrases in all meetings, gently correcting any misunderstandings or misuse, listed on a physical team board).
3. Meet Regularly
Meeting regularly helps reduce the adverse effect of constant context morphing. Adopting some agility in your software development approach helps with this. For example, daily stand-ups are great ways to ensure everyone on the team is still on the same page. Regular meetings with the client to demonstrate progress also guarantees that “understandings” are still valid.
4. Imbibe an Instant Feedback System
When having one-on-one discussions, there is a feedback system a team can imbibe to ensure that there is shared understanding between the individuals involved. Instead of one of the parties involved in the discussion saying “yes, I understand”, the individual should instead explain what they understand and state how this information will affect their work. Doing this simple thing forces the parties involved in the discussion to get on the same page as more often it will be seen that when one says “yes, I understand” it doesn’t always mean that the individual’s understanding is the same as the other’s. This technique can easily be applied to group meetings as well. You can view this as a summary and conclusion section of any team related discussion.
5. No Dumb Questions/Suggestions
You can speak from here to Mars but until you get some feedback from your audience (an individual or group) you really can’t tell if they understand what you’re trying to communicate. Environments and team cultures that make it hard for members to express themselves will typically have low levels of shared understanding and high levels of re-work. To improve the levels of shared understanding on your team you need to allow team members express themselves freely because this gives you an opportunity to gently correct any misunderstandings. You also need to give extra attention to new team members as they are still learning the team culture and are usually under pressure to fit in that they tend to not reveal their misunderstandings in meetings.
Software development is a communication problem. The key to picking up momentum as a team and maintaining it comes down to how well everyone on the team understands why they are doing what they are doing, and how they plan to get it done. Everyone has to be on the same page and this is what shared understanding is all about. Differences in team member’s domain knowledge, a constantly shifting context, communication channels and geographic location of members are some of the things that make achieving shared understanding harder. Ensuring there are no dumb questions, an instant feedback system is adopted, meetings are held regularly, a shared vocabulary exists and everyone is allowed into the room helps in achieving shared understanding across a team.
Intellectual Apps’ Founder was recently at the O’Reilly Software Architecture Conference in London, this article is a summary of his presentation.
Maintaining an API gateway these days generally involves handling different types of user facing apps such as a web, mobile (of different platforms) and IOT devices. The Backend for Frontend (BFF) pattern specifically addresses this aspect of software solutions.
At Intellectual Apps we build software solutions, and in creating solutions for our clients we frequently get to build web and mobile apps within a single solution. This often means that we have a single API gateway for all the apps to communicate through. Over numerous clients/projects/products we started to notice a lot of repetition in the modules we built into software solutions, so naturally we sort to find a way we could share functionality across solutions in an easy way and this lead us to start experimenting with microservices.
In building microsevices based solutions, as the name suggests, one ends up having several independent services working together as part of a single solution. This posed a specific challenge for us as we now had to make the user facing apps do a lot more work in composing data from numerous services. So we took a step back and after some brainstorming, we realised that we had several other problems which presented themselves in two forms:
Having all apps communicate through a single API gateway.
Apps communicating through a single API gateway
Having apps communicate with multiple services.
Apps communicating directly with microservices
These scenarios created the following specific challenges for us:
Having all apps communicate through a single API gateway.
Given that the data consumption patterns of mobile apps are not the same as web apps, having all the apps share a single API gateway meant that the mobile apps often got more data than necessary when calling the same endpoints being used by the web application. For instance, when returning data to show the details of an item, the web app has room to show way more details than a mobile app can. So when the mobile app calls the same endpoint it simply gets more data that it can possibly display on a small screen which means a lot of the data never gets displayed immediately.
With all apps communicating through a single API gateway, the codebase got bloated. Many attimes this was due to the face that checks were put in place at the API gateway level to determine which app was make the call just so that app specific things could be done.
Having apps communicate with multiple services.
The major challenge with this approach is the extra processing that mobile apps had to do in order compose data coming from multiple independent services in addition to the numerous network calls that have to be made. The immediate effect of this is the drain on battery life.
Enter the BFF
After conducting some research we came across the Backend for Frontend pattern and the motivation for us considering this was to enable us operate in a more agile fashion. The approach was popularized by Sam Newman, the author of Building Microservices. Sam Newman talks about his experience working on a SoundCloud project which faced challenges similar to ours and how he and the team there applied this approach to address the challenges.
We adopted the BFF approach and applied it to our projects and this made our architecture look as follows:
Apps communicating via BFFs
The BFF pattern is a technique where a dedicated layer serves a specific front-end platform. It can easily be seen from the diagram above that each platform gets a specific layer that performs the following functions:
Some front-end specific logic.
Having BFFs perform the functions listed above means that:
Mobile apps won’t have to make multiple network calls.
Mobile apps do less work on data as data composition takes place in the BFF.
Each platform gets the right data needed from each call.
Codebase for each BFF is specific to a platform therefore getting rid of a bloated codebase.
When to use the BFF pattern If one or more of the following are true in your current architecture then the BFF pattern may be something to consider:
You have web, mobile and IOT apps talking to multiple services.
You have web, mobile and IOT apps sharing a single API gateway.
You are migrating to microservices.
You have organisations outside yours consuming your APIs.
A Little More
Typically the front-end team should maintain the BFFs as these layers are technically extensions of the apps they work on. Doing this will let your front-end team iterate faster as they won’t have to communicate with another team, supposing the BFF is maintained by the back-end team.
It may be argued that there will be duplication of code across BFFs, yes, this holds true but the trade-off here is having bloated code in a single API gateway. We even go to the point of having separate BFFs for Android and iOS platforms as this let us focus specifically on one platform.
It also goes without saying that with the BFF approach, there will be more codebases to maintain.
That’s it and I hope you find this article useful, and consider using this pattern as we do at Intellectual Apps so you could respond faster to client and user requirements.