Simple Design
Declan Whelan
@dwhelan
Simple Design
Declan Whelan
@dwhelan
“Scrum is not a process or
a technique for building products;
rather, it is a framework within
which you can employ various
processes and techniques.”
Scrum Guide
www.XProgramming.com
red circle contains requirementsred circle contains requirements
green circle crates a container to
enable inner practices to be
successful
green circle crates a container to
enable inner practices to be
successful
day-to-day engineering practicesday-to-day engineering practices
Engineering Practices Matter
Simple Design
Simple Design
TestedTested
ClearClear
DryDry
SuccinctSuccinct
Simple Design
TestedTested
ClearClear
DryDry
SuccinctSuccinct
What is TDD?
• Simple, high-feedback
incremental coding technique
• Write tests as specs, prior
to code
• Immediate feedback from
test execution
TDD Rules
1.Test everything that could possibly
break.
2.Do not write any production code
until you have written the code that
will test it.
3.Code is not checked in until all unit
tests pass.
TDD Rhythm
Exercise
public static List<SelectOption> createEndDaysList() { List<SelectOption>
daysList = new ArrayList<SelectOption>(); Date dt = getCurrentDatePlus14Days();
int day = getDateDay(dt); for (int intLooper = 1; intLooper <= 31; intLooper++)
{ SelectOption option = new SelectOption(); if (day == intLooper) {
option.setLabel(String.valueOf(intLooper));
option.setValue(String.valueOf(intLooper)); option.setSelected(true);
} else { option.setLabel(String.valueOf(intLooper));
option.setValue(String.valueOf(intLooper)); option.setSelected(false);
} daysList.add(option); } return daysList;}public static
List<SelectOption> createEndMonthList(Date expiryDate) { List<SelectOption>
monthList = new ArrayList<SelectOption>(); int month = getDateMonth(expiryDate);
for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option
= new SelectOption(); if (month == intLooper)
{ option.setLabel(String.valueOf(intLooper));
option.setValue(String.valueOf(intLooper)); option.setSelected(true);
} else { option.setLabel(String.valueOf(intLooper));
option.setValue(String.valueOf(intLooper)); option.setSelected(false);
} monthList.add(option); } return monthList;}
public static List<SelectOption> createEndDaysList() { List<SelectOption>
daysList = new ArrayList<SelectOption>(); Date dt = getCurrentDatePlus14Days();
int day = getDateDay(dt); for (int intLooper = 1; intLooper <= 31; intLooper++)
{ SelectOption option = new SelectOption(); if (day == intLooper) {
option.setLabel(String.valueOf(intLooper));
option.setValue(String.valueOf(intLooper)); option.setSelected(true);
} else { option.setLabel(String.valueOf(intLooper));
option.setValue(String.valueOf(intLooper)); option.setSelected(false);
} daysList.add(option); } return daysList;}public static
List<SelectOption> createEndMonthList(Date expiryDate) { List<SelectOption>
monthList = new ArrayList<SelectOption>(); int month = getDateMonth(expiryDate);
for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option
= new SelectOption(); if (month == intLooper)
{ option.setLabel(String.valueOf(intLooper));
option.setValue(String.valueOf(intLooper)); option.setSelected(true);
} else { option.setLabel(String.valueOf(intLooper));
option.setValue(String.valueOf(intLooper)); option.setSelected(false);
} monthList.add(option); } return monthList;}
• Find a Partner
• Write pseudo code for tests
you would write
Simple Design
TestedTested
ClearClear
DryDry
SuccinctSuccinct
Exercise
Stroop Effect
Green Red Blue
Purple Blue Purple
Blue Purple Red
Green Purple Green
The Stroop Effect
first set of words is easy to
comprehend.
takes people much longer for
people to comprehend the
correct meaning in the second
case
The Stroop Effect
first set of words is easy to
comprehend.
takes people much longer for
people to comprehend the
correct meaning in the second
case
“semantic interference” where
naming is incongruent with
meaning.
“semantic interference” where
naming is incongruent with
meaning.
This is because of “semantic
facilitation” where name is
congruent with meaning.
- people much faster at naming
the ink color
This is because of “semantic
facilitation” where name is
congruent with meaning.
- people much faster at naming
the ink color
IDE’s leverage this with syntax
colouring.
IDE’s leverage this with syntax
colouring.
Green Red Blue
Purple Blue Purple
black
yellow
Meaning:
Colour:
1. look at top and understand its
meaning
2. look at actual coluor
MATCH - if ink colour of bottom
word matches word at top
NOMATCH
1. look at top and understand its
meaning
2. look at actual coluor
MATCH - if ink colour of bottom
word matches word at top
NOMATCH
blue
black
Meaning:
Colour:
black
yellow
yellow
red
red
yellow
red
yellow
blue
blue
yellow
blue
red
red
blue
red
yellow
yellow
red
yellow
red
yellow
blue
black
yellow
black
black
blue
red
black
The
End
Debrief:
any change as you went longer?
any easier - maybe a little but
still very tiring.
Debrief:
any change as you went longer?
any easier - maybe a little but
still very tiring.
This is like reading code when you
read code and the names of things
are incongruent with their meaning,
We have to keep reminding ourselves
‘oh yeah this is the Foo class and it
actually does Bar”
This is like reading code when you
read code and the names of things
are incongruent with their meaning,
We have to keep reminding ourselves
‘oh yeah this is the Foo class and it
actually does Bar”
Its WAY harder to understand
code that has poorly chosen
names.
Its WAY harder to understand
code that has poorly chosen
names.
We have to choose a lot names
esp. with trends towards smaller
classes and methods.
We have to choose a lot names
esp. with trends towards smaller
classes and methods.
A lot of value in putting energy
into names
A lot of value in putting energy
into names
Choosing Good NamesChoosing Good Names
Choosing Good NamesChoosing 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 TestTelephone Test
Goal Donor vs Gold Owner
Date genymdhmsWe want to promote conversation
about code.
We want to promote conversation
about code.
Pronounceable Names
Avoid Encodings
Choosing Good NamesChoosing Good Names
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
Used to make sense.
IDEs now help with type and scope
- don’t need to have names reflect
types.
Used to make sense.
IDEs now help with type and scope
- don’t need to have names reflect
types.
Not so important to embed types or scope
information in the variable.
IDEs help
Not such a problem with small names.
Not so important to embed types or scope
information in the variable.
IDEs help
Not such a problem with small names.
Choosing Good NamesChoosing Good Names
Intention-Revealing
Name
Role-Suggesting NamePattern to guide each decision.
Derived a pattern for each
programming decision he made.
Pattern to guide each decision.
Derived a pattern for each
programming decision he made.
Intention-Revealing Name
applyMeasureConstraintTo
EnableSortingByMeasure()
Think about method names based on how they will look in calling code.
Why was this method invoked and not some other? That is a question
that can profitably be answered by the name of the method. The calling
method should be telling a story. Name methods so they help tell that
story.
Kent Beck - pg 79
Think about method names based on how they will look in calling code.
Why was this method invoked and not some other? That is a question
that can profitably be answered by the name of the method. The calling
method should be telling a story. Name methods so they help tell that
story.
Kent Beck - pg 79
Intention-Revealing Name
applyMeasureConstraintTo
EnableSortingByMeasure()
applyMeasureConstraint()
Role-Suggesting Name
int result
IndexCardPageLayout sut
Choosing Good NamesChoosing Good Names
Ubiquitous Language
If we start using different words
we are bound to change the code
to match our language.
If we start using different words
we are bound to change the code
to match our language.
Use names from the problem and
solution domain.
Use names from the problem and
solution domain.
CComBstr sVal
Ubiquitous Language
CComBstr sVal
CComBstr calibrationToolName
Ubiquitous Language
sVal is terrible.
s implies String which I already know from
CComBstr
every variable has a value so Val in name is useless
sVal is terrible.
s implies String which I already know from
CComBstr
every variable has a value so Val in name is useless
People are dropping sophisticated tools to
measure things in drilled wells.
They calibrate these tools and these tools
have name - that’s what that is
People are dropping sophisticated tools to
measure things in drilled wells.
They calibrate these tools and these tools
have name - that’s what that is
Having bad names in code is costlyHaving bad names in code is costly
Rx rx
Ubiquitous Language
Ask participants!Ask participants! Healthwatch for a pharmacy
chain.
Had pharmacists on the team and
Rx is the term they would use.
Healthwatch for a pharmacy
chain.
Had pharmacists on the team and
Rx is the term they would use.
Could be better in terms of role
playing ..
e.g. refillable
Could be better in terms of role
playing ..
e.g. refillable
People need to know the domain.
The code, via ubiquitous language,
helps the team learn the domain
People need to know the domain.
The code, via ubiquitous language,
helps the team learn the domain
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.
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
The complexity here is not in the
code. The complexity is accidental
driven by the names used.
The complexity here is not in the
code. The complexity is accidental
driven by the names used.
Choosing Good NamesChoosing Good Names
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
Ubiquitous language
Using names
Ubiquitous language
Using names
Choosing Good NamesChoosing 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 NamesChoosing 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
Mention use of ‘each’Mention use of ‘each’
Choosing Good NamesChoosing Good Names
Exercise
public static List<SelectOption> createEndDaysList() { List<SelectOption>
daysList = new ArrayList<SelectOption>(); Date dt = getCurrentDatePlus14Days();
int day = getDateDay(dt); for (int intLooper = 1; intLooper <= 31; intLooper++)
{ SelectOption option = new SelectOption(); if (day == intLooper) {
option.setLabel(String.valueOf(intLooper));
option.setValue(String.valueOf(intLooper)); option.setSelected(true);
} else { option.setLabel(String.valueOf(intLooper));
option.setValue(String.valueOf(intLooper)); option.setSelected(false);
} daysList.add(option); } return daysList;}public static
List<SelectOption> createEndMonthList(Date expiryDate) { List<SelectOption>
monthList = new ArrayList<SelectOption>(); int month = getDateMonth(expiryDate);
for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option
= new SelectOption(); if (month == intLooper)
{ option.setLabel(String.valueOf(intLooper));
option.setValue(String.valueOf(intLooper)); option.setSelected(true);
} else { option.setLabel(String.valueOf(intLooper));
option.setValue(String.valueOf(intLooper)); option.setSelected(false);
} monthList.add(option); } return monthList;}
public static List<SelectOption> createEndDaysList() { List<SelectOption>
daysList = new ArrayList<SelectOption>(); Date dt = getCurrentDatePlus14Days();
int day = getDateDay(dt); for (int intLooper = 1; intLooper <= 31; intLooper++)
{ SelectOption option = new SelectOption(); if (day == intLooper) {
option.setLabel(String.valueOf(intLooper));
option.setValue(String.valueOf(intLooper)); option.setSelected(true);
} else { option.setLabel(String.valueOf(intLooper));
option.setValue(String.valueOf(intLooper)); option.setSelected(false);
} daysList.add(option); } return daysList;}public static
List<SelectOption> createEndMonthList(Date expiryDate) { List<SelectOption>
monthList = new ArrayList<SelectOption>(); int month = getDateMonth(expiryDate);
for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option
= new SelectOption(); if (month == intLooper)
{ option.setLabel(String.valueOf(intLooper));
option.setValue(String.valueOf(intLooper)); option.setSelected(true);
} else { option.setLabel(String.valueOf(intLooper));
option.setValue(String.valueOf(intLooper)); option.setSelected(false);
} monthList.add(option); } return monthList;}
• Find a Partner
• Highlight names you would improve
• Write a better name
interloper :)
Simple Design
TestedTested
ClearClear
DryDry
SuccinctSuccinct
DRY: Don’t Repeat Yourself
Every piece of knowledge must have a
single, unambiguous, authoritative
representation within a system.
Avoiding Duplicate CodeAvoiding Duplicate Code
Once and Only Once
Data, structure, or logic should exist
in only one place in the system.
Avoiding Duplicate CodeAvoiding Duplicate Code
Test-Driven Development
1.Write new code only if an
automated test has failed.
2.Eliminate duplication.
Avoiding Duplicate CodeAvoiding Duplicate Code
Single Choice Principle
Whenever a software system must
support a set of alternatives, one and
only one module in the system should
know their exhaustive list.
Avoiding Duplicate CodeAvoiding Duplicate Code
Duplication may be the root
of all evil in software.
Avoiding Duplicate CodeAvoiding Duplicate Code
Copy & Paste
function something() {
}
function something() {
}
function something() {
}
function somethingElse() {
}
function something() {
}
function somethingElse() {
}
function something() {
}
Duplicate Code
Copy & Paste
☞ Duplicate Code
Edit the Copy
Duplicate Code
Avoid duplication by expressing
commonality and variability
explicitly.
function somethingElse() {
}
function something() {
}
Exercise
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();}
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
Commonality Variability Resolution
Behaviour Collaborator
Encapsulate
Collection
Select Options
Commonality Variability Resolution
Data Structure Value of State Simple Java Type
Select Options
Encapsulate
Collection
Select Options
Parameter
Object
Simple Design
TestedTested
ClearClear
DryDry
SuccinctSuccinct
Single Responsibility PrincipleSingle Responsibility Principle
There should be one and
only one reason for a class
to change.
SRPViolationSRPViolation
if(checkAccess(user)) {
updateEmail(user, email)
}
}
public boolean checkAccess(User user) {
...
}
public boolean updateEmail(User user, String email) {
...
}
}
SRP RestoredSRP Restored
if(securityService.checkAccess(user)) {
emailService.updateEmail(user, email)
}
}
public class SecurityService {
public boolean checkAccess(User user) {
...
}
}
public class EmailService {
...
}
}
Simple Design
TestedTested
ClearClear
DryDry
SuccinctSuccinct
Want More?
Agile Engineering Training KWMarch 17-18, 2015http://bit.ly/aetkw
Use ‘p2p’ for 10% discount
Reading
The Elements of Programming Style
Kernighan and Plauger
Prefactoring
Extreme Abstraction Extreme Separation Extreme
Readability
Ken Pugh
Agile in a Flash
Speed-Learning Agile Development
Jeff Langr and Tim Ottinger
Reading
Clean Code
A Handbook of Agile Software Craftsmanship
Robert C. Martin
Domain Driven Design
Tackling Complexity in the Heart of Software
Eric Evans
Implementation Patterns
Kent Beck
Reading
The Pragmatic Programmer: From Journeyman to MasterA
Extreme Programming Explained: Embrace ChangeKent B
Test Driven Development: By ExampleKent Beck
Object-Oriented Software Construction
Bertrand Meyer
Reading
Design 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 Development
James O. Coplien and Gertrud Bjørnvig
Photo Credits
http://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/
http://www.flickr.com/photos/93617791@N00/1347587396/
http://www.flickr.com/photos/8281413@N06/5070788991/
http://www.flickr.com/photos/23403402@N00/1197947341/
http://www.flickr.com/photos/54087404@N00/4638056301/
http://en.wikipedia.org/wiki/File:Leghold_trap.JPG
http://www.hostingwiththemostzing.com/?p=12
http://www.flickr.com/photos/36829973@N04/3546657245/
Photo Credits
http://www.flickr.com/photos/42644641@N07/5702962303/
http://www.flickr.com/photos/44124484001@N01/116962927/
http://www.flickr.com/photos/25509772@N00/2951851296/
http://www.flickr.com/photos/49016492@N08/4534101229/
http://www.flickr.com/photos/44123231@N05/5658726857/
http://www.flickr.com/photos/24367734@N00/46452239/
http://www.flickr.com/photos/17001563@N00/2847422081/
http://www.flickr.com/photos/59707463@N00/1312377396/
Photo Credits
http://www.flickr.com/photos/44123231@N05/5658726857/
https://dianedrake.com/wp-content/uploads/2014/06/sisyphus1.png
Photo Credits
Diagram Credits
Lisa Crispin and Janet Gregory
Agile Testing: A Practical Guide for Testers
and Agile Teams
Addison-Wesley Professional; January 9, 2009.
Mike Cohn
Succeeding with Agile: Software Development
Using Scrum
Addison-Wesley Professional; November 5, 2009.
Diagram Credits
Jim Highsmith
The Financial Implications of Technical Debt
http://jimhighsmith.com/the-financial-implications-of-technical-debt/
Martin Fowler
http://martinfowler.com/bliki/TechnicalDebtQuadrant.html
Jim Highsmith in his article The Financial Implications of Technical Debt, states:

Simple Design

  • 1.
  • 2.
  • 4.
    “Scrum is nota process or a technique for building products; rather, it is a framework within which you can employ various processes and techniques.” Scrum Guide
  • 5.
    www.XProgramming.com red circle containsrequirementsred circle contains requirements green circle crates a container to enable inner practices to be successful green circle crates a container to enable inner practices to be successful day-to-day engineering practicesday-to-day engineering practices
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
    What is TDD? •Simple, high-feedback incremental coding technique • Write tests as specs, prior to code • Immediate feedback from test execution
  • 13.
    TDD Rules 1.Test everythingthat could possibly break. 2.Do not write any production code until you have written the code that will test it. 3.Code is not checked in until all unit tests pass.
  • 14.
  • 15.
  • 16.
    public static List<SelectOption>createEndDaysList() { List<SelectOption> daysList = new ArrayList<SelectOption>(); Date dt = getCurrentDatePlus14Days(); int day = getDateDay(dt); for (int intLooper = 1; intLooper <= 31; intLooper++) { SelectOption option = new SelectOption(); if (day == intLooper) { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(true); } else { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(false); } daysList.add(option); } return daysList;}public static List<SelectOption> createEndMonthList(Date expiryDate) { List<SelectOption> monthList = new ArrayList<SelectOption>(); int month = getDateMonth(expiryDate); for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option = new SelectOption(); if (month == intLooper) { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(true); } else { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(false); } monthList.add(option); } return monthList;} public static List<SelectOption> createEndDaysList() { List<SelectOption> daysList = new ArrayList<SelectOption>(); Date dt = getCurrentDatePlus14Days(); int day = getDateDay(dt); for (int intLooper = 1; intLooper <= 31; intLooper++) { SelectOption option = new SelectOption(); if (day == intLooper) { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(true); } else { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(false); } daysList.add(option); } return daysList;}public static List<SelectOption> createEndMonthList(Date expiryDate) { List<SelectOption> monthList = new ArrayList<SelectOption>(); int month = getDateMonth(expiryDate); for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option = new SelectOption(); if (month == intLooper) { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(true); } else { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(false); } monthList.add(option); } return monthList;} • Find a Partner • Write pseudo code for tests you would write
  • 17.
  • 18.
  • 19.
    Stroop Effect Green RedBlue Purple Blue Purple Blue Purple Red Green Purple Green The Stroop Effect first set of words is easy to comprehend. takes people much longer for people to comprehend the correct meaning in the second case The Stroop Effect first set of words is easy to comprehend. takes people much longer for people to comprehend the correct meaning in the second case “semantic interference” where naming is incongruent with meaning. “semantic interference” where naming is incongruent with meaning. This is because of “semantic facilitation” where name is congruent with meaning. - people much faster at naming the ink color This is because of “semantic facilitation” where name is congruent with meaning. - people much faster at naming the ink color IDE’s leverage this with syntax colouring. IDE’s leverage this with syntax colouring. Green Red Blue Purple Blue Purple
  • 20.
    black yellow Meaning: Colour: 1. look attop and understand its meaning 2. look at actual coluor MATCH - if ink colour of bottom word matches word at top NOMATCH 1. look at top and understand its meaning 2. look at actual coluor MATCH - if ink colour of bottom word matches word at top NOMATCH
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
    The End Debrief: any change asyou went longer? any easier - maybe a little but still very tiring. Debrief: any change as you went longer? any easier - maybe a little but still very tiring. This is like reading code when you read code and the names of things are incongruent with their meaning, We have to keep reminding ourselves ‘oh yeah this is the Foo class and it actually does Bar” This is like reading code when you read code and the names of things are incongruent with their meaning, We have to keep reminding ourselves ‘oh yeah this is the Foo class and it actually does Bar” Its WAY harder to understand code that has poorly chosen names. Its WAY harder to understand code that has poorly chosen names. We have to choose a lot names esp. with trends towards smaller classes and methods. We have to choose a lot names esp. with trends towards smaller classes and methods. A lot of value in putting energy into names A lot of value in putting energy into names
  • 38.
  • 39.
    Choosing Good NamesChoosingGood 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.
  • 40.
    Telephone TestTelephone Test GoalDonor vs Gold Owner Date genymdhmsWe want to promote conversation about code. We want to promote conversation about code.
  • 41.
    Pronounceable Names Avoid Encodings ChoosingGood NamesChoosing Good Names
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
    LPSTR lpCmdLine m_name Avoid Encodings LPSTRcommandLine name Used to make sense. IDEs now help with type and scope - don’t need to have names reflect types. Used to make sense. IDEs now help with type and scope - don’t need to have names reflect types. Not so important to embed types or scope information in the variable. IDEs help Not such a problem with small names. Not so important to embed types or scope information in the variable. IDEs help Not such a problem with small names.
  • 47.
    Choosing Good NamesChoosingGood Names Intention-Revealing Name Role-Suggesting NamePattern to guide each decision. Derived a pattern for each programming decision he made. Pattern to guide each decision. Derived a pattern for each programming decision he made.
  • 48.
    Intention-Revealing Name applyMeasureConstraintTo EnableSortingByMeasure() Think aboutmethod names based on how they will look in calling code. Why was this method invoked and not some other? That is a question that can profitably be answered by the name of the method. The calling method should be telling a story. Name methods so they help tell that story. Kent Beck - pg 79 Think about method names based on how they will look in calling code. Why was this method invoked and not some other? That is a question that can profitably be answered by the name of the method. The calling method should be telling a story. Name methods so they help tell that story. Kent Beck - pg 79
  • 49.
  • 50.
  • 51.
    Choosing Good NamesChoosingGood Names Ubiquitous Language If we start using different words we are bound to change the code to match our language. If we start using different words we are bound to change the code to match our language. Use names from the problem and solution domain. Use names from the problem and solution domain.
  • 52.
  • 53.
    CComBstr sVal CComBstr calibrationToolName UbiquitousLanguage sVal is terrible. s implies String which I already know from CComBstr every variable has a value so Val in name is useless sVal is terrible. s implies String which I already know from CComBstr every variable has a value so Val in name is useless People are dropping sophisticated tools to measure things in drilled wells. They calibrate these tools and these tools have name - that’s what that is People are dropping sophisticated tools to measure things in drilled wells. They calibrate these tools and these tools have name - that’s what that is Having bad names in code is costlyHaving bad names in code is costly
  • 54.
    Rx rx Ubiquitous Language Askparticipants!Ask participants! Healthwatch for a pharmacy chain. Had pharmacists on the team and Rx is the term they would use. Healthwatch for a pharmacy chain. Had pharmacists on the team and Rx is the term they would use. Could be better in terms of role playing .. e.g. refillable Could be better in terms of role playing .. e.g. refillable People need to know the domain. The code, via ubiquitous language, helps the team learn the domain People need to know the domain. The code, via ubiquitous language, helps the team learn the domain
  • 55.
  • 56.
    applyPhq9DateRangeConstraint() Ubiquitous Language The PHQ-9is 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.
  • 57.
    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 The complexity here is not in the code. The complexity is accidental driven by the names used. The complexity here is not in the code. The complexity is accidental driven by the names used. Choosing Good NamesChoosing Good Names
  • 58.
    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 Ubiquitous language Using names Ubiquitous language Using names Choosing Good NamesChoosing Good Names
  • 59.
    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 NamesChoosing Good Names
  • 60.
    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 Mention use of ‘each’Mention use of ‘each’ Choosing Good NamesChoosing Good Names
  • 61.
  • 62.
    public static List<SelectOption>createEndDaysList() { List<SelectOption> daysList = new ArrayList<SelectOption>(); Date dt = getCurrentDatePlus14Days(); int day = getDateDay(dt); for (int intLooper = 1; intLooper <= 31; intLooper++) { SelectOption option = new SelectOption(); if (day == intLooper) { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(true); } else { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(false); } daysList.add(option); } return daysList;}public static List<SelectOption> createEndMonthList(Date expiryDate) { List<SelectOption> monthList = new ArrayList<SelectOption>(); int month = getDateMonth(expiryDate); for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option = new SelectOption(); if (month == intLooper) { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(true); } else { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(false); } monthList.add(option); } return monthList;} public static List<SelectOption> createEndDaysList() { List<SelectOption> daysList = new ArrayList<SelectOption>(); Date dt = getCurrentDatePlus14Days(); int day = getDateDay(dt); for (int intLooper = 1; intLooper <= 31; intLooper++) { SelectOption option = new SelectOption(); if (day == intLooper) { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(true); } else { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(false); } daysList.add(option); } return daysList;}public static List<SelectOption> createEndMonthList(Date expiryDate) { List<SelectOption> monthList = new ArrayList<SelectOption>(); int month = getDateMonth(expiryDate); for (int intLooper = 1; intLooper <= 12; intLooper++) { SelectOption option = new SelectOption(); if (month == intLooper) { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(true); } else { option.setLabel(String.valueOf(intLooper)); option.setValue(String.valueOf(intLooper)); option.setSelected(false); } monthList.add(option); } return monthList;} • Find a Partner • Highlight names you would improve • Write a better name interloper :)
  • 63.
  • 65.
    DRY: Don’t RepeatYourself Every piece of knowledge must have a single, unambiguous, authoritative representation within a system. Avoiding Duplicate CodeAvoiding Duplicate Code
  • 66.
    Once and OnlyOnce Data, structure, or logic should exist in only one place in the system. Avoiding Duplicate CodeAvoiding Duplicate Code
  • 67.
    Test-Driven Development 1.Write newcode only if an automated test has failed. 2.Eliminate duplication. Avoiding Duplicate CodeAvoiding Duplicate Code
  • 68.
    Single Choice Principle Whenevera software system must support a set of alternatives, one and only one module in the system should know their exhaustive list. Avoiding Duplicate CodeAvoiding Duplicate Code
  • 69.
    Duplication may bethe root of all evil in software. Avoiding Duplicate CodeAvoiding Duplicate Code
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
    Duplicate Code Copy &Paste ☞ Duplicate Code Edit the Copy
  • 76.
    Duplicate Code Avoid duplicationby expressing commonality and variability explicitly.
  • 77.
  • 78.
  • 79.
    Can you spotthe duplicate code? How would you make the commonality and variation explicit? Can you spot the commonality and variation?
  • 81.
    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();}
  • 82.
    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();}
  • 83.
    Select Options Commonality VariabilityResolution Behaviour Collaborator Encapsulate Collection
  • 84.
    Select Options Commonality VariabilityResolution Data Structure Value of State Simple Java Type
  • 85.
  • 86.
  • 87.
  • 89.
    Single Responsibility PrincipleSingleResponsibility Principle There should be one and only one reason for a class to change.
  • 90.
    SRPViolationSRPViolation if(checkAccess(user)) { updateEmail(user, email) } } publicboolean checkAccess(User user) { ... } public boolean updateEmail(User user, String email) { ... } }
  • 91.
    SRP RestoredSRP Restored if(securityService.checkAccess(user)){ emailService.updateEmail(user, email) } } public class SecurityService { public boolean checkAccess(User user) { ... } } public class EmailService { ... } }
  • 92.
  • 93.
    Want More? Agile EngineeringTraining KWMarch 17-18, 2015http://bit.ly/aetkw Use ‘p2p’ for 10% discount
  • 94.
    Reading The Elements ofProgramming Style Kernighan and Plauger Prefactoring Extreme Abstraction Extreme Separation Extreme Readability Ken Pugh Agile in a Flash Speed-Learning Agile Development Jeff Langr and Tim Ottinger
  • 95.
    Reading Clean Code A Handbookof Agile Software Craftsmanship Robert C. Martin Domain Driven Design Tackling Complexity in the Heart of Software Eric Evans Implementation Patterns Kent Beck
  • 96.
    Reading The Pragmatic Programmer:From Journeyman to MasterA Extreme Programming Explained: Embrace ChangeKent B Test Driven Development: By ExampleKent Beck Object-Oriented Software Construction Bertrand Meyer
  • 97.
    Reading Design Patterns: Elementsof 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 Development James O. Coplien and Gertrud Bjørnvig
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
    Diagram Credits Lisa Crispinand Janet Gregory Agile Testing: A Practical Guide for Testers and Agile Teams Addison-Wesley Professional; January 9, 2009. Mike Cohn Succeeding with Agile: Software Development Using Scrum Addison-Wesley Professional; November 5, 2009.
  • 103.
    Diagram Credits Jim Highsmith TheFinancial Implications of Technical Debt http://jimhighsmith.com/the-financial-implications-of-technical-debt/ Martin Fowler http://martinfowler.com/bliki/TechnicalDebtQuadrant.html Jim Highsmith in his article The Financial Implications of Technical Debt, states: