Challenging Five Common Engineering Dogmas

Software Engineering

This article critically examines five widely accepted engineering dogmas, including mandatory code reviews, rigid sprints, and the overuse of external packages or feature flags. It challenges their 'common wisdom' status, advocating for a more balanced and context-aware approach to software development practices.

Following a previous discussion on the observed behaviors of software projects, this article delves into five widely accepted engineering practices, challenging their 'common wisdom' status and proposing a reevaluation. These dogmas, while rooted in valid intentions, can often lead to unintended inefficiencies and complexities.

The five practices under scrutiny are:

  1. Don’t reinvent the wheel – always find a package.
  2. Every pull request (PR) must be reviewed.
  3. Rigid 2-4 week sprints are the definitive model for modern teams.
  4. Every code change should be behind a feature flag/gate.
  5. If a comment is needed, the code is too complex.

1. The "Don't Reinvent the Wheel" Fallacy: Over-reliance on External Packages

The advice to reuse existing code is often lauded for its potential to save development time. However, this philosophy can lead to an excessive reliance on third-party packages, introducing hidden risks.

One notable example is the left-pad incident, where the removal of an 11-line package from NPM disrupted builds for major companies like Facebook, Spotify, and Netflix. Another cautionary tale involves the is-even npm package, which, despite having hundreds of thousands of weekly downloads, performs a trivial calculation that could be easily implemented from scratch.

Over-dependence on external libraries also increases vulnerability to security incidents, demanding significant time for updates and vulnerability management. In many smaller organizations, the absence of a formal vetting process for packages means engineers often add dependencies without rigorous scrutiny. While Large Language Models (LLMs) can accelerate both the adoption of unnecessary dependencies and the implementation of known solutions from scratch, striking the right balance between reuse and internal development remains crucial.

2. Reconsidering Mandatory Code Reviews

For over 15 years, mandatory code reviews have been a staple in software development, typically requiring one or two reviewers per pull request. While code reviews undeniably enhance quality and foster knowledge sharing, a rigid, mandatory process can introduce significant bottlenecks.

A detailed analysis of the costs associated with mandatory code reviews reveals that while they improve code quality, they can significantly impede development speed. The issue isn't with code reviews themselves, but rather with overly strict and lengthy processes, such as requiring re-reviews for every minor commit on an already approved PR.

Some organizations adopt a more flexible approach, empowering skilled engineers to merge their own code and only requesting reviews for risky changes, when seeking input, or during onboarding. This philosophy trusts engineers and avoids unnecessary bottlenecks, recognizing that pairing programming can also serve as an effective alternative to asynchronous reviews.

3. Challenging the Dominance of 2-4 Week Sprints

The prevalent use of 2-4 week sprints in agile methodologies often diminishes the intrinsic joy of software creation. If given the freedom to design an ideal team organization, many would question whether the current sprint-based approach truly maximizes customer value or fosters engineering creativity and enjoyment.

Alternatives like the "Shape Up" methodology offer a different perspective. This approach advocates for 6-week cycles, followed by one or two weeks dedicated to independent work, bug fixes, pet projects, and general winding down. Crucially, these are not "sprints"; the emphasis is on calm, deliberate work and smart decision-making rather than continuous, exhausting effort.

The key takeaway is not necessarily to adopt "Shape Up" wholesale, but to acknowledge that alternatives to Scrum/Kanban exist. Teams have the opportunity to design a workflow that genuinely suits their specific context and culture, promoting sustainable development without leading to engineer burnout.

4. The Perils of Overusing Feature Flags

While feature flags offer powerful capabilities for controlled rollouts and experimentation, their indiscriminate use can significantly degrade a codebase.

Once feature flags are introduced, product managers often discover various extended applications beyond simple toggling: moving configurations to PM-accessible interfaces, enabling per-user adjustments for granular feedback (similar to, but distinct from, canary releases), using flags to disable resource-intensive features during system overload, or gating premium features. This broad application can even extend to hiding bug fixes behind flags for potential rapid reversion.

This expansive use can quickly lead to a codebase riddled with hundreds of active feature flags, dramatically increasing complexity and making testing much harder. Furthermore, feature flags can foster a false sense of security; instances where code intended to be hidden behind a flag is erroneously released to production are not uncommon, especially in frontend frameworks like React.

Feature flags are valuable tools when used judiciously. However, it's perfectly acceptable to thoroughly test a code change on a staging environment and release it without any flags or gates, reserving flags for truly complex or high-risk deployments.

5. Re-evaluating Code Commenting Philosophy

The evolution of advice on code commenting has seen two prominent extremes. The initial perspective encouraged extensive commenting to ensure future understandability. This was followed by a counter-dogma asserting that if comments are necessary, the code itself is poorly written and should be self-explanatory.

Adopting either extreme of this advice is generally counterproductive. While writing clear, self-documenting code is always a goal, there are undeniably situations where a concise comment or two can save a future developer hours of frustration when deciphering complex logic, intricate algorithms, or non-obvious design choices. The art lies in finding the balance.

Conclusion

Many widely accepted 'common wisdoms' in engineering, such as 'don’t release on Friday' or 'microservices automatically ensure scale and ownership,' are not entirely baseless. There's usually a logical reason for their initial adoption. However, effective engineering leadership requires balancing these dogmas with practical realities, constantly assessing what truly benefits their teams and projects.