Agile 2012 Simple Design Applied
-
Upload
declan-whelan -
Category
Self Improvement
-
view
1.625 -
download
5
description
Transcript of Agile 2012 Simple Design Applied
Simple Design Applied Spend more time creating
valuable code
Declan Whelan @dwhelan
Alistair McKinnell@mckinnell
Exercise
On an index card write up to three facts on an index card.
Be ready to share with your table.
What is Simple Design?
At your table gather the facts and count how many distinct
facts you came up with.
What is Simple Design?
Introductions
?
www.XProgramming.com
Exercise
At your table order the rules of simple design in
priority order.
Simple Design
1. All tests must pass2. No code is duplicated3. Code is self-explanatory4. No superfluous parts exist
Simple Design
1. All tests must pass2. No code is duplicated3. Code is self-explanatory4. No superfluous parts exist
Simple Design
1. Passes its tests2. No code is duplicated3. Code is self-explanatory4. No superfluous parts exist
Simple Design
1. Passes its tests2. Minimizes duplication3. Code is self-explanatory4. No superfluous parts exist
Simple Design
1. Passes its tests2. Minimizes duplication3. Maximizes clarity4. No superfluous parts exist
Simple Design
1. Passes its tests2. Minimizes duplication3. Maximizes clarity4. Has fewer elements
Simple Design
1. Passes its tests (given TDD)2. Minimizes duplication3. Maximizes clarity4. Has fewer elements
Simple Design
1. Passes its tests (given TDD)2. Minimizes duplication3. Maximizes clarity (fix names)4. Has fewer elements
Simple Design
1. Passes its tests (given TDD)2. Minimizes duplication3. Maximizes clarity (fix names)4. Has fewer elements
Simple Design
That leaves me with two key elementsof simple design: remove duplication and fix bad names. When I remove duplication, I tend to seean appropriate structure emerge, and whenI fix bad names, I tend to see responsibilities slide into appropriate parts of the design.
J. B. Rainsberger
• Remove duplication• Fix bad names
Simple Design
• Fix bad names
Simple Design(for today)
Choosing good names❤• Remove duplication
Commonality & Variability❤
Exercise
Stroop Effect
Green Red BluePurple Blue Purple
Blue Purple RedGreen Purple Green
Green Red BluePurple Blue Purple
blackyellow
Meaning:
Colour:
blueblack
Meaning:
Colour:
blackyellow
yellowred
redyellow
redyellow
blueblue
yellowblue
redred
bluered
yellowyellow
redyellow
redyellow
blueblack
yellowblack
blackblue
redblack
TheEnd
Exercise
CComBstr sVal $.getJSON() int result
Rx rx applyMeasureConstraintToEnableSortingByMeasure() float hp
applyPhq9DateRangeConstraint() public void run() Date genymdhms
m_name Label label IShapeFactory
Customer int i RollOverPerformanceIndicatorsToNextMonthTask
CustomerManager LPSTR lpCmdLine int daysSinceModification
boolean fNewPage UpdatePerfIndValueDecCountCmd DepressionSelfManagementCalculator
PerfIndValueDecCountForMatchingIvpCmd PulseRenderer IndexCardPageLayout sut
Tutorial02
CComBstr sVal $.getJSON() int result
Rx rx applyMeasureConstraintToEnableSortingByMeasure() float hp
applyPhq9DateRangeConstraint() public void run() Date genymdhms
m_name Label label IShapeFactory
Customer int i RollOverPerformanceIndicatorsToNextMonthTask
CustomerManager LPSTR lpCmdLine int daysSinceModification
boolean fNewPage UpdatePerfIndValueDecCountCmd DepressionSelfManagementCalculator
PerfIndValueDecCountForMatchingIvpCmd PulseRenderer IndexCardPageLayout sut
Tutorial02
Find a partner and each of you:
1. select a name you thought was good2. explain why to your partner3. select a name you thought was bad4. explain why to your partner
CComBstr sVal $.getJSON() int result
Rx rx applyMeasureConstraintToEnableSortingByMeasure() float hp
applyPhq9DateRangeConstraint() public void run() Date genymdhms
m_name Label label IShapeFactory
Customer int i RollOverPerformanceIndicatorsToNextMonthTask
CustomerManager LPSTR lpCmdLine int daysSinceModification
boolean fNewPage UpdatePerfIndValueDecCountCmd DepressionSelfManagementCalculator
PerfIndValueDecCountForMatchingIvpCmd PulseRenderer IndexCardPageLayout sut
Choosing Good Names
Choosing Good Names
Use the telephone test for readability. If someone could understand your code when read aloud over the telephone, it's clear enough. If not, then it needs rewriting.
Telephone Test
Goal Donor vs Gold Owner
Date genymdhms
Choosing Good Names
Splitters can be lumped more easily than lumpers can be split.It is easier to combine two concepts that it is to separate them.
Splitting a Lumper
Customer Address
Customer Address
Billing Address Mailing Address Service Address
Splitting a Lumper
Billing Address Mailing Address Service Address
Lumping a Splitter
Customer Address
Billing Address Mailing Address Service Address
Lumping a Splitter
Choosing Good Names
Pronounceable NamesAvoid Encodings
UpdatePerfIndValueDecCountCmd
Pronounceable Names
UpdatePerfIndValueDecCountCmd
DecrementAggregateCommand
Pronounceable Names
Date genymdhms
Pronounceable Names
Date genymdhms
Date generatedTimestamp
Pronounceable Names
LPSTR lpCmdLine
m_name
Avoid Encodings
LPSTR commandLine
name
Choosing Good Names
Intention-Revealing NameRole-Suggesting Name
Intention-Revealing Name
applyMeasureConstraintTo EnableSortingByMeasure()
Intention-Revealing Name
applyMeasureConstraintTo EnableSortingByMeasure()
applyMeasureConstraint()
Role-Suggesting Name
int result
IndexCardPageLayout sut
Choosing Good Names
Ubiquitous Language
CComBstr sVal
Ubiquitous Language
CComBstr sVal
CComBstr calibrationToolName
Ubiquitous Language
Rx rx
Ubiquitous Language
Rx rx
Rx refillable
Ubiquitous Language
applyPhq9DateRangeConstraint()
Ubiquitous Language
The PHQ-9 is the nine item depression scale of the Patient Health Questionnaire.
The PHQ-9 is a powerful tool for assisting primary care clinicians in diagnosing depression as well as selecting and monitoring treatment.
Agile in a FlashSpeed-Learning Agile
Software Development
Jeff Langr andTim Ottinger
edited by Susannah Pfalzer
PragmaticProgrammers
Agile Cards for Agile Teams
Prepared exclusively for Alistair McKinnell Copyright ©2011 Pragmatic Programmers
43 Really Meaningful Names
! Are accurate
! Are purposeful
! Are pronounceable
! Begin well
! Are simple
! Depend on context
! Match name length to scope
Prepared exclusively for Alistair McKinnell Copyright ©2011 Pragmatic Programmers
Alistair McKinnell @amckinnell Declan Whelan @dwhelanNaming Guidelines v1.0 August 2012 ! 1/1
Naming'GuidelinesSystem'of'Names
S1# # Name#pass#the#“telephone”#test.
S2# # There#is#a#clean#name#for#each#concept.#Remember:#later#on#it’s#easier#to#lump#things#together#than#to#split#them#apart.
S3# # Name#is#from#the#problem#or#solu?on#domain#and#support#ubiquitous#language#for#the#team
GeneralG1## Name#is#pronounceable.
G2## Name#avoids#encodings#and#member#prefixes.
G3## Name#suggest#why#it#exists.
G4## Name#suggest#how#it#should#be#used.
G5## Name#suggest#what#it#does.
G6## Name#is#easily#searchable#in#the#code#base.
ClassesC1# If#this#is#an#important#base#class#its#class#name#should#be#a#simple#single#word.
C2# If#this#is#a#subclass#its#class#name#suggests#how#it#differs#from#its#superclass.
C3# The#class#name#is#a#noun#or#a#noun#phrase.
MethodsM1# The#method#name#suggests#why#it#would#be#called.
M2# The#method#is#name#a#verb#or#a#verb#phrase.
Variables/Fields/ArgumentsV1# Its#name#indicate#the#role#it's#playing.
V2# The#length#of#the#name#reflect#its#scope.
Choosing Good Names•Locate one guideline that if applied would have the biggest impact on your code
•Find a partner•Discuss
Choosing Good Namespublic List<int[]> getThem() { List<int[]> list1 = new ArrayList<int[]>();
for (int[] x : theList) if (x[0] == 4) list1.add(x);
return list1;}
Source: Clean Code: A Handbook of Agile Software Craftsmanship, Robert C. Martin, pages 18-19
public List<int[]> getFlaggedCells() { List<int[]> flaggedCells = new ArrayList<int[]>();
for (int[] cell : gameBoard) if (cell[STATUS_VALUE] == FLAGGED) flaggedCells.add(cell);
return flaggedCells;}
public List<int[]> getThem() { List<int[]> list1 = new ArrayList<int[]>();
for (int[] x : theList) if (x[0] == 4) list1.add(x);
return list1;}
Source: Clean Code: A Handbook of Agile Software Craftsmanship, Robert C. Martin, pages 18-19
Choosing Good Names
public List<Cell> getFlaggedCells() { List<Cell> flaggedCells = new ArrayList<Cell>();
for (Cell cell : gameBoard) if (cell.isFlagged()) flaggedCells.add(cell);
return flaggedCells;}
public List<int[]> getThem() { List<int[]> list1 = new ArrayList<int[]>();
for (int[] x : theList) if (x[0] == 4) list1.add(x);
return list1;}
Source: Clean Code: A Handbook of Agile Software Craftsmanship, Robert C. Martin, pages 18-19
Choosing Good Names
public List<Cell> getFlaggedCells() { List<Cell> result = new ArrayList<Cell>();
for (Cell cell : gameBoard) if (cell.isFlagged()) result.add(cell);
return result;}
public List<int[]> getThem() { List<int[]> list1 = new ArrayList<int[]>();
for (int[] x : theList) if (x[0] == 4) list1.add(x);
return list1;}
Source: Clean Code: A Handbook of Agile Software Craftsmanship, Robert C. Martin, pages 18-19
Choosing Good Names
Choosing Good Names
int realDaysPerIdealDay = 4;const int WORK_DAYS_PER_WEEK = 5;int sum = 0;
for (int j=0; j < NUMBER_OF_TASKS; j++) { int realTaskDays = taskEstimate[j] * realDaysPerIdealDay; int realTaskWeeks = (realdays / WORK_DAYS_PER_WEEK); sum += realTaskWeeks;}
int s = 0;
for (int j=0; j<34; j++) { s += (t[j]*4)/5;}
const int EFFECTIVE_DAYS_PER_WEEK = 4;const int WORKING_DAYS_PER_WEEK = 5;
int effectiveTotalEstimate = 0;
for (int j=0; j < NUMBER_OF_TASKS; j++) { int effectiveTaskEstimate = taskEstimate[j] * EFFECTIVE_DAYS_PER_WEEK / WORKING_DAYS_PER_WEEK; effectiveTotalEstimate += effectiveTaskEstimate;}
Source: Clean Code: A Handbook of Agile Software Craftsmanship, Robert C. Martin, page 23
What’s In A Name?
Moonbeam Zappa
All tests must pass No code is duplicated
Code is self-explanatory No superfluous parts exist
No code is duplicated
Exercise
How do you handle duplicate code
in your codebase?
DRY: Don’t Repeat YourselfEvery piece of knowledge must have a single, unambiguous, authoritative representation within a system.
Avoiding Duplicate Code
Avoiding Duplicate Code
Once and Only OnceData, structure, or logic should exist in only one place in the system.
Avoiding Duplicate Code
Test-Driven Development1. Write new code only if an
automated test has failed.2. Eliminate duplication.
Single Choice PrincipleWhenever a software system must support a set of alternatives, one and only one module in the system should know their exhaustive list.
Avoiding Duplicate Code
Duplication may be the root of all evil in software.
Avoiding Duplicate Code
Commonality and Variability
Copy & Paste
function something() {
}
function something() {
}
function something() {
}
function somethingElse() {
}
function something() {
}
function somethingElse() {
}
function something() {
}
Duplicate Code
Copy & Paste
☞ Duplicate CodeEdit the Copy
Duplicate Code
Avoid duplication by expressing commonality and variability
explicitly.
function somethingElse() {
}
function something() {
}
Duplicate Code: Select Options
Can you spot the duplicate code?
How would you make the commonality and variation explicit?
Can you spot the commonality and variation?
public static List<SelectOption> createEndMonthList(Date expiryDate) { int selectedMonth = getDateMonth(expiryDate);
SelectOptionsSource months = new SelectOptionsSource(1, 12, selectedMonth); SelectOptions monthOptions = new SelectOptions(months);
return monthOptions.create();}
public static List<SelectOption> createEndDaysList() { int selectedDay = getDateDay(getCurrentDatePlus14Days());
SelectOptionsSource days = new SelectOptionsSource(1, 31, selectedDay); SelectOptions dayOptions = new SelectOptions(days);
return dayOptions.create();}
public static List<SelectOption> createEndYearList() { int selectedYear = getDateYear(getCurrentDatePlus14Days());
SelectOptionsSource years = new SelectOptionsSource(1985, 1985 + 30, selectedYear); SelectOptions yearOptions = new SelectOptions(years);
return yearOptions.create();}
public static List<SelectOption> createEndMonthList(Date expiryDate) { int selectedMonth = getDateMonth(expiryDate);
SelectOptionsSource months = new SelectOptionsSource(1, 12, selectedMonth); SelectOptions monthOptions = new SelectOptions(months);
return monthOptions.create();}
public static List<SelectOption> createEndDaysList() { int selectedDay = getDateDay(getCurrentDatePlus14Days());
SelectOptionsSource days = new SelectOptionsSource(1, 31, selectedDay); SelectOptions dayOptions = new SelectOptions(days);
return dayOptions.create();}
public static List<SelectOption> createEndYearList() { int selectedYear = getDateYear(getCurrentDatePlus14Days());
SelectOptionsSource years = new SelectOptionsSource(1985, 1985 + 30, selectedYear); SelectOptions yearOptions = new SelectOptions(years);
return yearOptions.create();}
public static List<SelectOption> createEndMonthList(Date expiryDate) { int selectedMonth = getDateMonth(expiryDate);
SelectOptionsSource months = new SelectOptionsSource(1, 12, selectedMonth); SelectOptions monthOptions = new SelectOptions(months);
return monthOptions.create();}
public static List<SelectOption> createEndDaysList() { int selectedDay = getDateDay(getCurrentDatePlus14Days());
SelectOptionsSource days = new SelectOptionsSource(1, 31, selectedDay); SelectOptions dayOptions = new SelectOptions(days);
return dayOptions.create();}
public static List<SelectOption> createEndYearList() { int selectedYear = getDateYear(getCurrentDatePlus14Days());
SelectOptionsSource years = new SelectOptionsSource(1985, 1985 + 30, selectedYear); SelectOptions yearOptions = new SelectOptions(years);
return yearOptions.create();}
Select Options
create()
SelectOptions
create()
SelectOptions
getFirst()getLast()isSelected()
SelectOptionsSource
Commonality Variability Resolution
Behaviour Collaborator Encapsulate Collection
Select Options
Commonality Variability Resolution
Data Structure Value of State Simple Java Type
getFirst()getLast()isSelected()
SelectOptionsSource
create()
SelectOptions
Select Options
create()
SelectOptions
Encapsulate Collection
create()
SelectOptions
getFirst()getLast()isSelected()
SelectOptionsSource
Select Options
getFirst()getLast()isSelected()
SelectOptionsSource
create()
SelectOptions
ParameterObject
Duplicate Code: Compound Result Handler
Can you spot the duplicate code?
How would you make the commonality and variation explicit?
Can you spot the commonality and variation?
if ( ... ) {
} else {
}
Compound Result HandlerisNegative()isPositive()
CompoundResultClassifier
toNumber()
AbstractCompoundResultClassifier
isNegative()isPositive()
QueensCompoundResultClassifier
isNegative()isPositive()
StandardCompoundResultClassifier
CompoundResultHandler
Compound Result HandlerisNegative()isPositive()
CompoundResultClassifier
toNumber()
AbstractCompoundResultClassifier
isNegative()isPositive()
QueensCompoundResultClassifier
isNegative()isPositive()
StandardCompoundResultClassifier
CompoundResultHandler
Compound Result Handler
Commonality Variability Resolution
Behaviour Implementation Inheritance(Object-Oriented)
isNegative()isPositive()
CompoundResultClassifier
toNumber()
AbstractCompoundResultClassifier
isNegative()isPositive()
QueensCompoundResultClassifier
isNegative()isPositive()
StandardCompoundResultClassifier
CompoundResultHandler
isNegative()isPositive()
CompoundResultClassifier
toNumber()
AbstractCompoundResultClassifier
isNegative()isPositive()
QueensCompoundResultClassifier
isNegative()isPositive()
StandardCompoundResultClassifier
CompoundResultHandler
Commonality Variability Resolution
Behaviour Implementation Inheritance(Object-Oriented)
Compound Result Handler
Compound Result HandlerisNegative()isPositive()
CompoundResultClassifier
toNumber()
AbstractCompoundResultClassifier
isNegative()isPositive()
QueensCompoundResultClassifier
isNegative()isPositive()
StandardCompoundResultClassifier
CompoundResultHandler
Commonality Variability Resolution
Implementation None Base Class
Compound Result HandlerisNegative()isPositive()
CompoundResultClassifier
toNumber()
AbstractCompoundResultClassifier
isNegative()isPositive()
QueensCompoundResultClassifier
isNegative()isPositive()
StandardCompoundResultClassifier
CompoundResultHandler
Commonality Variability Resolution
Implementation None Base Class
Factory
Compound Result Handlerpublic static CompoundResultClassifier createCompoundResultClassifier( Patient sourcePatient) { return isRegisteredAtQueens(sourcePatient) ? QUEENS : STANDARD;}
private static boolean isRegisteredAtQueens(Patient sourcePatient) { return sourcePatient.getDataWarehouse().equals(DataWarehouseTag.QHN);}
Avoiding Duplicate Code
Commonality and Variability
Duplicate Code
Copy & Paste
☞ Duplicate CodeEdit the Copy
Duplicate Code
Avoid duplication by expressing commonality and variability
explicitly.
All tests must pass No code is duplicated
Code is self-explanatory No superfluous parts exist
0 10 20 30 40 50 60 70 80
0 10 20 30 40 50 60 70 80
0 10 20 30 40 50 60 70 80
0 10 20 30 40 50 60 70 80
“The prime directive that was unanimously agree upon by allpresent was that in the nexttens years Agile leaders must
Demand Technical Excellence.”
Jeff Sutherland
“Failure to do that meansyou are not an Agile leader.”
Jeff Sutherland
Personal Action Plan
ReadingThe Elements of Programming StyleKernighan and Plauger
PrefactoringExtreme Abstraction Extreme Separation Extreme ReadabilityKen Pugh
Agile in a FlashSpeed-Learning Agile
Software Development
Jeff Langr andTim Ottinger
edited by Susannah Pfalzer
PragmaticProgrammers
Agile Cards for Agile Teams
Prepared exclusively for Alistair McKinnell
Agile in a FlashSpeed-Learning Agile DevelopmentJeff Langr and Tim Ottinger
ReadingClean CodeA Handbook of Agile Software CraftsmanshipRobert C. Martin
Domain Driven DesignTackling Complexity in the Heart of SoftwareEric Evans
Implementation PatternsKent Beck
ReadingThe Pragmatic Programmer: From Journeyman to MasterAndrew Hunt and Dave Thomas
Extreme Programming Explained: Embrace ChangeKent Beck and Cynthia Andres
Test Driven Development: By ExampleKent Beck
Object-Oriented Software ConstructionBertrand Meyer
ReadingDesign Patterns: Elements of Reusable Object-Oriented Software Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides
Multi-Paradigm Design for C++James O. Coplien
Lean Architecture: for Agile Software DevelopmentJames O. Coplien and Gertrud Bjørnvig
Photo Creditshttp://www.flickr.com/photos/27558040@N00/4151899795/
http://www.flickr.com/photos/popilop/331357312/
http://www.flickr.com/photos/arlette/3260468/
http://www.flickr.com/photos/36829973@N04/3546657245/
http://www.flickr.com/photos/40838054@N00/7261734660/