Votre code sent mauvais car il existe probablement de nombreux cas où il pourrait être modifié ou amélioré.
La plupart de ces odeurs ne sont que des indices de quelque chose qui pourrait ne pas fonctionner. Par conséquent, ils ne sont pas obligés d’être réparés en soi… (Vous devriez cependant vous y pencher.)
Vous pouvez retrouver toutes les odeurs de code précédentes (Partie I - XLV) ici .
Nous allons continuer...
Un autre vaisseau spatial s'est écrasé. Un autre problème logiciel
TL;DR : Concevoir et tester le logiciel. C'est moins cher que le matériel
Luna-25 s'est écrasé sur la surface de la Lune le 19 août 2023.
4 jours avant l'atterrissage en douceur de l'avion indien Chandrayaan-3 sur le pôle sud de la Lune.
Une analyse médico-légale a révélé que les instructions partageaient un bus et n’étaient pas correctement hiérarchisées.
Les vaisseaux spatiaux ont une longue histoire de pannes logicielles.
class TaskManager: def __init__(self): self.tasks = [] def add_task(self, task, priority): self.tasks.append((task, priority)) def execute_tasks(self): # No sorting for task, _ in self.tasks: task.execute() class Task: def __init__(self, name): self.name = name def execute(self): print(f"Executing task: {self.name}") task_manager = TaskManager() highPriorityTask = Task("Slow down") mediumPriorityTask = Task("Take Photos") reviveKlaatu = Task("Klaatu barada nikto") # unsorted task_manager.add_task(mediumPriorityTask, 2) task_manager.add_task(highPriorityTask, 1) task_manager.add_task(reviveKlaatu, 3) task_manager.execute_tasks()
class TaskManager: def __init__(self): self.tasks = [] def add_task(self, task, priority): self.tasks.append((task, priority)) def execute_tasks(self): # Sort tasks by priority (high to low) self.tasks.sort(key=lambda x: x[1], reverse=True) for task, _ in self.tasks: task.execute() class Task: def __init__(self, name): self.name = name def execute(self): print(f"Executing task: {self.name}") task_manager = TaskManager() highPriorityTask = Task("Slow down") mediumPriorityTask = Task("Take Photos") reviveKlaatu = Task("Klaatu barada nikto") # unsorted task_manager.add_task(mediumPriorityTask, 2) task_manager.add_task(highPriorityTask, 1) task_manager.add_task(reviveKlaatu, 3) task_manager.execute_tasks()
C'est une odeur de design
Créer des composants logiciels et simuler des conditions réelles et non réelles
Code Smell 198 – Hypothèses cachées
Les odeurs de code sont mon opinion .
Le moteur analytique n’a aucune prétention à créer quoi que ce soit. Elle peut faire tout ce que nous savons comment lui ordonner… Mais elle est susceptible d’exercer une influence indirecte et réciproque sur la science elle-même.
Ada Lovelace
Génie logiciel Citations intéressantes
Laissez les cowboys aux films hollywoodiens.
TL;DR : Écrire du code en tant que programmeur d'équipe
Écrivez un code professionnel.
Utilisez des noms déclaratifs non cryptés.
Les codeurs cowboy ne suivent pas les meilleures pratiques.
Ils ne suivent pas les suggestions de l'équipe.
Le codage Cowboy est généralement considéré comme une approche non professionnelle et risquée du développement de logiciels, car il peut conduire à un code difficile à maintenir et sujet aux erreurs.
Les programmeurs Cowboy sont de bonnes personnes ; cependant, ils ne peuvent pas travailler en groupe .
# Very simple example # Compute the sum of two numbers without any structure or best practices. num1 = input("Enter the first number: ") num2 = input("Enter the second number: ") # WARNNING!!!! Don't remove the line below !!!!! # (Unpleasant comment) res = num1 + num2 # (No data type checking or error handling) print("The sum is: " + result) # (No validation or formatting) # (No good names, no functions, no error handling, no testing, # no version control, and no structure.)
def add_numbers(): try: firstAddend = float(input("Enter the first number: ")) secondAddend = float(input("Enter the second number: ")) total = firstAddend + secondAddend return total except ValueError: print("Invalid input. Please enter valid numbers.") return None def main(): total = add_numbers() if total is not None: print("The sum is: {:.2f}".format(sum)) if __name__ == "__main__": main()
Vous pouvez définir des règles environnementales pour empêcher ces pratiques de codage et renforcer la constitution d’équipes.
Le développement de logiciels est un travail d'équipe.
Code Smell 06 - Programmeur trop intelligent
Code Smell 02 - Constantes et nombres magiques
Code Smell 105 - Méthodes comiques
https://www.linkedin.com/pulse/software-development-cowboy-coding-hakan-atbaş/
Photo de Taylor Brandon sur Unsplash
Le danger des ordinateurs n’est pas qu’ils finissent par devenir aussi intelligents que les hommes, mais que nous acceptions entre-temps de les faire à mi-chemin.
Bernard Avishai
Plus d'une classe, c'est un gâchis.
TL;DR : Suivre le principe de séparation des préoccupations et l'organisation des dossiers
Déclarer une seule classe par fichier
Utiliser la portée du nom
Dans les langages qui déclarent des classes à l’aide d’un système de fichiers, avoir une classe par fichier est généralement considéré comme une bonne pratique.
Cette approche contribue à améliorer l’organisation et la maintenabilité du code et réduit les problèmes potentiels.
Vous pouvez organiser les espaces de noms dans des répertoires distincts au sein de la structure de votre projet.
De cette façon, vous pouvez conserver une base de code logique et efficace tout en évitant les problèmes liés à la déclaration de plusieurs classes dans un seul fichier.
<? namespace MyNamespace; class Class1 { public function sayHello() { echo "Hello from Class1!\n"; } } class Class2 { public function sayHello() { echo "Hello from Class2!\n"; } }
<? namespace MyNamespace; class Class1 { public function sayHello() { echo "Hello from Class1!\n"; } }
<? namespace MyNamespace; class Class2 { public function sayHello() { echo "Hello from Class2!\n"; } }
De nombreuses normes imposent cette règle
Gardez votre code organisé et suivez les normes connues.
Code Odeur 48 - Code sans normes
Photo de Marjan Blan sur Unsplash
Sans exigences ni conception, la programmation est l'art d'ajouter des bugs à un fichier texte vide.
Louis Sygley
Vous compliquez trop votre code.
TL;DR : Éviter la complexité et la bureaucratie accidentelles
Une odeur de code « paperasse » peut être liée à une complexité inutile, à une bureaucratie ou à une configuration excessive qui rend la base de code plus difficile à comprendre ou à maintenir.
class VotingSystem: def __init__(self, config): self.config = config def validate_voter(self, voter_id): if self.config['voter_verification_enabled']: # Code to verify the voter's identity goes here def cast_vote(self, voter_id, candidate): if self.config['voting_enabled']: # Code to record the vote goes here def generate_vote_report(self): if self.config['generate_report']: # Code to generate a voting report goes here def audit_voting_system(self): if self.config['audit_enabled']: # Code to perform an audit of the voting system goes here # ... other voting-related methods ... # Usage config = { 'voter_verification_enabled': True, 'voting_enabled': False, 'generate_report': False, 'audit_enabled': True } voting_system = VotingSystem(config) # Voter validation, voting, report generation, # and auditing are handled based on the configuration.
class VoterVerification: def verify_voter(self, voter_id): # Code to verify the voter's identity goes here class VotingMachine: def cast_vote(self, voter_id, candidate): # Code to record the vote goes here class VoteReporter: def generate_report(self): # Code to generate a voting report goes here class VotingAuditor: def audit_voting_system(self): # Code to perform an audit of the voting system goes here # Usage voter_verification = VoterVerification() voting_machine = VotingMachine() vote_reporter = VoteReporter() voting_auditor = VotingAuditor() # Voter verification, vote casting, report generation, # and auditing are handled separately.
Certains outils peuvent deviner que vous surchargez vos objets avec des responsabilités inutiles.
L'odeur de code administratif est évidente car les développeurs doivent naviguer dans la configuration complexe pour déterminer quelles fonctionnalités sont actives.
Cela ajoute non seulement une complexité inutile, mais augmente également le risque de mauvaises configurations pouvant avoir un impact sur l'intégrité de votre système.
Code Odeur 54 - Bateaux à ancre
Les odeurs de code sont mon opinion .
Photo de l'explosion sur Unsplash
Une erreur du logiciel : si cela fonctionne et que nous ne changeons rien, il continuera à fonctionner.
Jessica Kerr
Votre code est mort et vivant.
TL;DR : Recherchez attentivement les conditions de course
Évitez les conditions de course
Évitez les variables globales
Utiliser une synchronisation appropriée
Le code de Schrödinger est un code qui peut être dans deux états différents en même temps, mais l'état du code n'est déterminé qu'après son exécution.
Cela peut se produire lorsque le code contient une condition de concurrence critique ou lorsque le code dépend de l'état d'une variable globale qui peut être modifiée par d'autres threads ou processus.
import threading cats_alive = 0 def thread_1(): cats_alive += 1 def thread_2(): cats_alive -= 1 if cats_alive > 0: feedThem() # The value of cats_alive is indeterminate, # so the code can be in either of the two states: # # 1. cats_alive > 0 and feedThem() is called. # 2. cats_alive <= 0 and feedThem() is not called.
import threading lock = threading.Lock() cats_alive = 0 def thread_1(): with lock: cats_alive += 1 def thread_2(): with lock: cats_alive -= 1 if cats_alive > 0: feedThem() # With the lock, the two threads cannot access # the `cats_alive` variable at the same time. # This means that the value of `cats_alive` is always determined, # and the program will not exhibit Schrödinger code behavior.
Effectuer des révisions de code sur du code concurrent
Pour éviter le code Schrödinger, évitez les conditions de concurrence et évitez de dépendre de l'état des variables globales qui peuvent être modifiées par d'autres threads ou processus.
Si vous devez utiliser une variable globale dans votre code, assurez-vous qu'elle est correctement synchronisée.
Code Smell 198 – Hypothèses cachées
Code Smell 60 - Cours mondiaux
Photo de Yerlin Matu sur Unsplash
La dernière chose que vous vouliez qu'un programmeur fasse, c'est de jouer avec l'état interne
Alan Kay
La semaine prochaine, 5 odeurs supplémentaires.