Introduction

“Software Craftsmanship”, “Clean Code”, “SOLID”… Ces termes circulent partout dans notre écosystème, souvent accompagnés d’un sentiment d’intimidation. J’ai longtemps pensé que c’était réservé aux développeurs “experts”, à ceux qui écrivent des livres ou donnent des conférences.

Erreur ! Le Software Craftsmanship, c’est avant tout une démarche progressive d’amélioration continue. Pas besoin d’être Robert C. Martin pour commencer. Il suffit de faire un pas, puis un autre.

Qu’est-ce que le Software Craftsmanship, vraiment ?

Au-delà des définitions savantes

Oublions un instant les définitions académiques. Le Software Craftsmanship, c’est simplement l’envie de bien faire son travail. C’est se soucier de :

  • La lisibilité de son code (pour soi et ses collègues)
  • La facilité de maintenance (parce qu’on reviendra dessus)
  • La fiabilité (parce qu’on n’aime pas les bugs en production)
  • L’évolutivité (parce que les besoins changent)

L’analogie de l’artisan

Imaginez un menuisier qui construit une table. Il peut :

  1. Bâcler : assembler rapidement des planches, tant que ça tient
  2. Faire correctement : choisir le bon bois, soigner les assemblages, poncer, vernir

Dans les deux cas, vous avez une table. Mais laquelle préférez-vous chez vous ? Laquelle durera le plus longtemps ?

Pour le code, c’est pareil. Vous pouvez faire fonctionner une feature rapidement, ou prendre un peu plus de temps pour qu’elle soit robuste et maintenable.

Les premiers pas : commencer petit

1. Nommage explicite

Le premier et plus simple changement : donnez des noms clairs à vos variables et fonctions.

// Avant
function calc(u, p) {
  return u * p * 0.8;
}

// Après
function calculateDiscountedPrice(unitPrice, quantity) {
  const DISCOUNT_RATE = 0.8;
  return unitPrice * quantity * DISCOUNT_RATE;
}

Pourquoi ça marche ? Dans 6 mois, quand vous reviendrez sur ce code, vous comprendrez immédiatement ce qu’il fait.

Exercice pratique : Prenez un fichier de votre projet actuel et renommez 5 variables ou fonctions avec des noms plus explicites. Vous devriez ressentir immédiatement la différence.

2. Fonctions courtes et focalisées

Une fonction doit faire une seule chose et la faire bien.

// Avant : fonction qui fait trop de choses
function processOrder(order) {
  // Validation
  if (!order.items || order.items.length === 0) {
    throw new Error('Order must have items');
  }
  
  // Calcul du prix
  let total = 0;
  for (let item of order.items) {
    total += item.price * item.quantity;
  }
  
  // Application des taxes
  const taxAmount = total * 0.20;
  total += taxAmount;
  
  // Sauvegarde en base
  database.save('orders', { ...order, total, taxAmount });
  
  // Envoi d'email
  emailService.send(order.customerEmail, `Commande confirmée: ${total}€`);
  
  return total;
}
// Après : responsabilités séparées
function processOrder(order) {
  validateOrder(order);
  const total = calculateOrderTotal(order);
  const savedOrder = saveOrder(order, total);
  sendConfirmationEmail(savedOrder);
  return total;
}

function validateOrder(order) {
  if (!order.items || order.items.length === 0) {
    throw new Error('Order must have items');
  }
}

function calculateOrderTotal(order) {
  const subtotal = order.items.reduce((sum, item) => {
    return sum + (item.price * item.quantity);
  }, 0);
  
  return addTaxes(subtotal);
}

function addTaxes(amount) {
  const TAX_RATE = 0.20;
  return amount * (1 + TAX_RATE);
}

Pourquoi ça marche ? Chaque fonction a un rôle clair. Plus facile à tester, déboguer et modifier.

Exercice pratique : Trouvez une fonction de plus de 20 lignes dans votre code et découpez-la en 2-3 fonctions plus petites.

3. Élimination de la duplication

Le principe DRY (Don’t Repeat Yourself) est l’un des plus importants.

// Avant : duplication
function calculateStudentDiscount(price) {
  return price * 0.9; // 10% de réduction
}

function calculateSeniorDiscount(price) {
  return price * 0.85; // 15% de réduction
}

function calculateEmployeeDiscount(price) {
  return price * 0.8; // 20% de réduction
}

// Après : logique commune
function calculateDiscount(price, discountRate) {
  return price * (1 - discountRate);
}

const DISCOUNT_RATES = {
  STUDENT: 0.1,
  SENIOR: 0.15,
  EMPLOYEE: 0.2
};

