The Technical Debt Trap


The Presentation inside:

Slide 0

The technical Debt Trap #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 1

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev Doc Norton, CEO [email protected] @DocOnDev


Slide 2

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev what is technical debt?


Slide 3

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev Shipping first time code is like going into debt. – Ward Cunningham OOPSLA ‘92


Slide 4

#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


Slide 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. 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


Slide 6

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev The danger occurs when the debt is not repaid. Every minute spent on not-quiteright code counts as interest on that debt. – Ward Cunningham OOPSLA ‘92


Slide 7

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev The danger occurs when the debt is not repaid. Every minute spent on not-quiteright code counts as interest on that debt. – Ward Cunningham OOPSLA ‘92


Slide 8

Technical debt is #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 9

Technical debt is good #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 10

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev Technical debt is good


Slide 11

Technical debt is good #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 12

Technical debt is a strategic decision #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 13

Technical debt is a strategic decision • Allow for Rapid Delivery • To Elicit Quick Feedback • And Correct Design #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 14

technical debt is an indication of learning #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 15

technical debt is an indication of learning • Now know what you need • Implementation doesn’t match #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 16

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt is a metaphor


Slide 17

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev Can’t keep running at this pace Puts pressure on our design a n o ion ng at di nd il u B u fo k ea w It’s raining men (hallelujah) metaphors rock we reason by analogy


Slide 18

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev SHORT-TERMCredit HIGH INTEREST Card Loan Shark INADVERTENT AUTO LOAN RECKLESS DEBT IN FRAUDULENT Long-Term Prudent THE THIRD Student Loan P Return on QUADRANT L Investment Intentional PYRAMID SCHEME RAGMATIC EVERAGE HOME LOAN VOLUNTARY OPERATIONAL metaphorphosis when metaphors go wrong


Slide 19

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev “CUT A LOT OF CORNERS” - James Shore “quick and dirty” - Martin Fowler “just hack it in” - Steve McConnell “sloppy” - David Laribee metaphorphosis when metaphors go wrong


Slide 20

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev Deliberate “We don’t have time for design” “We must ship now and deal with consequences” Reckless Prudent “What’s Layering?” “Now we know how we should have done it” Inadvertent technical debt quadrant


Slide 21

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev [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. – Ward Cunningham Youtube ‘09


Slide 22

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev confused the debt metaphor with the idea that you could write code poorly – Ward Cunningham Youtube ‘09


Slide 23

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev 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. – Ward Cunningham Youtube ‘09


Slide 24

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev 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. – Ward Cunningham Youtube ‘09


Slide 25

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev Dirty code is to technical debt as the pawn broker is to financial debt. – Ward Cunningham twitter ‘09


Slide 26

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev 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. – Ward Cunningham twitter ‘09


Slide 27

technical debt? Ask yourself… #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 28

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? #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 29

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? #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 30

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 #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 31

mess (noun) #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 32

mess (noun) • Disorderly accumulation, heap, or jumble • A state of embarrassing confusion • An unpleasant or difficult situation #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 33

cruft (noun) #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 34

cruft (noun) • An unpleasant substance • The result of shoddy construction • Redundant, old or improperly written code #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 35

But, It’s Just semantics #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 36

It’s not Just semantics #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 37

It’s not Just semantics Technical Debt is Good #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 38

It’s not Just semantics Quick and Dirty is Technical Debt is Good #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 39

It’s not Just semantics Quick and Dirty is Good #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 40

It’s not Just semantics Quick and Dirty is Good #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 41

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev Deliberate “We don’t have time for design” “We must ship now and deal with consequences” Reckless Prudent “What’s Layering?” “Now we know how we should have done it” Inadvertent technical debt quadrant


Slide 42

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev Deliberate “We don’t have time for design” “Let’s deploy and gather more information” Reckless Prudent “What’s Layering?” “Now we know how we should have done it” Inadvertent technical debt quadrant


Slide 43

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt in other fields


Slide 44

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt in other fields


Slide 45

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev Technical Debt in other fields


Slide 46

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev Technical Debt in other fields


Slide 47

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt in other fields


Slide 48

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt in other fields TE RA E R L CK E S ES IB EL D D AN


Slide 49

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt in other fields TE RA E L CK E R S ES IB EL D D AN TE RA E R KL EC S ES IB EL D D AN


Slide 50

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev technical debt in other fields TE RA E CK E R SS LE ND A AD IN NT TE ER V L CK E R S ES IB EL D D AN TE RA E R KL EC S ES IB EL D D AN


Slide 51

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev Deliberate “We don’t have time for design” “Let’s deploy and gather more information” Reckless Prudent “What’s Layering?” “Now we know how we should have done it” Inadvertent technical debt quadrant


Slide 52

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev Deliberate Reckless LE “We don’t have SIB time N for design” O P ES R IR “What’s Layering?” “Let’s deploy and gather more information” Prudent “Now we know how we should have done it” Inadvertent technical debt quadrant


Slide 53

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev Deliberate Reckless LE “We don’t have SIB time N for design” O P ES R IR T N E “What’s Layering?” M O C T E P IN “Let’s deploy and gather more information” Prudent “Now we know how we should have done it” Inadvertent technical debt quadrant


Slide 54

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev Deliberate Reckless LE “We don’t have SIB time N for design” O P ES R IR T N E “What’s Layering?” M O C T E P IN “Let’s deploy and gather more information” L A IC N H T C B E E T D “Now we know how we Prudent should have done it” Inadvertent technical debt quadrant


Slide 55

cruft or debt? #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 56

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? #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 57

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; } } } } } } } } } } } } } } } #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 58

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; } } } } } } } } } } } } } } } #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 59

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; } } } } } } } #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 60

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; } } } } } #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 61

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 62

