Home  >  Article  >  Web Front-end  >  The Never Ending Battle Against Software Complexity

The Never Ending Battle Against Software Complexity

王林
王林Original
2024-07-27 07:48:52826browse

The Never Ending Battle Against Software Complexity

What is Complexity?

Recently, I finished reading "A Philosophy of Software Design" and in the second chapter, it explores the topic of Software Complexity. 

The book "A Philosophy of Software Design" defines complexity practically:

"Complexity is anything related to the structure of a software system that makes it hard to understand and modify."

In other words, complexity can take many forms, and doesn't necessary has anything to do with performance, your code can be performant and still be complex

I'd like to share some key definitions and insights from the book in this article. But first, let's imagine a common situation that probably you’ve already been to…


A Short Horror Story

Let's dive into a horror story many of you have probably experienced or will experience.

  1. It started with a simple CRUD task management app. The code was clean, modular, and easy to maintain. The development team was happy, and the system worked perfectly for initial clients.

  2. Problems began when the sales team sold the system to a large company, claiming it had calendar integration, email notifications, and an amazing report generator. With the sale finalized, these features had to be implemented quickly.

  3. Calendar Integration: The team had to integrate with Google Calendar and Outlook. Different developers implemented the solutions, resulting in inconsistent approaches.

  4. Email Notifications: Email notifications were added next. One developer used a specific library, while another created a custom solution. The mixed approaches made the code confusing.

  5. Report Generator: For the report generator, developers used various technologies: PDFs, Excel exports, and interactive dashboards. The lack of a unified approach made maintenance a nightmare.

  6. Growing Complexity: Each feature was developed in isolation and quickly, leading to dependencies between features. Developers started creating "quick fixes" to make everything work, increasing the system's complexity and coupling.

Software development doesn't happen in a vacuum; various internal and external factors influence it. We've all been, or will be, in a situation like this.


The Beginning of the End

Then the problems began:

  1. Changes in one part of the system affected other parts unexpectedly.
  2. Small changes required modifications in many other files, making estimations difficult.
  3. Month after month, the code became harder to understand, often fixed through trial and error.
  4. Productivity declined, and everyone dreaded maintenance tasks.
  5. The inevitable call for "We need to refactor."
  6. Certain tasks could only be handled by specific developers (classic)
  7. Over time, the once beautifully written and well-documented software became a train wreck.

Naming the Symptoms

It's clear we now have a complex system.

Now let's "dissect" this complexity to make it easier to identify and mitigate it.

Well, "mitigate" means:

"To make less severe, serious, or painful; to alleviate."

I believe complexity is often inherent in code. Some things are complex by nature. Your role as a developer isn't just to create code that the computer can execute efficiently but also to create code that future developers (including your future self) can work with.

“Controlling complexity is the essence of computer programming.”

— Brian Kernighan

The author of the mentioned book states that complexity typically manifests in three ways, which we will explore here.

Change Amplification

Change amplification occurs when a seemingly simple change requires modifications in many different places.

For example, if the Product Owner requests a "priority" or "completion date" field and your entities are tightly coupled, how many changes would you need to make?

Cognitive Load

Cognitive load refers to the amount of knowledge and time a developer needs to complete a task.

So imagine this scenario: A new developer joined the team, he was assigned to fix a bug in the report generator. To complete this task, the dev needed to:

  • Comprenez les différentes intégrations de calendrier (Google et Outlook).
  • Comprenez les différentes approches en matière de notifications par e-mail.
  • Naviguez dans le code fragmenté du générateur de rapports, traitant des PDF, Excel et des tableaux de bord.
  • Intégrez ces diverses technologies et styles pour trouver et corriger le bug.

Il s'agit du scénario classique « impossible à estimer », dans lequel la tâche pourrait prendre un ou huit points : mieux vaut lancer un D20 et répondre en conséquence.

Inconnus Inconnus

Les inconnus inconnus, c'est quand vous ne savez pas ce que vous ne savez pas.

C'est la pire manifestation de la complexité, car vous pourriez modifier des choses que vous ne devriez pas, ce qui provoquerait la rupture de tout.

Exemple : Un développeur a modifié le code d'envoi d'e-mails pour ajouter une nouvelle notification, ignorant que cela affecterait le générateur de rapports, qui dépendait de cette fonction. Cela a causé des problèmes importants aux clients, illustrant la pire forme de complexité émergente.

Causes de la complexité

Après avoir vu l'histoire d'horreur et les trois principaux symptômes, regardons ce qui cause la complexité.

1. Dépendances

Les dépendances sont essentielles dans les logiciels et ne peuvent pas être complètement éliminées. Ils permettent aux différentes parties du système d’interagir et de fonctionner ensemble. Cependant, les dépendances, lorsqu’elles ne sont pas gérées correctement, peuvent augmenter considérablement la complexité.

Définition:

Une dépendance existe lorsque le code ne peut pas être compris ou modifié de manière isolée, nécessitant la prise en compte ou la modification du code associé.

Types de dépendances :

  • Direct : Le module A s'appuie directement sur le module B.
  • Transitif : Le module A s'appuie sur le module B, qui s'appuie sur le module C.
  • Cyclique : Les modules A, B et C sont interdépendants de manière circulaire.

2. Obscurité

L'obscurité se produit lorsque des informations importantes ne sont pas évidentes. Cela peut rendre la base de code difficile à comprendre, entraînant une charge cognitive accrue et le risque d'inconnues.

Définition:

L'obscurité se produit lorsque des informations importantes ne sont pas évidentes.

Exemples d'obscurité :

  • Mauvaise dénomination : Variables et fonctions dont les noms ne sont pas clairs.
  • Effets secondaires cachés : Méthodes qui effectuent des actions inattendues.
  • État global : Surutilisation des variables globales.
  • Héritage profond : Comportement réparti sur de nombreux niveaux dans les hiérarchies de classes.

N'oubliez pas : la complexité est incrémentielle

  • La complexité est rarement causée par une seule « erreur » ou une mauvaise décision.
  • La complexité s'accumule « lentement » à cause des mauvaises décisions et des dépendances au fil du temps.

Parce que c'est progressif, il est facile de penser : « juste pour une fois, ça n'aura pas d'importance ». Mais une fois accumulées, réparer une ou deux dépendances à elle seule ne fera pas beaucoup de différence.

« Tout est un compromis en génie logiciel. »
— Je ne me souviens pas de l'auteur

Conclusion

Je pourrais écrire beaucoup de règles, de stratégies et de cadres que vous avez probablement déjà vus sur Internet pour éviter la complexité : SOLID, Design Patterns, YAGNI, KISS, etc.

Cependant, vous pouvez les unifier tous en un seul principe directeur (comme mentionné dans « Le programmeur pragmatique. ») : « Ce que j'implémente est-il facile à changer ? » Si la réponse est non, alors vous augmentez probablement la complexité.

S'assurer que votre code est facile à modifier simplifie la maintenance, réduit la charge cognitive des développeurs et rend le système plus adaptable et moins sujet aux erreurs.

Merci !

The above is the detailed content of The Never Ending Battle Against Software Complexity. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn