Communication, coordination and collaboration
While working within software engineering teams, one often comes across the phrase:
“It is a people problem and not a technical problem.”
While this may be true in many cases, it happens often enough that it is clearly highlighting an important problem in the machinery of developing software systems. As such, it is also highlighting and opportunity for improvement.
Rephrasing this slightly to “Why does this feel like a people problem and not a technical problem?” we can quickly see that the issues are often around:
- communication: have the various parties involved received a sufficient instruction that they can understand and act on?
- coordination: have the various parties communicated back their acknowledgement of the steps required and have they managed expectations in terms of timelines and scope?
- collaboration: have the various parties highlighted tasks that are tightly coupled and would benefit from higher bandwidth communication and shared involvement?
Taking another step back, one sees that all of these issues are the type of issues that arise in complex systems. These systems must achieve a goal, while also managing a network of interactions.
With this in mind, we can start to look at the many mechanisms in our toolbox for software engineering, and realise that very often they exist to help manage the complexity of the problem:
- architectural principles: decoupling and decomposing systems into cohesive parts manages complexity by creating better boundaries in the system that support independent change.
- version control: version control tools that support branching and merging explicitly manage complexity by supporting concurrent work while imposing well defined work-flows for coordinating shared efforts.
- agile methodologies: provide processes that the team can follow in order to obtain early feedback from effort on the critical path, and thereby manage the complexity of implementing systems when the full problem space and solution is not known up front.
- telemetry: tooling to collect and collate metrics from running systems helps to provide rapid feedback from production, in order to manage the complexity involved when the “real world” doesn’t behave the same way as the lab.
- continuous delivery: CI/CD helps to automate the link between coding output and execution in production, so as to manage the complexity involved in building systems with many independently moving parts when their performance characteristics may further depend on their environmental context.
- operational closure: a principle involved in addressing the full life-cycle of a subsystem early in the design and implementation phase, helps to manage the complexity of implementing long running processes where the reciprocal mechanisms may only be needed far in the future.
- emotional intelligence: increases in empathy and awareness of non-verbal signals within the team helps to manage the complexity of communicating complicated concepts across a wide audience, while still needing work within a resource constrained setting.
- experimentation: explicit orchestration of experiments as a basic currency underpinning projects helps to manage the complexity of simultaneously needing to implement solutions while also searching for the solutions.
When I work with teams I aim to increase the awareness of the need for managing complexity, while simultaneously ensuring that concrete and pragmatic mechanisms are put in place for use by the team.
This enables the team to focus on the delivery of solutions that solve the actual business needs, while not being slowed down by miscommunication and insufficient cooperation. Furthermore, it enables the team to start to be aware of other areas where complexity needs to be managed better in order to remain effective.
The result is a team that is able to work with a changing environment while still being effective in delivering quality systems. The business in turn can now be more adaptive and able to leverage “change” as an opportunity in the market place.