Raise your hand 🖐️ if you recognize this meme:
Do you agree with it? I generally do. In today's fast-changing tech world, it's easy to get lost in the 'rules' of coding.
It's important that we occasionally stop and rethink our methods—not to reduce the importance of solid coding principles, but to make sure our efforts align with the broader goals of our projects and companies.
Avoiding the Pitfalls of Dogma & Hype
Traditional coding practices are the foundation of software development projects. They ensure code readability, maintainability, and scalability. But blindly applying these practices, without considering the project's specific context, can lead to inefficiencies and waste.
For example, being too rigid with certain practices might slow down development in the early stages of a startup, where the ability to pivot quickly is key.
A Real-World Example
Please take this as an example and not literal agains this specific pattern. I share as its what is fresh in my mind as I've experienced this in at least two workplaces over the last year.
We're currently seeing a lot of hype around Clean Architecture, which involves using the Ports & Adapter Pattern. Well-known figures like Uncle Bob or Vaughn Vernon advocate for it, making it the center of attention.
In many organizations, every single project starts as a Ports & Adapters project, focusing on business logic and separating it from external contact points. While the pattern can be valuable at a code level, we need to consider its drawbacks:
Starting up: Setting up a Ports & Adapters project takes more initial time, potentially delaying the first release. It may not be the best fit for projects with tight deadlines or a priority on launching a minimum viable product quickly.
Cognitive load: Ports & Adapters can increase the cognitive load for developers, especially those unfamiliar with the pattern. It might require more training and time for developers to understand and use effectively, slowing down development.
Over-engineering: The Ports & Adapters pattern can lead to over-engineering, especially in simple projects where such a complex structure isn't needed. This could make the code more complicated and difficult to manage.
Maintenance: The Ports & Adapters pattern could add more maintenance work. If a project's scope isn't too complex, a simpler architecture might be easier to maintain and evolve over time.
If you have unlimited time or budget, this might not be a concern. But that's not the reality for most new products. Especially in a fast-paced product development environment where you're trying to find product-market fit or experiment with user reactions, this could hinder your profitability.
Aligning Practices with Goals
Here are some things to consider to align coding practices with your project and company goals:
Assess the Project Lifecycle Phase: The needs of a nascent project are vastly different from those of a mature one. Early on, the focus might be on prototyping and rapid iteration. As the project matures, stability and scalability become more important.
Proof of Concept: At this stage, you might prioritize speed over structure. The main goal is to validate your idea's feasibility, so it will be acceptable to take shortcuts in code quality and/or testing.
Minimum Valuable Product: At this stage, the goal is to create a functional product with just enough features to satisfy early customers and provide feedback for future product development. Therefore, while it's important to strive for reusable code, speed and functionality might take precedence.
Minimum Lovable Product: This stage focuses on improving the user experience, making the product more appealing and enjoyable. While maintaining the focus on functionality, you might prioritize refining the user interface, improving performance, or adding features that enhance user satisfaction.
Production Quality Product: At this stage, the focus is on refining the product into a fully-fledged offering that can sustain long-term growth. You might prioritize code quality, extensive testing, and scalable architecture, as the product's stability and performance become increasingly critical.
Understand the Business Impact: Consider how the project directly impacts the business. Projects that are critical to revenue or customer experience might require more stringent practices, whereas internal tools might allow for more flexibility.
Team Tools: For tools used by the engineering team, the balance might lean towards speed and functionality. These tools are often used to automate tasks or improve workflows, so they need to work efficiently. Code quality and maintainability can be slightly relaxed, as long as the tool's functionality and performance are not compromised.
Internal Tools: These might include tools for other non-engineering departments. In these cases, the investment normally is not high so there is a need to balance functionality and code quality, maintainability, and scalability.
Client Product: For products that directly touch the client, such as a mobile app or a web platform, the focus might lean heavily towards both functionality and user experience. It is crucial to ensure code quality, maintainability, and scalability to provide a smooth and reliable user experience.
Assess Team Abilities: Your team's experience and skills are essential. Consider the potential learning curve when introducing new practices, patterns, or frameworks, as they may not yield the expected results.
Balance Risk and Reward: Understand the risk profile of different decisions. For example, skipping peer review process might speed up deployment but increase the risk of bugs in production.
Moving Forward
As leaders, we need to ensure that our teams aren't following practices just for compliance, but are actively contributing to our company’s objectives. We should foster an environment where questioning the status quo is welcomed, as long as it's with the intent of finding better, more aligned ways to work.
This doesn't mean lowering our standards, but rather adapting them intelligently to better serve our ultimate goals. It's about efficient and effective application, not complete abandonment or blind adherence. Balancing the discipline of coding standards with the flexibility needed to meet business objectives is an art that can greatly influence the success of software projects.
Let’s create a culture that values critical thinking and adaptability as much as coding excellence. By doing so, we not only align our coding practices with our project and company goals but also empower our teams to contribute their best work towards collective success.
Nice read, good post! Very identified...
Developers should be advised and taught about "Aligning Practices with Goals" early in their careers. The lack of business context awareness and the software-developed audience easily leads to inefficient product development or developer frustration.