function calculateStudentDiscount(price) {
  return calculateDiscount(price, DISCOUNT_RATES.STUDENT);
}

Exercice pratique : Identifiez 3 endroits où vous répétez la même logique et factorisez-la.

Outils simples pour progresser

1. Le linter : votre premier allié

Un linter comme ESLint (JavaScript) ou Pylint (Python) vous aide à repérer automatiquement les problèmes basiques.

// Configuration ESLint simple
{
  "extends": ["eslint:recommended"],
  "rules": {
    "no-unused-vars": "error",
    "no-console": "warn",
    "prefer-const": "error",
    "no-var": "error"
  }
}

Installation en 2 minutes :

npm install eslint --save-dev
npx eslint --init

2. Le formateur de code

Prettier ou Black (Python) formatent automatiquement votre code selon des règles cohérentes.

Pourquoi c’est utile ? Fini les débats sur les virgules et l’indentation. L’équipe se concentre sur la logique.

3. Les tests unitaires : commencer simple

Pas besoin de viser 100% de couverture dès le départ. Commencez par tester les fonctions les plus critiques.

// Fonction à tester
function calculateDiscount(price, discountRate) {
  if (price < 0) throw new Error('Price cannot be negative');
  if (discountRate < 0 || discountRate > 1) {
    throw new Error('Discount rate must be between 0 and 1');
  }
  return price * (1 - discountRate);
}

// Test simple avec Jest
describe('calculateDiscount', () => {
  test('calculates discount correctly', () => {
    expect(calculateDiscount(100, 0.2)).toBe(80);
  });
  
  test('throws error for negative price', () => {
    expect(() => calculateDiscount(-100, 0.2)).toThrow('Price cannot be negative');
  });
});

Commencez par : tester 1-2 fonctions par semaine. L’habitude viendra naturellement.

Progresser étape par étape

Semaine 1-2 : Les bases

  • Installer un linter et un formateur
  • Renommer 10 variables/fonctions avec des noms explicites
  • Découper 2-3 fonctions trop longues

Semaine 3-4 : Structure

  • Éliminer 3 duplications de code
  • Écrire 5 tests unitaires pour les fonctions critiques
  • Organiser le code en modules logiques

Mois 2 : Approfondissement

  • Apprendre 1 principe SOLID (commencer par la responsabilité unique)
  • Refactoriser un module complexe
  • Mettre en place une review de code simple

Mois 3+ : Automatisation

  • Intégrer les tests dans la CI/CD
  • Mettre en place des métriques de qualité
  • Partager les bonnes pratiques avec l’équipe

Erreurs à éviter quand on débute

1. Le perfectionnisme paralysant

Ne refactorisez pas tout d’un coup. Améliorez progressivement, feature par feature.

Règle du Boy Scout : “Laissez le code plus propre que vous ne l’avez trouvé”. Même une petite amélioration compte.

2. L’over-engineering

N’appliquez pas tous les design patterns d’un coup. Commencez simple et complexifiez seulement quand c’est nécessaire.

// Trop compliqué pour commencer
class OrderProcessorFactory {
  createProcessor(type) {
    switch(type) {
      case 'online': return new OnlineOrderProcessor();
      case 'store': return new StoreOrderProcessor();
    }
  }
}

// Commencez par ça
function processOrder(order) {
  if (order.type === 'online') {
    return processOnlineOrder(order);
  }
  return processStoreOrder(order);
}

3. Ignorer le contexte

Adaptez vos standards au contexte du projet. Un prototype rapide n’a pas les mêmes exigences qu’un système critique.

Ressources pour continuer

Lectures accessibles

  • “Clean Code” de Robert C. Martin : commencez par les 3 premiers chapitres
  • “Refactoring” de Martin Fowler : excellent pour apprendre à améliorer le code existant
  • Articles de blog et tutoriels plutôt que des livres théoriques

Pratique

  • Code katas : exercices courts pour pratiquer (FizzBuzz, Roman Numerals)
  • Code reviews avec des collègues bienveillants
  • Projets perso pour expérimenter sans pression

Communautés

  • Forums locaux et meetups développeurs
  • Slack/Discord de communautés tech
  • Mentoring informel avec des collègues expérimentés

Conclusion

Le Software Craftsmanship n’est pas une destination, c’est un voyage. Chaque petit pas compte : un nom de variable plus clair, une fonction mieux découpée, un test ajouté.

L’objectif n’est pas de devenir parfait du jour au lendemain, mais de s’améliorer continuellement. Dans 6 mois, vous regarderez votre code d’aujourd’hui et vous sourirez en voyant le chemin parcouru.

Commencez par une seule pratique cette semaine. Laquelle allez-vous choisir ?