cruft or debt? 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)) { ... } #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 63

// 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)) { ... } #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 64

if (customer.isFederallyRegulated()) { ... } #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 65

cruft or debt? 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"); } #DevBootcamp / #TechnicalDebtTrap / @DocOnDev http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html


Slide 66

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 #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 67

cruft is a bad decision #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 68

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 #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 69

The Trap #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 70

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 #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 71

failing strategies #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 72

failing strategies #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 73


Slide 74

winning strategy Clean Constantly #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 75

winning strategy Clean Constantly • Never make an intentional mess • Monitor your “Technical Debt” • Follow the Boy Scout Rule • Remember quality is your responsibility #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 76

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 #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 77

Monitor your cruft #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 78

Monitor your cruft • Code Coverage • Code Complexity • Coupling • Maintainability • Monitor Trends, Not Points #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 79

review Technical Debt Cruft #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 80

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 #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 81

review Technical Debt o j b o c r u • A strategic design decision o y • Requires business to o informed be d • Includes a pay-back plan o t n Cruft io • Happens s is mto be monitored and cleaned • Needs r e p • k NOT Technical Debt Is s a R E V #DevBootcamp / #TechnicalDebtTrap / @DocOnDev E N y l t c e r r


Slide 82

comments or questions? #DevBootcamp / #TechnicalDebtTrap / @DocOnDev Doc Norton, CEO [email protected] @DocOnDev


Slide 83

Thank You! #DevBootcamp / #TechnicalDebtTrap / @DocOnDev Doc Norton, CEO [email protected] @DocOnDev


Slide 84

The technical Debt Trap #DevBootcamp / #TechnicalDebtTrap / @DocOnDev


Slide 85

#DevBootcamp / #TechnicalDebtTrap / @DocOnDev • OOPSLA 92 Paper - http://dl.acm.org/citation.cfm? id=157715, http://c2.com/doc/oopsla92.html • Steve McConnell - http://blogs.construx.com/blogs/ stevemcc/archive/2007/11/01/technical-debt-2.aspx • Ward Cunningham Technical Debt Video - http:// www.youtube.com/watch? v=pqeJFYwnkjE&feature=player_embedded • 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/wpcontent/uploads/2011/04/Technical-Debt-SoftwareQuality1.jpg • Hardening Sprints - http://blog.castsoftware.com/wpcontent/uploads/2011/04/Technical-Debt-SoftwareQuality1.jpg • 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


Slide 86


×

HTML:





Ссылка: