Anzeige
Anzeige

Más contenido relacionado

Similar a The Technical Debt Trap(20)

Anzeige
Anzeige

The Technical Debt Trap

  1. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev The technical Debt Trap
  2. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev Doc Norton, CEO doc@wearecto2.com @DocOnDev
  3. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev what is technical debt?
  4. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev – Ward Cunningham OOPSLA ‘92 Shipping first time code is like going into debt.
  5. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite. – Ward Cunningham OOPSLA ‘92
  6. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite. The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt. – Ward Cunningham OOPSLA ‘92
  7. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev The danger occurs when the debt is not repaid. Every minute spent on not-quite- right code counts as interest on that debt. – Ward Cunningham OOPSLA ‘92
  8. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev The danger occurs when the debt is not repaid. Every minute spent on not-quite- right code counts as interest on that debt. – Ward Cunningham OOPSLA ‘92
  9. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev Technical debt is
  10. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev Technical debt is good
  11. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev Technical debt is good
  12. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev Technical debt is good
  13. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev Technical debt is a strategic decision
  14. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev Technical debt is a strategic decision • Allow for Rapid Delivery • To Elicit Quick Feedback • And Correct Design
  15. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt is an indication of learning
  16. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt is an indication of learning • Now know what you need • Implementation doesn’t match
  17. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt is a metaphor
  18. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev metaphors rock we reason by analogy Building on a weak foundation Puts pressure on our design Can’t keep running at this pace It’s raining men (hallelujah)
  19. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev metaphorphosis when metaphors go wrong Credit CardSHORT-TERM Long-Term Return on Investment OPERATIONALHOME LOAN Loan Shark PRAGMATIC LEVERAGE Intentional AUTO LOAN FRAUDULENT VOLUNTARY PYRAMID SCHEME Prudent Student Loan HIGH INTEREST INADVERTENT RECKLESS DEBT IN THE THIRD QUADRANT
  20. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev metaphorphosis when metaphors go wrong “quick and dirty” - Martin Fowler “sloppy” - David Laribee “just hack it in” - Steve McConnell “CUT A LOT OF CORNERS” - James Shore
  21. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt quadrant Reckless Inadvertent Prudent Deliberate “We don’t have time for design” “We must ship now and deal with consequences” “Now we know how we should have done it” “What’s Layering?”
  22. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev – Ward Cunningham Youtube ‘09 [Many] have explained the debt metaphor and confused it with the idea that you could write code poorly with the intention of doing a good job later.
  23. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev – Ward Cunningham Youtube ‘09 confused the debt metaphor with the idea that you could write code poorly
  24. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev – Ward Cunningham Youtube ‘09 The ability to pay back debt [...] depends upon you writing code that is clean enough to be able to refactor as you come to understand your problem.
  25. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev – Ward Cunningham Youtube ‘09 The ability to pay back debt [...] depends upon you writing code that is clean enough to be able to refactor as you come to understand your problem.
  26. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev – Ward Cunningham twitter ‘09 Dirty code is to technical debt as the pawn broker is to financial debt.
  27. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev – Ward Cunningham twitter ‘09 Dirty code is to technical debt as the pawn broker is to financial debt. Don’t think you are ever going to get your code back.
  28. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt? Ask yourself…
  29. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt? Ask yourself… • Is the code clean? • Is the code tested? • Is there a learning objective or event? • Is there a plan for payback? • Is the business truly informed?
  30. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt? If you say no to even one… • Is the code clean? • Is the code tested? • Is there a learning objective or event? • Is there a plan for payback? • Is the business truly informed?
  31. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt? If you say no to even one… • Is the code clean? • Is the code tested? • Is there a learning objective or event? • Is there a plan for payback? • Is the business truly informed? ... then you don’t have Technical Debt
  32. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev mess (noun)
  33. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev mess (noun) • Disorderly accumulation, heap, or jumble • A state of embarrassing confusion • An unpleasant or difficult situation
  34. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev cruft (noun)
  35. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev cruft (noun) • An unpleasant substance • The result of shoddy construction • Redundant, old or improperly written code
  36. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev But, It’s Just semantics
  37. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev It’s not Just semantics
  38. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev It’s not Just semantics Technical Debt is Good
  39. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev It’s not Just semantics Technical Debt is GoodQuick and Dirty is Technical Debt
  40. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev It’s not Just semantics Quick and Dirty is Good
  41. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev It’s not Just semantics Quick and Dirty is Good
  42. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt quadrant Reckless Inadvertent Prudent Deliberate “We don’t have time for design” “We must ship now and deal with consequences” “Now we know how we should have done it” “What’s Layering?”
  43. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt quadrant Reckless Inadvertent Prudent Deliberate “We don’t have time for design” “Let’s deploy and gather more information” “Now we know how we should have done it” “What’s Layering?”
  44. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt in other fields
  45. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt in other fields
  46. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev Technical Debt in other fields
  47. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev Technical Debt in other fields
  48. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt in other fields
  49. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev RECKLESS AND DELIBERATE technical debt in other fields
  50. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev RECKLESS AND DELIBERATE RECKLESS AND DELIBERATE technical debt in other fields
  51. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev RECKLESS AND DELIBERATE RECKLESS AND DELIBERATE RECKLESS AND INADVERTENT technical debt in other fields
  52. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt quadrant Reckless Inadvertent Prudent Deliberate “We don’t have time for design” “Let’s deploy and gather more information” “Now we know how we should have done it” “What’s Layering?”
  53. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt quadrant Reckless Inadvertent Prudent Deliberate “We don’t have time for design” “Let’s deploy and gather more information” “Now we know how we should have done it” “What’s Layering?” IRRESPONSIBLE
  54. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt quadrant Reckless Inadvertent Prudent Deliberate “We don’t have time for design” “Let’s deploy and gather more information” “Now we know how we should have done it” “What’s Layering?” IRRESPONSIBLE INCOMPETENT
  55. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt quadrant Reckless Inadvertent Prudent Deliberate “We don’t have time for design” “Let’s deploy and gather more information” “Now we know how we should have done it” “What’s Layering?” IRRESPONSIBLE INCOMPETENT TECHNICAL DEBT
  56. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev cruft or debt?
  57. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev DataSet aDs, qDs; aDs = _dbConnector.UpdateAgentList(); qDs = _dbConnector.GetQueueList(); foreach (DataTable aTable in aDs.Tables) { foreach (DataRow aRow in aTable.Rows) { foreach (DataColumn aColumn in aTable.Columns) { DataSet asDs = _dbConnector.GetAgentSkills(aRow[aColumn].ToString());//AgentId foreach (DataTable asTable in asDs.Tables) { foreach (DataRow asRow in asTable.Rows) { foreach (DataColumn asColumn in asTable.Columns) { foreach (DataTable qTable in qDs.Tables) { foreach (DataRow qRow in qTable.Rows) { foreach (DataColumn qColumn in qTable.Columns) { DataSet sqDs = _dbConnector.GetSkillsForQueue(qRow[qColumn].ToString()); foreach (DataTable sqTable in sqDs.Tables) { foreach (DataRow sqRow in sqTable.Rows) { foreach (DataColumn sqColumn in sqTable.Columns) { foreach (string skill in sqRow[sqColumn].ToString().Split(paramDelimStr)) { if (skill == asRow[asColumn].ToString()) { try { _dbConnector.SetAgentQueueSkill(aRow[aColumn].ToString(), qRow[qColumn].ToString(), skill); } catch { continue; } } } } } } } } } } } } } } } cruft or debt?
  58. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev DataSet aDs, qDs; aDs = _dbConnector.UpdateAgentList(); qDs = _dbConnector.GetQueueList(); foreach (DataTable aTable in aDs.Tables) { foreach (DataRow aRow in aTable.Rows) { foreach (DataColumn aColumn in aTable.Columns) { DataSet asDs = _dbConnector.GetAgentSkills(aRow[aColumn].ToString());//AgentId foreach (DataTable asTable in asDs.Tables) { foreach (DataRow asRow in asTable.Rows) { foreach (DataColumn asColumn in asTable.Columns) { foreach (DataTable qTable in qDs.Tables) { foreach (DataRow qRow in qTable.Rows) { foreach (DataColumn qColumn in qTable.Columns) { DataSet sqDs = _dbConnector.GetSkillsForQueue(qRow[qColumn].ToString()); foreach (DataTable sqTable in sqDs.Tables) { foreach (DataRow sqRow in sqTable.Rows) { foreach (DataColumn sqColumn in sqTable.Columns) { foreach (string skill in sqRow[sqColumn].ToString().Split(paramDelimStr)) { if (skill == asRow[asColumn].ToString()) { try { _dbConnector.SetAgentQueueSkill(aRow[aColumn].ToString(), qRow[qColumn].ToString(), skill); } catch { continue; } } } } } } } } } } } } } } }
  59. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev DataSet aDs, qDs; aDs = _dbConnector.UpdateAgentList(); qDs = _dbConnector.GetQueueList(); foreach (DataTable aTable in aDs.Tables) { foreach (DataRow aRow in aTable.Rows) { foreach (DataColumn aColumn in aTable.Columns) { DataSet asDs = _dbConnector.GetAgentSkills(aRow[aColumn].ToString());//AgentId foreach (DataTable asTable in asDs.Tables) { foreach (DataRow asRow in asTable.Rows) { foreach (DataColumn asColumn in asTable.Columns) { foreach (DataTable qTable in qDs.Tables) { foreach (DataRow qRow in qTable.Rows) { foreach (DataColumn qColumn in qTable.Columns) { DataSet sqDs = _dbConnector.GetSkillsForQueue(qRow[qColumn].ToString()); foreach (DataTable sqTable in sqDs.Tables) { foreach (DataRow sqRow in sqTable.Rows) { foreach (DataColumn sqColumn in sqTable.Columns) { foreach (string skill in sqRow[sqColumn].ToString().Split(paramDelimStr)) { if (skill == asRow[asColumn].ToString()) { try { _dbConnector.SetAgentQueueSkill(aRow[aColumn].ToString(), qRow[qColumn].ToString(), skill); } catch { continue; } } } } } } } } } } } } } } }
  60. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev DataSet aDs, qDs, asDs, sqDs; aDs = _dbConnector.UpdateAgentList(); qDs = _dbConnector.GetQueueList(); foreach (DataRow aRow in aDS.Tables[0].Rows) { String agentID = aRow[“AgentId”].ToString(); asDs = _dbConnector.GetAgentSkills(agentID); foreach (DataRow asRow in asDs.Tables[0].Rows) { String agentSkill = asRow[“Skill”].ToString(); foreach (DataRow qRow in qDs.Tables[0].Rows) { queueName = qRow[“QueueName”].ToString(); sqDs = _dbConnector.GetSkillsForQueue(queueName); foreach (DataRow sqRow in sqDs.Tables[0].Rows) { foreach (string skill in sqRow[“Skills”].ToString().Split(paramDelimStr)) { if (skill == agentSkill) { try { _dbConnector.SetAgentQueueSkill(agentID, queueName, skill); } catch { continue; } } } } } } }
  61. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev AgentList agents = new AgentList(_dbConnector.UpdateAgentList()); QueueList queues = new QueueList(_dbConnector.GetQueueList()); foreach (Agent agent in agents) { foreach (Skill agentSkill in agent.skills) { foreach (Queue queue in queues) { foreach (Skill queueSkill in queue.skills.Where(x => x == agentSkill)) { try {_dbConnector.SetAgentQueueSkill(agent.agentID, queue.name, agentSkill); } catch { continue; } } } } }
  62. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev
  63. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev if ((customer.state == “AL” && customer.type == CustomerType.GENERAL_AGENT && customer.revenue > 100000) || (customer.type == CustomerType.RETRO_AGENT && (customer.state == “WI” || customer.state == “IL”)) || (customer.type == CustomerType.FED_MANAGEMENT && customer.revenue > 150000)) { ... } cruft or debt?
  64. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev // If customer is Federally Regulated if ((customer.state == “AL” && customer.type == CustomerType.GENERAL_AGENT && customer.revenue > 100000) || (customer.type == CustomerType.RETRO_AGENT && (customer.state == “WI” || customer.state == “IL”)) || (customer.type == CustomerType.FED_MANAGEMENT && customer.revenue > 150000)) { ... }
  65. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev if (customer.isFederallyRegulated()) { ... }
  66. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev double getSpeed() { switch (_type) { case EUROPEAN: return getBaseSpeed(); case AFRICAN: return getBaseSpeed() - getLoadFactor() * _numberOfCoconuts; case NORWEGIAN_BLUE: return (_isNailed) ? 0 : getBaseSpeed(_voltage); } throw new RuntimeException ("Should be unreachable"); } http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html cruft or debt?
  67. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev class Swallow ... double getSpeed() { return getBaseSpeed(); } end class class EuropeanSwallow ... end class class AfricanSwallow ... double getSpeed() { return super.getSpeed - coconutLoad(); } double coconutLoad() { return getLoadFactor() * _numberOfCoconuts; } end class class NorwegianSwallow ... double getSpeed() { return (_isNailed) ? 0 : getBaseSpeed(_voltage); } end class
  68. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev cruft is a bad decision
  69. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev cruft is a bad decision • You are a professional developer • You’re going to create unintentional cruft • You have to clean up the existing cruft
  70. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev The Trap
  71. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev The Trap • Precedent for speed over quality • Expectation of increased velocity • Cruft slows you down • Must write more cruft to keep up • Ask permission to do your job correctly
  72. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev failing strategies
  73. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev failing strategies
  74. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev winning strategy Clean Constantly
  75. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev winning strategy Clean Constantly • Never make an intentional mess • Monitor your “Technical Debt” • Follow the Boy Scout Rule • Remember quality is your responsibility
  76. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev winning strategy Clean Constantly • Never make an intentional mess • Monitor your “Technical Debt” • Follow the Boy Scout Rule • Remember quality is your responsibility • NEVER ask permission to do your job correctly
  77. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev Monitor your cruft
  78. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev Monitor your cruft • Code Coverage • Code Complexity • Coupling • Maintainability • Monitor Trends, Not Points
  79. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev review Technical Debt Cruft
  80. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev review Technical Debt • A strategic design decision • Requires business to be informed • Includes a pay-back plan Cruft • Happens • Needs to be monitored and cleaned • Is NOT Technical Debt
  81. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev review Technical Debt • A strategic design decision • Requires business to be informed • Includes a pay-back plan Cruft • Happens • Needs to be monitored and cleaned • Is NOT Technical Debt NEVER ask perm issio n to do yo ur jo b co rrectly
  82. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev comments or questions? Doc Norton, CEO doc@wearecto2.com @DocOnDev
  83. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev Thank You! Doc Norton, CEO doc@wearecto2.com @DocOnDev
  84. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev The technical Debt Trap
  85. #DevBootcamp / #TechnicalDebtTrap / @DocOnDev • OOPSLA 92 Paper - http://dl.acm.org/citation.cfm? id=157715, http://c2.com/doc/oopsla92.html • Ward Cunningham Technical Debt Video - http:// www.youtube.com/watch? v=pqeJFYwnkjE&feature=player_embedded • Ward Cunningham Twitter - http://twitter.com/ WardCunningham/status/3742903303 • Technical Debt Quadrant - http://martinfowler.com/ bliki/TechnicalDebtQuadrant.html • James Shore - http://jamesshore.com/Blog/ CardMeeting/Voluntary-Technical-Debt.html • Martin Fowler - http://www.martinfowler.com/bliki/ TechnicalDebt.html • David Larabee - http://msdn.microsoft.com/en-us/ magazine/ee819135.aspx • Steve McConnell - http://blogs.construx.com/blogs/ stevemcc/archive/2007/11/01/technical-debt-2.aspx • Jon Stewart - http://big.assets.huffingtonpost.com/ JonConfused.gif • Cruft Example 1 - http://thedailywtf.com/Series/ 2010/3/CodeSOD.aspx • Debt Threshold - http://blog.castsoftware.com/wp- content/uploads/2011/04/Technical-Debt-Software- Quality1.jpg • Hardening Sprints - http://blog.castsoftware.com/wp- content/uploads/2011/04/Technical-Debt-Software- Quality1.jpg
Anzeige