The development process Part 2
Working in software is working with people
Have you read the previous blog yet?: The Development Process, part 1?
Alex, determined to drive meaningful change, proposes a bold solution that Alex believes can address the root of their issues. "I've been researching and thinking about this, and I suggest we consider implementing a paradigm shift at Etrain," Alex declares. "In the end, while we are all building different products, they are all part of a singular vision. We need to look at all available resources and take into account the wishes and expertise of our developers. Our landscape is complex and changing. We’re losing value because our teams cannot handle that reality well. So to fix it, let’s not tell the developers what to do. Let’s ask them what they think. Flexibility and putting people first should be our guiding principles in tackling this problem. Have the software developers themselves think of a solution to the problem. I know they’re able to do it."
Alex's proposal draws a mix of intrigued and skeptical expressions from the group. Some nod in agreement, recognizing the potential of such an approach, while others, like the project manager who had voiced concerns earlier, remain cautious.
"It sounds promising," one of the product owners says, "but how would this work in practice? Are you suggesting something like a scaled agile framework? Would that really address the constant changes and instability we're facing?"
Alex outlines their vision, emphasizing the importance of cross-functional teams, clear communication, and adaptability. Alex believes that by aligning the organization around a shared vision, empowering teams to make decisions, and fostering collaboration, they can create an environment that not only mitigates the impact of constant changes but also promotes a culture where people thrive and deliver their best work. As the discussion unfolds, it becomes clear that while the path ahead is challenging, it offers a promising solution to the persistent problems that have been plaguing Etrain's projects and teams.
“Yeah. Good luck with that,” a project manager quips. “Etrain is not ready for this. You’re asking for the impossible.”
Another adds: “You should maybe stick to your laptop, Alex. This is outside your expertise.”
Alex falls silent. Self-doubt creeps in for a bit, but then, a familiar voice can be heard. It’s the product owner of the booking system. “I think software engineering is exactly Alex’s expertise.”
People over plans
In 'The Development Process, Part 1,' we delved into the essential role of planning in software engineering projects. Yet, planning is just the opening act; the real magic happens during the development phase, where human creativity and expertise take center stage. Even in the era of AI (which we have undoubtedly entered by now), one undeniable truth remains: it's people who breathe life into software. Unlike planning, testing, or even programming, people are not merely a component or software development. They are the heartbeat of software development. Software exists to serve people, and software engineering thrives through the people who craft it. This allows me to introduce the main point of this blog: being able to work with people is an essential skill for a software engineer.
Working with others, even when alone
I’ll try not to strawman this, but I’ve heard people say that they “code alone” because they do not work in a team. You could argue that people skills aren’t important for such software engineers. You’d be wrong, but you could argue that. Let me quickly explain why I think even “solo developers” work with people in various ways. Firstly, you'll encounter requirements written by people, whether it's your initial specifications or those provided by clients and stakeholders. Secondly, your software is intended for users – real people who will interact with and rely on your creation. Lastly, even if you're the first and only developer on a project, you're building upon the work of predecessors, who have left their code, documentation, and knowledge behind, and descendants, who will build upon what you’ve created. So, whether you're a lone coder or part of a larger team, the influence and involvement of people are woven into the very fabric of software development.
And of course, when working in a software development team larger than one person, people skills are very important. So, let’s discuss these different people you’ll interact with as a software engineer, starting with the requirements. On the one hand, we have various analysts, requirement writers, and stakeholders, and being able to communicate with them is very much a plus. However, on the other hand, we have the person most often associated with requirements: the product leader. Communication with your product leader is key.
Product ownership versus product management
You’ll notice I said product leader instead of the potentially more familiar product owner, or even product manager. In the realm of engineering software, a critical aspect is having a person who embodies the essence of the product, ensuring it aligns with the vision and goals. This often falls under the roles of Product Owners (PO) and Product Manager (PM). These two functions play distinct but complementary roles in the software development process.
A PO focuses on representing the end-users and stakeholders. The PO is responsible for defining and prioritizing features, creating a clear backlog, and ensuring that the development team delivers what the users need. They act as the voice of the customer, maintaining a tight feedback loop with the end-users to make sure the product evolves to meet their requirements.
A PM, on the other hand, takes a broader view. They are responsible for the overall strategy, market analysis, and the long-term vision of the product. PMs coordinate with various teams, set strategic goals, and ensure the product aligns with the company's objectives. They play a critical role in understanding market trends and competitive landscapes.
However, in many successful software development teams, these roles often blend into a conceptual role we can call Product Leaders (PL). A PL combines the user-centric focus of a PO with the strategic thinking and market awareness of a PM. In dynamic environments, having someone who can bridge these functions becomes increasingly important.
Why is having agency over product decisions crucial within the development team? When engineers have a say in shaping the product direction, it not only enhances their sense of ownership and commitment but also results in more innovative solutions. Developers on the front lines often gain unique insights into technical feasibility, potential challenges, and opportunities for improvement. Their involvement in product decisions can lead to more efficient development processes and better outcomes.
Earlier I said communication with your product leader is key. Most developers will agree with this assertion. Those who don’t tend to fall into a very different mindset from mine. I’ll group them as the mindset of ‘I write the code’ versus ‘I help create the product.’ The former implies a narrow focus on coding tasks, while the latter embraces a broader perspective. An ‘I help create the product’ mentality recognizes that software development is not merely about writing lines of code; it’s about crafting solutions that serve users and meet business objectives. This shift in mindset fosters collaboration, a deeper understanding of the product’s purpose, and a shared responsibility for its success. In today’s fast-paced tech landscape, embracing a ‘product creator’ mindset is a powerful way to drive innovation, create meaningful user experiences, and ensure that your software not only works but excels in meeting user needs.
Interacting with users
Moving on, let’s discuss the significance of user interaction. Typically, it’s the product leader who takes the lead in engaging with users, both directly and indirectly, while developers focus on the technical aspects. However, cultivating the ability to communicate directly with your product’s users can be a valuable skill for a software engineer. It can offer fresh insights and a broader perspective, enriching your growth journey. Moreover, as a developer, considering ways to facilitate and automate user communication within your product can be advantageous. Features like ‘Contact Us’ options, evaluation options for different features, clear error messages and codes, and robust monitoring mechanisms – while topics we’ve explored before – warrant repetition because they contribute significantly to a smoother user experience and a more efficient development process.
Working in a team
Now, let’s delve into the core of this blog, where we explore the profound impact of team composition and interactions on productivity. For most developers, teamwork is a fundamental aspect of their work, and understanding team dynamics is crucial.
I’ve referenced them before, but let’s explore Tuckman’s Stages of Group Development in full.
Forming: In the initial Forming stage, a team’s just coming together. Team members are often polite, cautious, and trying to figure out their roles and expectations. They may not yet fully understand the scope of the project or how they fit into it.
Storming: As the team starts to work together, the Storming phase can be turbulent. Conflicts and disagreements may arise as individuals assert themselves and their ideas. This stage is marked by a struggle for power and influence within the team.
Norming: The Norming phase is where team members begin to find common ground and establish norms for working together. Collaboration becomes smoother, and trust starts to build. Roles and responsibilities become clearer.
Performing: In the Performing phase, the team operates at its highest level of productivity. Members are highly engaged, work together seamlessly, and achieve their goals effectively. This stage is marked by a strong sense of unity and purpose.
Adjourning: The Adjourning phase is when the team wraps up its work, and members transition to other projects or roles. It's often characterized by reflection on the team's accomplishments and a sense of closure.
In each of these stages, some behaviours may cause problems, while in others they will not. It is therefore important to recognize both which stage your team currently resides in, and the effects of your behaviour. Let’s repeat the first four stages, but now with some dos and don’ts attached.
Forming: In this early stage, team members may exhibit over-cautiousness, reluctance to voice their opinions, and a tendency to rely heavily on the leader for guidance. They may not be comfortable with open discussion. Because of that, focus on creating bonds with your team members. Show interest in them and foster a culture of opening up to each other. Try to refrain from starting with a “Storming” mentality, especially when joining teams that already exist.
Storming: The Storming phase can be marked by open conflicts, power struggles, and resistance to collaboration. Team members may challenge each other's ideas and vie for dominance in decision-making. Weirdly, if your instinct is to prevent open conflict and quell aggressive discussions, do not follow that instinct during this phase. You’ll force your team back in the forming stage. Instead, set rules for proper discussion, time-box the discussions, and make sure the discussions remain professional, not personal.
Norming: During Norming, some team members may become complacent, resist change, or fall into groupthink, where they conform to the majority opinion rather than critically evaluate ideas. The best thing to do here is to start documenting the norms somewhere, like with a team motto, a way of working, a definition of done, various decisions, and even your technical and architectural documentation. Reaching this stage means the team is almost ready to start performing, so try to create some enthusiasm about the newfound team identity.
Performing: In the Performing phase, there's a risk of potential burnout due to high levels of engagement. Creativity and innovation may dwindle as the team becomes overly focused on maintaining its efficiency and momentum. Instead, it is important to look back every once in a while, to maintain the happy buzz that is at this stage, and also look forward to predicting upcoming changes that may endanger the stage progression.
Efficiency within a team can decline if the team regresses to a previous stage, which can happen due to various factors:
- Introduction of new team members can disrupt the existing dynamics and require time for integration.
- Role changes within the team may lead to confusion or a need for reestablishing norms and expectations.
- Departure of key team members can impact the team's capabilities and knowledge base.
- Evolving project requirements may necessitate a reevaluation of goals and strategies.
- Significant adjustments in project scope, budget, or time constraints can introduce stress and uncertainty.
- Artificial progression, where consensus is feigned to appease management, can lead to unresolved issues and hinder genuine progress.
Understanding these intricacies of team development and being vigilant about potential challenges is vital for maintaining a productive and harmonious team environment.
So, what are some other aspects of teams in successful software development? In my experience, team members must be equal and must be accepting of failure. Moreover, software engineers in a team need to engage in mentoring and coaching. Let me explain in more detail.
In my experience, one of the crucial aspects of effective teamwork is the concept of equality among team members. Yes, we all like to distinguish between juniors and seniors. Even I made a distinction between coders, programmers, and engineers at the start of this series, which could be understood as a hierarchy. However, I find that any team where one of the members cannot be told “you’re wrong” is a recipe for failure somewhere down the road. Nobody is right all the time, especially in the complex world of software development.
To illustrate the significance of equality, let's take a somber example from aviation history.
(Yes, I’ll admit to a guilty pleasure of mine: I’ve watched almost every episode of Mayday: Aircraft Investigation. It’s actually quite often applicable to software engineering).
The tragic crash of Eastern Air Lines Flight 401 in 1972 serves as a stark reminder of the consequences when team members, the co-pilot and flight engineer, do not feel empowered to challenge the decisions of another team member, in this case, the pilot. In the accident, the aircraft was in perfect condition but ultimately crashed due to a malfunctioning landing gear light. The co-pilot and flight engineer noticed the issue but hesitated to confront the pilot about it. They held the belief that questioning the pilot's judgment was inappropriate. As a result, the plane crashed, leading to a devastating loss of lives.
This tragic incident emphasizes the importance of creating an environment where all team members, regardless of their roles, feel empowered to speak up, voice concerns, and challenge decisions when necessary. In software development teams, this principle translates into fostering a culture of open communication, where junior engineers can question senior developers and vice versa. It's about recognizing that diversity of thought and perspective can lead to better decisions and safer outcomes.
Another important predictor of team success is emotional safety. In other words, each member must feel and acknowledge that making mistakes is okay. Failure is an inherent part of growth and innovation, and it's crucial for team members to feel emotionally safe to fail without facing severe repercussions. When individuals fear punitive consequences for mistakes, they are less likely to take risks or suggest alternative approaches. This fear stifles creativity and can lead to suboptimal solutions.
In software development, fostering a culture of psychological safety encourages experimentation and learning from failures. A software engineer can act as an example and model the target behaviour. When engineers are not afraid to admit their mistakes or propose unconventional ideas, it can lead to breakthroughs and improvements in the development process. It will also allow other team members to feel that same emotional safety. Encouraging open discussions about failures and treating them as opportunities for growth can enhance team dynamics and contribute to a more robust software engineering practice.
Mentoring and Coaching
Mentoring and coaching are pivotal for the growth and professional development of software engineers. Engaging in activities such as code review not only ensures the quality of the codebase but also provides a platform for knowledge sharing and mentorship. Senior engineers can guide junior team members, imparting valuable insights and best practices.
Moreover, mentoring and coaching contribute to the overall professionalism of the field. It's about passing on not just technical skills but also ethical considerations and a sense of responsibility. Encouraging mentorship within software development teams helps bridge the gap between experienced engineers and those entering the field, ultimately raising the industry's overall standards.
Don’t worry, be happy
Of course, there are many more important pieces in the entire process of software development. I’ve mentioned Agile and DevOps in previous blogs, as I find that transparency is key. However, almost all other aspects of the process should be custom fit to the situation. If you follow the advice I’ve laid out in the previous blogs, and use transparency, software quality, and ethics as guidelines, you’ll find a process that works for your team, for your product, for the moment.
However, there is one additional very important factor in software engineering that will predict success. Or at least, it will predict how often and deeply you will experience success. And that factor is enjoyment in your work. Software engineers need to enjoy their work to do it. At least do it according to the standards I’ve set in this series. Nobody can perform in a complex and changing environment unless their work is fulfilling to them. So, look back at your progress regularly. Set clear boundaries for yourself. Make work enjoyment an explicit goal for yourself and your team.
One of my mantra’s this blog series has been “[X] is your responsibility, not somebody else’s”, but nowhere is it truer than in the case of your happiness. It is probably the toughest responsibility of all, at least for some people, so help each other where you can.
Being a people person is necessary for the future of our profession
We’ve almost reached the end of this blog entry. The next entry in this series will be the last one, and it will take a slightly different form. But before we finish up, I want to provide my final argument for why I think it is so important to work well with people. It is vital to safeguard the progress of our profession. We need to work with and inspire the next generation and listen to them in return. The software engineering field will only advance and increase professionalism if seasoned engineers actively engage with the next generation and challenge the status quo. It's not enough to simply continue working within one's comfort zone; instead, experienced engineers should actively seek opportunities to mentor, teach, and inspire emerging talent. I mean, that I feel that way should not be a surprise; it’s the entire point of me writing an entire blog series.
By sharing knowledge, fostering a sense of ethical responsibility, and encouraging critical thinking, experienced engineers contribute to a more professional and ethical software development industry. This responsibility goes beyond writing code; it's about shaping the future of the profession and ensuring it evolves in a positive direction. It's an investment in the growth and sustainability of the field itself, one that promises a brighter and more innovative future for software engineering.
One year later, in the comfortable office of Kim, a seasoned coach and mentor, Alex is sitting in a comfy chair. Both of them are enjoying a nice cup of coffee and reflecting on the changes that have unfolded at Etrain over the past year. Kim has been instrumental in guiding Alex during the challenging journey of implementing a new collaborative paradigm within the entire organization.
Kim starts the conversation with a warm smile, "So, Alex, it's been quite a year. Let's talk about how things are going with the various projects you're overseeing at Etrain."
Alex leans forward, appreciating Kim's support throughout this transformative period. "It's been a rollercoaster, to say the least. We’ve made plenty of mistakes, but the change-up in team dynamics did bring more stability and transparency to our projects. It hasn't been without its challenges. People left. People fought. But I think the results are good."
Kim nods thoughtfully, "Change is never easy. It’s a cliché, but not untrue. If I remember correctly, you joined Etrain almost two years ago, right? You've done quite a few things that weren't necessarily expected of you when you started."
Alex chuckles, "Yes, I've had to wear many hats. Besides programming and setting up architecture, I've found myself acting as a mentor and coach to some of the other developers, and even to others here at Etrain. It wasn't in my job description, but it felt essential to help them navigate the changes we were implementing."
Kim nods in approval, "That's quite commendable, Alex. You've taken on a leadership role that goes beyond your job title.”
“Does it, though?” Alex asks. “Is what I did not precisely what was needed to, you know, engineer good software?”
Kim looks at Alex for a bit, before shrugging. “I don’t know, to be fair. Let me ask you that question, but in a different way: what do you believe are the responsibilities of a software engineer?"
Alex takes a deep breath, pondering the question that encompasses the essence of the Etrain journey. "I think a software engineer's responsibilities extend far beyond writing code. We're problem solvers, collaborators, and mentors. Our duty is to not only build functional software but to create solutions that make people's lives better. It's about fostering a culture of continuous improvement, learning from failures, and empowering others to do the same. Ultimately, it's about the impact we have on the organization and the industry… even the world, as a whole."
"Maybe we should update the software engineer vacancy descriptions on our website,” Kim jokes approvingly. You've come a long way! You were already an impressive software engineer when I first met you, and since then, you've embraced your role as a software engineer with depth and compassion."
“Thanks, I guess,” Alex says.
“You just need to work on your ability to respond to compliments a bit.”
As the meeting concludes, Alex leaves Kim's office feeling at peace, despite all the challenges the various software projects at Etrain are still facing. Alex walks through the halls, reminiscing about the past two years. ‘Software engineering is an awesome job,’ Alex thinks, before sitting down behind a laptop to write a few more lines of code.
An overview of what has already been posted and what is still to come, here is a full overview:
As always, I ask you to contact me. Send me your corrections, provide suggestions, ask your questions, deliver some hot takes of your own, or share a personal story. I promise to read it, and if possible, will include it in the series.
Writing Quality Code, Part 1