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

Clean Code - princípios e práticas para um código sustentável

Clean Code - princípios e práticas para um código sustentável

Palestra sobre Clean Code - princípios e práticas para um código sustentável " apresentada no JsDay 2017 em Feira de Santana

B11eec4cb13d50de922479fcc5e2e803?s=128

Andrews Medina

July 17, 2017
Tweet

Transcript

  1. clean code princípios e práticas para um código sustentável

  2. whoami dev na Jusbrasil contribuidor projetos open source

  3. código feio

  4. function randomNumber() { return 5; }

  5. if value is True: doSomething() elif value is False: doSomething2()

    else: doSomething3()
  6. if (x != 0 && x != 1 && x

    != 2 && x != 3 && x > 4) { doSomething(); }
  7. if (player.hasPermission("se.block.smoke")) if (block != Material.LEVER) { if (block !=

    Material.BED) { if (block != Material.BED_BLOCK) { if (block != Material.CACTUS) { if (block != Material.BRICK_STAIRS) { if (block != Material.BIRCH_WOOD_STAIRS) { if (block != Material.BREWING_STAND) { if (block != Material.CAKE) { if (block != Material.CAKE_BLOCK) { if (block != Material.CAULDRON) { if (block != Material.CHEST) { if (block != Material.CLAY) { if (block != Material.SAND) { if (block != Material.BURNING_FURNACE) { if (block != Material.COBBLESTONE_STAIRS) { if (block != Material.FENCE) { if (block != Material.FENCE_GATE) { if (block != Material.FIRE) { if (block != Material.GRAVEL) { if (block != Material.IRON_DOOR_BLOCK) { if (block != Material.IRON_FENCE) { if (block != Material.IRON_DOOR) {
  8. if (block != Material.BURNING_FURNACE) { if (block != Material.COBBLESTONE_STAIRS) {

    if (block != Material.FENCE) { if (block != Material.FENCE_GATE) { if (block != Material.FIRE) { if (block != Material.GRAVEL) { if (block != Material.IRON_DOOR_BLOCK) { if (block != Material.IRON_FENCE) { if (block != Material.IRON_DOOR) { if (block != Material.LADDER) { if (block != Material.MELON) { if (block != Material.LEAVES) { if (block != Material.LOCKED_CHEST) { if (block != Material.SANDSTONE_STAIRS) { if (block != Material.SMOOTH_STAIRS) { if (block != Material.SPRUCE_WOOD_STAIRS) { if (block != Material.TNT) { if (block != Material.WOOD_DOUBLE_STEP) { if (block != Material.WOOD_DOOR) { if (block != Material.WEB) { if (block != Material.ICE) { if (block != Material.SNOW_BLOCK) { if (block != Material.SNOW) { if (block != Material.WATER_LILY) { if (block != Material.TORCH) {
  9. if (block != Material.RAILS) { if (block != Material.POWERED_RAIL) {

    if (block != Material.DETECTOR_RAIL) { if (block != Material.DEAD_BUSH) { if (block != Material.GRASS) { if (block != Material.NETHER_BRICK_STAIRS) { if (block != Material.NETHER_FENCE) { if (block != Material.NETHER_WARTS) { if (block != Material.HUGE_MUSHROOM_1) { if (block != Material.HUGE_MUSHROOM_2) { if (block != Material.BROWN_MUSHROOM) { if (block != Material.GLASS) { if (block != Material.JUNGLE_WOOD_STAIRS) { if (block != Material.WATER) { if (block != Material.SUGAR_CANE_BLOCK) { if (block != Material.WOOD_DOUBLE_STEP) { if (block != Material.WALL_SIGN) { if (block != Material.WOOD_PLATE) { if (block != Material.STONE_PLATE) { if (block != Material.STONE_BUTTON) { if (block != Material.WOOD_STAIRS) { if (block != Material.TRAP_DOOR) { if (block != Material.TRIPWIRE) { if (block != Material.TRIPWIRE_HOOK) { if (block != Material.WOOD_STEP) { if (block != Material.THIN_GLASS) { if (block != Material.REDSTONE_TORCH_OFF) { if (block != Material.REDSTONE_TORCH_ON) { if (block != Material.SAPLING) { String s = new SerializableLocation(loc).unpack().toString(); this.plugin.Blindeness.add(s); this.plugin.Blindeness.save(); if (this.String1 == this.plugin.getConfig().getString("_Block_Blindeness")) { player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] You Created a" + ChatColor.DARK_RED + " BlindenessEffectBlock" + ChatColor.DARK_GREEN + " at " + ChatColor.RED + s); } else { player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] You Created a" + ChatColor.DARK_RED + " BlindenessEffectBlock" + ChatColor.DARK_GREEN + " at " + ChatColor.RED + s); } } else { player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else
  10. if (block != Material.RAILS) { if (block != Material.POWERED_RAIL) {

    if (block != Material.DETECTOR_RAIL) { if (block != Material.DEAD_BUSH) { if (block != Material.GRASS) { if (block != Material.NETHER_BRICK_STAIRS) { if (block != Material.NETHER_FENCE) { if (block != Material.NETHER_WARTS) { if (block != Material.HUGE_MUSHROOM_1) { if (block != Material.HUGE_MUSHROOM_2) { if (block != Material.BROWN_MUSHROOM) { if (block != Material.GLASS) { if (block != Material.JUNGLE_WOOD_STAIRS) { if (block != Material.WATER) { if (block != Material.SUGAR_CANE_BLOCK) { if (block != Material.WOOD_DOUBLE_STEP) { if (block != Material.WALL_SIGN) { if (block != Material.WOOD_PLATE) { if (block != Material.STONE_PLATE) { if (block != Material.STONE_BUTTON) { if (block != Material.WOOD_STAIRS) { if (block != Material.TRAP_DOOR) { if (block != Material.TRIPWIRE) { if (block != Material.TRIPWIRE_HOOK) { if (block != Material.WOOD_STEP) { if (block != Material.THIN_GLASS) { if (block != Material.REDSTONE_TORCH_OFF) { if (block != Material.REDSTONE_TORCH_ON) { if (block != Material.SAPLING) { String s = new SerializableLocation(loc).unpack().toString(); this.plugin.Blindeness.add(s); this.plugin.Blindeness.save(); if (this.String1 == this.plugin.getConfig().getString("_Block_Blindeness")) { player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] You Created a" + ChatColor.DARK_RED + " BlindenessEffectBlock" + ChatColor.DARK_GREEN + " at " + ChatColor.RED + s); } else { player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] You Created a" + ChatColor.DARK_RED + " BlindenessEffectBlock" + ChatColor.DARK_GREEN + " at " + ChatColor.RED + s); } } else { player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else player.sendMessage(ChatColor.DARK_GREEN + "[SpecialEffects] Can't" + ChatColor.DARK_RED + " create a EffectBlock" + ChatColor.DARK_GREEN + " Using this material"); } else
  11. http://codecrap.com/

  12. who?

  13. None
  14. código feio é um problema?

  15. computadores não ligam para beleza

  16. ninguém vai ler, só eu!

  17. é só uma poc

  18. é rapidinho, depois eu mudo

  19. CHUCK NORRIS IS WATCHING YOU

  20. código limpo legível e reusável

  21. regra do escoteiro

  22. don’t repeat yourself

  23. keep it simple

  24. seja o autor do seu código

  25. práticas

  26. nomes

  27. use nomes pronunciáveis

  28. let x = “http://j.us”;

  29. let encurtadorURL = “http://api.j.us”;

  30. use nomes buscáveis

  31. setTimeout(notifyUser, 120);

  32. const TWO_MINUTES = 120; setTimeout(notifyUser, TWO_MINUTES);

  33. use nomes claros

  34. function calcula(valor) { return valor * 1.1; }

  35. function calculaGorjeta(valor) { return valor * 1.1; }

  36. funções

  37. funções devem fazer apenas uma coisa

  38. function notifyClients(clients) { clients.forEach(clientId) => { const client = db.find(clientId);

    if (client.isActive()) { notify(client); } } }
  39. function notifyActiveClients(clients) { client.filter(isActive).forEach(notify); } function isActive(clientId) { const client

    = db.find(clientId); return client.isActive(); }
  40. não use flags como parâmetros

  41. function createUser(user, isAdmin) { db.save(user); if (isAdmin) { promoteUser(user); }

    }
  42. function createUser(user) { db.save(user); } function createAdmin(user) { createUser(user); promoteUser(user);

    }
  43. objetos

  44. Single Responsibility Principle (SRP)

  45. class UserSettings { constructor(user) { this.user = user; } changeSettings(settings)

    { if (this.verifyCredentials()) { … } } verifyCredentials() { … } }
  46. class UserFriends { constructor(user) { this.user = user; } addFriends(friend)

    { if (this.verifyCredentials()) { … } } verifyCredentials() { … } }
  47. class UserAuth { constructor(user) { this.user = user; } verifyCredentials()

    { … } } class UserSettings { constructor(user) { this.user = user; this.auth = new UserAuth(user); } changeSettings(settings) { if (this.auth.verifyCredentials()) { … } } }
  48. cuidados gerais

  49. código duplicado

  50. variáveis não usadas

  51. “unreachable” code

  52. console.log

  53. linter

  54. linter

  55. Testes

  56. testes são códigos para verificar que seu código está funcionando

    como esperado
  57. func testeSoma() { let resultado = soma(1, 1); expect(resultado).toBe(2); }

  58. func testeSplitHostAndPort() { let url = “jusbrasil.com.br:3333”; let {host, port}

    = splitHostAndPort(url); expect(host).toBe(“jusbrasil.com.br”); expect(port).toBe(3333); }
  59. testes me deixam mais lento?

  60. TDD

  61. None
  62. testes ajudam a manter a manutenção e o reuso do

    código
  63. Com TDD todo código novo nasce com testes

  64. TDD ajuda a focar na resolução do problema

  65. func testLogin() { let user = db.find(userId); user.login(password); assert(user.isLogged()); }

  66. func testBot() { let bot = new Bot(); expect(bot.x).toBe(0); expect(bot.y).toBe(0);

    bot.walkToLeft(5); expect(bot.x).toBe(-5); }
  67. None
  68. coding style

  69. const semEstilo = { foo: 3, 'bar': 4, 'data-blah': 5,

    };
  70. const comEstilo = { foo: 3, bar: 4, data-blah: 5,

    };
  71. • airbnb • Google • Mozilla • Idiomatic.js • jQuery

    Core • Node.js • …
  72. type check TypeScript Flow

  73. // @flow function square(n: number): number { return n *

    n; } square("2"); // Error!
  74. Coding Dojo

  75. code review

  76. legado???

  77. legado +6 meses sem manutenção deploy não funcionava 33% cobertura

    de testes
  78. livros

  79. ????

  80. @andrewsmedina github.com/andrewsmedina twitter.com/andrewsmedina

  81. perguntas?