Upgrade to Pro — share decks privately, control downloads, hide ads and more …

 Les pièges courants dans les équipes technique...

 Les pièges courants dans les équipes techniques et comment les éviter

Soyons honnêtes : construire de super produits n’est pas juste une question de beau code, c’est surtout une question d’équipe qui fonctionne bien ensemble.

En tant que freelance, j’ai pu constater que certains problèmes sont souvent les mêmes dans différentes équipes et dans différentes entreprises.

Au travers cette session, je partagerai les difficultés les plus courantes auxquelles les équipes techniques sont confrontées au quotidien et comment les résoudre !

Que vous soyez développeur, manager ou simplement quelqu’un qui souhaite améliorer l’ambiance de travail, vous repartirez avec des conseils pratiques pour aider votre équipe à s’améliorer !

Renaud MATHIEU

April 11, 2025
Tweet

More Decks by Renaud MATHIEU

Other Decks in Programming

Transcript

  1. Renaud Mathieu  Les pièges courants dans les équipes techniques et

    comment les éviter Android Makers by droidcon 2025 @renaudmathieu.com
  2. Objectif 1. Identi fi er les problèmes concrets qui freinent

    la productivité, la qualité ou la fl uidité du développement.
  3. Objectif 2. Proposer des pistes de solutions, avec des méthodes

    concrètes, outils, et retours d’expérience.
  4. ORGUEIL Symptômes • La tendance à sur-concevoir ou sur-ingénierer :

    faire du code ou des architectures trop complexes pour «   la beauté du geste   ». • Refus d’écouter le client ou de prendre en compte la satisfaction client parce qu’on pense avoir raison.
  5. ORGUEIL Symptômes : sur-concevoir interface WhateverScreenTimeBadgeSetHasSeenUseCase : CompletableUseCase<Boolean> class AScreenObserveStatusUseCaseImpl

    @Inject constructor( private val homeRepository: HomeRepository, private val whateverObserveAvailabilityUseCase: WhateverObserveAvailabilityUseCase, ) : WhateverScreenTimeBadgeSetHasSeenUseCase { override fun execute(params: Unit): Observable<Boolean> = Observable.combineLatest( whateverObserveAvailabilityUseCase.execute(Unit), homeRepository.observeHasSeenBadge(), ) { isAvailable, hasSeenBadge - > isAvailable && !hasSeenBadge } }
  6. ORGUEIL Illustrations interface WhateverScreenTimeBadgeSetHasSeenUseCase : CompletableUseCase<Boolean> class AScreenObserveStatusUseCaseImpl @Inject constructor(

    private val homeRepository: HomeRepository, private val whateverObserveAvailabilityUseCase: WhateverObserveAvailabilityUseCase, ) : WhateverScreenTimeBadgeSetHasSeenUseCase { override fun execute(params: Unit): Observable<Boolean> = Observable.combineLatest( whateverObserveAvailabilityUseCase.execute(Unit), homeRepository.observeHasSeenBadge(), ) { isAvailable, hasSeenBadge - > isAvailable && !hasSeenBadge } }
  7. ORGUEIL Illustrations import androidx.compose.runtime.Immutable import androidx.compose.ui.graphics.Color import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf

    @Immutable data class CharacterDetailsViewStateUiModel( val id: Int, val topBarColor: Color, val name: String, val status: String, val species: String, val type: String, val gender: String, val imageUrl: String, val episodes: PersistentList<String>, ) { companion object { val DEFAULT = CharacterDetailsViewStateUiModel( id = -1, topBarColor = Color.Transparent, name = "-", status = "-", species = "-", type = "-", gender = "-", imageUrl = "", episodes = persistentListOf(), ) } }
  8. C’est quoi la qualité ? Dev ๏ Facile à lire

    ๏ Facile à modi fi er ๏ Performant
  9. C’est quoi la qualité ? PM ๏ Utile ๏ Facile

    à expliquer ๏ Ramène de l’argent
  10. C’est quoi la qualité ? Clients ๏ Fais le job

    ๏ Facile à utiliser ๏ Fun / Agréable
  11. AVARICE Symptômes • Vouloir «   cumuler   » les

    fonctionnalités en backlog sans priorisation claire. • Empiler les chantiers (multiplication des répos, microservices, etc.) alors qu’on n’a pas la capacité humaine ou technique pour tout tenir.
  12. AVARICE Illustrations • DoR/DoD pas clair : on ajoute en

    backlog des user stories sans jamais valider les vraies conditions d’acceptation ou de «   De fi nition of Ready/Done   ». • Le Backlog contient énormément de tickets • On se retrouve avec un énorme work in progress… qui n’avance jamais.
  13. AVARICE Comment y remédier ? Red bin ๏ Pièces non

    conformes, détectés comme défectueux. ๏ Incite à la résolution rapide du problème.
  14. AVARICE Comment y remédier ? One Piece Flow ๏ One

    job at a time ๏ Identi fi er rapidement les défauts.
  15. AVARICE Comment y remédier ? Heijunka ๏ Consiste à lisser

    la production en fonction de la demande pour éviter les pics et creux de charge. ๏ Maintenir un f lux continu et stable
  16. AVARICE Comment y remédier ? Flux tiré ๏ VS Flux-poussé-dans-ta-tronche

    ๏ Au lieu d’approvisionner sur la base d’un plan « prévisionnel » (souvent source de surproduction), on attend que le poste « tire » ce dont il a besoin, au moment où il en a besoin.
  17. AVARICE Comment y remédier ? Timeboxing ๏ Durée fi xe

    ๏ Focus sur une seule tâche ๏ Évaluation après la timebox
  18. AVARICE Comment y remédier ? MoSCoW ๏ Must Have (M)

    ๏ Should Have (S) ๏ Could Have (C) ๏ Won’t Have (W)
  19. AVARICE Comment y remédier ? Impact ๏ % User Impact

    ๏ Analytics ๏ Know your users
  20. LUXURE Symptômes • Vouloir adopter toutes les dernières technologies ou

    frameworks sans se poser la question du ROI ni de la maintenance. • Faire du Proof of Concept permanent sans jamais stabiliser un pipeline ou un socle fi able.
  21. LUXURE Comment y remédier ? 2. Gradle Catalog 3. Gradle

    Convention 4. Gradle Managed Devices 1. Gradle Pro fi ler
  22. LUXURE Comment y remédier ? $ brew install gradle-profiler $

    gradle-profiler -- benchmark assembleDebug ⏳
  23. # Can specify scenarios to use when none are specified

    on the command line default-scenarios = ["assemble"] # Scenarios are run in alphabetical order assemble { # Show a slightly more human-readable title in reports title = "Assemble" # Run the 'assemble' task tasks = ["assemble"] } clean_build { title = "Clean Build" versions = ["3.1", "/Users/me/gradle"] tasks = ["build"] gradle-args = [" -- parallel"] system-properties { "key" = "value" } cleanup-tasks = ["clean"] run-using = tooling-api // value can be "cli" or "tooling-api" daemon = warm // value can be "warm", "cold", or "none" measured-build-ops = ["org.gradle.api.internal.tasks.SnapshotTaskInputsBuildOperationType"] // see -- measure-build-op buck { targets = [" // thing/res_debug"] type = "android_binary" // can be a Buck build rule type or "all" } warm-ups = 10 } ⏳ $ brew install gradle-profiler $ gradle-profiler -- benchmark assembleDebug $ gradle-profiler -- benchmark -- scenario-file performance.scenarios clean_build
  24. run-using = tooling-api // value can be "cli" or "tooling-api"

    daemon = warm // value can be "warm", "cold", or "none" measured-build-ops = ["org.gradle.api.internal.tasks.SnapshotTaskInputsBuildOperationType"] // see -- measure-build-op buck { targets = [" // thing/res_debug"] type = "android_binary" // can be a Buck build rule type or "all" } warm-ups = 10 } ideaModel { title = "IDEA model" # Fetch the IDEA tooling model tooling-api { model = "org.gradle.tooling.model.idea.IdeaProject" } # Can also run tasks # tasks = ["assemble"] } toolingAction { title = "IDEA model" # Fetch the IDEA tooling model tooling-api { action = "org.gradle.profiler.toolingapi.FetchProjectPublications" } # Can also run tasks # tasks = ["assemble"] } androidStudioSync { title = "Android Studio Sync" # Measure an Android studio sync # Note: Android Studio Hedgehog (2023.1.1) or newer is required # Note2: you need to have local.properties file in your project with sdk.dir set android-studio-sync { # Override default Android Studio jvm args # studio-jvm-args = ["-Xms256m", "-Xmx4096m"] # Pass an IDEA properties to Android Studio. This can be used to set a registry values as well # idea-properties = ["gradle.tooling.models.parallel.fetch=true"] } } ⏳ $ brew install gradle-profiler $ gradle-profiler -- benchmark assembleDebug $ gradle-profiler -- benchmark -- scenario-file performance.scenarios clean_build
  25. LUXURE Comment y remédier ? 2. Gradle Catalog 3. Gradle

    Convention 4. Gradle Managed Devices 1. Gradle Pro fi ler
  26. 2. Gradle Catalog [versions] kotlin = "2.1.0" coroutines = "1.7.3"

    [libraries] kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } kotlin-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } [plugins] kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } dependencies { implementation(libs.kotlin.stdlib) implementation(libs.kotlin.coroutines) } plugins { id(libs.plugins.kotlin) } ✅ Avantages 🎯 Version unique pour chaque lib 🔍 Auto-complétion dans l’IDE 🔄 Mise à jour simpli fi ée 🧼 Moins de risques d’erreurs
  27. LUXURE Comment y remédier ? 2. Gradle Catalog 3. Gradle

    Convention 4. Gradle Managed Devices 1. Gradle Pro fi ler
  28. 3. Gradle Convention 🔁 Éviter la duplication de code Gradle

    🔧 Imposer des standards cohérents entre modules ♻ Réutiliser facilement une con fi guration partagée 🧼 Garder les build.gradle.kts de chaque module lisibles build-logic/ ├── build.gradle.kts ├── settings.gradle.kts └── convention/ ├── build.gradle.kts └── src/main/kotlin/ ├── AndroidApplicationConventionPlugin.kt ├── AndroidLibraryConventionPlugin.kt └── KotlinLibraryConventionPlugin.kt class AndroidLibraryConventionPlugin : Plugin<Project> { override fun apply(target: Project) { with(target) { pluginManager.apply("com.android.library") pluginManager.apply("org.jetbrains.kotlin.android") extensions.configure<LibraryExtension> { compileSdk = 35 defaultConfig { minSdk = 26 } buildFeatures { compose = true } } } } } // module: feature/home/build.gradle.kts plugins { alias(libs.plugins.nowinandroid.android.library) } // module: build-logic/convention/build.gradle.kts gradlePlugin { plugins { register("androidLibrary") { id = libs.plugins.nowinandroid.android.library.asProvider().get().pluginId implementationClass = "AndroidLibraryConventionPlugin" }
  29. LUXURE Comment y remédier ? 2. Gradle Catalog 3. Gradle

    Convention 4. Gradle Managed Devices 1. Gradle Pro fi ler
  30. 4. Gradle Managed Devices internal fun configureGradleManagedDevices( commonExtension: CommonExtension <*

    , *, *, *, *, *> , ) { val pixel4 = DeviceConfig("Pixel 4", 30, "aosp-atd") val pixel6 = DeviceConfig("Pixel 6", 31, "aosp") val pixelC = DeviceConfig("Pixel C", 30, "aosp-atd") val allDevices = listOf(pixel4, pixel6, pixelC) val ciDevices = listOf(pixel4, pixelC) commonExtension.testOptions { managedDevices { devices { allDevices.forEach { deviceConfig -> maybeCreate(deviceConfig.taskName, ManagedVirtualDevice :: class.java).apply { device = deviceConfig.device apiLevel = deviceConfig.apiLevel systemImageSource = deviceConfig.systemImageSource } } } groups { maybeCreate("ci").apply { ciDevices.forEach { deviceConfig - > targetDevices.add(devices[deviceConfig.taskName]) } } } } ./gradlew pixel4api30aospatdDebugAndroidTest ✅ Automatisation complète des tests UI ✅ Pas besoin de lancer l’émulateur manuellement ✅ Compatible avec CI (GitHub Actions, GitLab, Bitrise, etc.) ✅ Facile à con fi gurer et intégrer au pipeline
  31. LUXURE Comment y remédier ? 2. Gradle Catalog 3. Gradle

    Convention 4. Gradle Managed Devices 1. Gradle Pro fi ler
  32. LUXURE Comment y remédier ? 2. Gradle Catalog 3. Gradle

    Convention 4. Gradle Managed Devices 1. Gradle Pro fi ler Temps de build Dependabot / Renovate Modules Tests
  33. ENVIE Symptômes • Vouloir copier les méthodes des autres équipes

    “plus cool” sans comprendre les spéci fi cités de son équipe/projet. • Jalouser les succès externes (ou d’autres équipes en interne) au point de négliger le dialogue
  34. GOURMANDISE Symptômes • Multiplier les réunions, les revues, les boards

    (Kanban, Slack, etc.) au point de noyer tout le monde. • Context switching • Processus administratifs excessifs
  35. COLÈRE Symptômes • Con f lits sur les merges ou

    sur la gestion de Git. • Manque de clarté sur le DoR/DoD qui génère des incompréhensions et des frustrations. • L’impression que chacun veut faire prévaloir ses idées (critiques virulentes en code review, discussions Slack en f lammées, etc.).
  36. COLÈRE Comment y remédier ? • Why ? Partage de

    connaissance. • What ? La PR suit les conventions fi xées • Who ? Qui décide fi nalement si le code est prêt à être utilisé ? • When ? À décider • Where ? Pairing / Remote screen sharing ? Et on le rappelle régulièrement
  37. COLÈRE Comment y remédier ? • Code Review Best Practices

    PULL_REQUEST_TEMPLATE.md CI Integration SCA / SAST
  38. COLÈRE Illustrations Salut 10:02 Salut 10:03 Sava? 11:42 Ça va

    et toi ? 11:42 J’ai une question pour toi 14:02 Mais vaut mieux qu’on en parle dans un point dédié. T’es dispo quand ? 14:02
  39. PARESSE Symptômes • Ne pas mettre en place les bonnes

    pratiques (tests, monitoring) par f lemme ou inertie. • Laisser traîner les décisions, reporter les rétrospectives, ne plus faire d’amélioration continue.
  40. PARESSE Illustrations • « La CI est pétée ? »

    • « On peut le faire dans un autre ticket ? » • « Preprod est encore pétée ? » • « Tu peux me fi ler les Secrets ? Sur Slack, ne t’embête pas ? » • « Je sais pas faire, c’est Jean-Miche qui s’en occupe en général » • « On a toujours le même problème »
  41. PARESSE Comment y remédier ? Plan ๏ Identi fi er

    un problème ๏ Dé fi nir un plan d’action ๏ Mesurer !
  42. PARESSE Comment y remédier ? Do ๏ Mettre en œuvre

    le plan élaboré à petite échelle pour tester son e f fi cacité
  43. PARESSE Comment y remédier ? Act ๏ Évaluer les résultats

    obtenus par rapport aux objectifs fi xés. ๏ Mesurer !
  44. J’ai eu une journée productive quand… J’ai pu accomplir toutes

    les tâches de ma journée J’ai fi nalisé tous les objectifs que je m’étais fi xé J’ai écrit plus de 10 lignes de code J’ai au moins écrit une ligne de code Je suis dans un bon mood et que j’ai bien dormi J’ai eu su f fi samment de temps calme pour faire ce que je dois faire et je n’ai pas besoin d’attendre des réponses venant d’autres personnes Quand il fait beau et que le bureau est calme Je n’ai pas perdu mon temps en réunions et je n’ai pas été sans arrêt interrompu
  45. Kaizen Principes clés • Amélioration continue : Petites étapes cumulatives

    pour des résultats signi fi catifs à long terme. • Implication de tous : Chaque employé contribue à identi fi er et résoudre les problèmes. • Élimination des gaspillages (Muda) : Suppression des activités sans valeur ajoutée. • Standardisation : Les améliorations sont intégrées dans les processus pour garantir leur pérennité. • Cycle PDCA (Plan-Do-Check-Act) : Méthodologie structurée pour plani fi er, tester, évaluer et ajuster les solutions