SlideShare a Scribd company logo
1 of 68
Download to read offline
What Can Journalists
Teach Developers About
Writing Source Code?
Alex Aitken	

@alexaitken

Alistair McKinnell	

@amckinnell
In some sense techniques for controllingā€Ø
complexity is what computer science is about.
Harold Abelson
Agenda
What Is Inverted Pyramid ?	

!

Writing Source Code
Using Inverted Pyramid
What Is Inverted Pyramid ?
The inverted pyramid is a metaphor ā€Ø
used by journalists to illustrate how ā€Ø
information should be prioritized.
ā€œThe Leadā€

The Lead

ā€œThe Bodyā€
ā€œThe Tailā€
ā€œThe Leadā€

The Lead

ā€œThe Bodyā€
ā€œThe Tailā€

ā€œThe Leadā€: the mostā€Ø
important information
ā€œThe Leadā€

The Lead

ā€œThe Bodyā€
ā€œThe Tailā€

ā€œThe Leadā€: the mostā€Ø
important information
ā€œThe Bodyā€: the crucialā€Ø
information
ā€œThe Leadā€

The Lead

ā€œThe Bodyā€
ā€œThe Tailā€

ā€œThe Leadā€: the mostā€Ø
important information
ā€œThe Bodyā€: the crucialā€Ø
information
ā€œThe Tailā€: any extraā€Ø
information
The Lead

Beneļ¬ts for Readers

1. Readers can leave an article at any point
and understand it, even if they do not
have all the details. 	

2. For those readers who wish to proceed, it
conducts them through the article details.
Exercise
1
ā€¢
ā€¢
ā€¢

Arrange cards as above	

1ā€“2 groups per table 	

3ā€“4 people per group

22
2
2
Some Boos at Graduation After Judge Bars Prayer
Associated Press
May 21, 2001
WASHINGTON, Ill. - A top student who gave a traditional farewell
speech at a high school graduation was booed and another student
was applauded for holding a moment of silence after a judge barred
prayer at the ceremony.

ā€¢
ā€¢
ā€¢
ā€¢

22
2
2

Experience inverted pyramid 	

Read one card at a time	

You have 4 minutes	

Itā€™s not important to read all cards
Some Boos at Graduation After Judge Bars Prayer
Associated Press
May 21, 2001

ā€œThe Leadā€

WASHINGTON, Ill. - A top student who gave a traditional farewell speech at a high school graduation was
booed and another student was applauded for holding a moment of silence after a judge barred prayer at
the ceremony.
A federal judge issued a restraining order days before Sunday's ceremony at Washington Community
High School blocking any student-led prayer. It was the ļ¬rst time in the 80-year history of the school that
no graduation prayers were said.

The Lead

ā€œThe Bodyā€

Natasha Appenheimer, the class valedictorian, traditionally a top student chosen to give the class
graduation speech, was booed when she received her diploma. Her family, backed by the American Civil
Liberties Union, had ļ¬led the lawsuit that led to the restraining order. Meanwhile, some stood and
applauded class speaker Ryan Brown when he bowed his head for a moment of silence before his
speech.
About 200 people attended a prayer vigil before the ceremony, and a placard-carrying atheist and a
Pentecostal minister got into a shouting match.
In spite of the turbulent atmosphere, Appenheimer said she wasn't upset by the way things turned out.

ā€œThe Tailā€

"It's my graduation. I'm happy," she said. The lawsuit "was worth it. We changed things, we righted a
wrong and made something better than it was before. I learned that when you believe in something, you
should stand up for it."
Graduate Annie White disagreed, saying many class members wanted to demonstrate that "God was a
part of our graduation."
Superintendent Lee Edwards said the school district might appeal McDade's ruling. He said the
invocation and benediction prayers usually said at the ceremony were innocuous, and "You would have to
have been working pretty hard to be offended."
School district ofļ¬cials defended the prayer on grounds that students, not administrators, were in charge
of graduation.
The Supreme Court's landmark 1962 decision outlawed organized prayer in public schools. In 1992, the
justices barred clergy-led prayers at graduations, and last year, the court barred ofļ¬cials from letting
students lead crowds in prayer before football games.
public class StringCalculator {	

!
!
!
!
!

public int add(String numbers) {	
List<Integer> values = convertToInteger(parseValues(numbers));	
failWhenContainsNegatives(values);	
return sumOf(values);	
}	
private String[] parseValues(String numbers) {	
if (numbers.isEmpty()) {	
return new String[] {};	
}	
if (containsCustomDelimiters(numbers)) {	
return parseCustomDelimitedValues(numbers);	
}	

!
!
!

!

!

}	
private List<Integer> convertToInteger(String[] numbers) {	
List<Integer> result = new ArrayList<>();	

!
!
!

}	
private boolean containsCustomDelimiters(String numbers) {	
return numbers.startsWith("//");	
}	
private String[] parseCustomDelimitedValues(String numbers) {	
int newlineIndex = numbers.indexOf('n');	
String delimiters = numbers.substring(2, newlineIndex);	
String numberList = numbers.substring(newlineIndex + 1);	
String[] customDelimiters = parseCustomDelimiters(delimiters);	

!

!

for (String customDelimiter : customDelimiters) {	
numberList = numberList.replaceAll(	
quoteRegularExpression(customDelimiter), ",");	
}	

!

return result;	
}	
private void failWhenContainsNegatives(List<Integer> values) {	
List<Integer> negatives = new ArrayList<>();	
for (Integer value : values) {	
if (value < 0) negatives.add(value);	
}	
if (!negatives.isEmpty()) {	
String message = "Error: negatives not allowed " + negatives;	
throw new RuntimeException(message);	
}	
}	

return result;	

	

for (String number : numbers) {	
result.add(toInteger(number));	
}	

!

for (Integer value : values) {	
result += value;	
}	

!

return parseStandardDelimiters(numbers);	

!
!

private int sumOf(List<Integer> values) {	
int result = 0;	

!
!
!
!
!
}

return numberList.split(",");	
}	
private String[] parseCustomDelimiters(String rawCustomDelimiters) {	
return rawCustomDelimiters.replaceAll("[", "").split("]");	
}	
private String quoteRegularExpression(String customSeparator) {	
return "Q" + customSeparator + "E";	
}	
private String[] parseStandardDelimiters(String numbers) {	
return numbers.split("[,n]");	
}	
private Integer toInteger(String number) {	
Integer value = Integer.parseInt(number);	
return value <= 1000 ? value : 0;	
}
Beneļ¬ts for Readers

public class StringCalculator {	

!
!
!

The Lead

!

public int add(String numbers) {	
List<Integer> values = convertToInteger(parseValues(numbers));	

private int
int

!

for

result += value;	

failWhenContainsNegatives(values);	
return sumOf(values);	
}	

}	

!
!

return
}	

1. Readers can leave an article at any point
!
!
!
and understand it, even if they do not
!
have all the details. 	

 !
!
private String[] parseValues(String numbers) {	
if (numbers.isEmpty()) {	
return
}	

private
return
}	
private
int

if (containsCustomDelimiters(numbers)) {	
return
}	

String delimiters = numbers.substring(2, newlineIndex);	
String numberList = numbers.substring(newlineIndex + 1);	

return parseStandardDelimiters(numbers);	

	

}	

!

String[] customDelimiters = parseCustomDelimiters(delimiters);	

private List<Integer> convertToInteger(String[] numbers) {	
List<Integer> result =

for

for (String number : numbers) {	
result.add(toInteger(number));	
}	

numberList = numberList.replaceAll(	
quoteRegularExpression(customDelimiter),
}	

!

!
2. For those readers who wish to proceed, it
!
!
conducts them through the article details.
!
!
return

}	

return result;	

}	

private
return
}	

private void failWhenContainsNegatives(List<Integer> values) {	
List<Integer> negatives =
for (Integer value : values) {	
if (value < 0) negatives.add(value);	
}	

!

if (!negatives.isEmpty()) {	
String message =
throw
}	
}	

!
!
!
!
}

private
return
}	
private
return
}	

private
Integer value = Integer.parseInt(number);	
return
}
The Lead

Beneļ¬ts for Developers

1. Readers can leave an article at any point
and understand it, even if they do not
have all the details. 	

2. For those readers who wish to proceed, it
conducts them through the article details.
The Lead

Beneļ¬ts for Developers

1. ā€ØDevelopers can leave source code at any
ā€Øpoint and understand it, even if they do
not have all the details.
	

2. For those readers who wish to proceed, it
conducts them through the article details.
The Lead

Beneļ¬ts for Developers

1. Developers can leave source code at any
point and understand it, even if they do
not have all the details.	

2. For those developers who need to see
more implementation details, it conducts
them through the source code.
The Lead

Beneļ¬ts for Developers

1. Understanding without all the details	

2. Details are effectively organized
Exercise
Lead

ā€¢
ā€¢

Body
Body
Body

Same groups as last exercise 	

Arrange cards as above

Tail
Tail
Tail
int add(String numbers)
numbers

add(numbers)

ā€œ1,2,3ā€

6

ā€œ1,1001,2ā€

3

ā€œ1,-2,3,-4ā€

Error showing -2, -4

ā€œ//#n2#4#6ā€

12
int add(String numbers)
numbers

add(numbers)

ā€œ1,2,3ā€

6

ā€œ1,1001,2ā€

3

ā€œ1,-2,3,-4ā€

Error showing -2, -4

ā€œ//#n2#4#6ā€

12

ā€œ//#n2#4#6ā€
public int add(String numbers) {
List<Integer> values = convertToInteger(parseValues(numbers));
failWhenContainsNegatives(values);
return sumOf(values);
}

Body
Body
Body

Tail
Tail
Tail

ā€¢
ā€¢

Flip over the card labelled Lead	


ā€¢

Share that understanding with your group

What can you say about the add()
method from reading the Lead card ?
public int add(String numbers) {
List<Integer> values = convertToInteger(parseValues(numbers));
failWhenContainsNegatives(values);

private String[] parseValues(String numbers) {
if (numbers.isEmpty()) {
return new String[] {};
}

return sumOf(values);

if (containsCustomDelimiters(numbers)) {
return parseCustomDelimitedValues(numbers);
}

}

Body
Body

return parseStandardDelimiters(numbers);
}

Tail
Tail
Tail

ā€¢
ā€¢

Flip over the Body cards one at a time	


ā€¢
ā€¢

Next, ļ¬‚ip over the Tail cards	


Ask yourself: What do I notice about the
code after reading each card ?	

Itā€™s not important to read all cards
public class StringCalculator {	

!
!
!
!
!

public int add(String numbers) {	
List<Integer> values = convertToInteger(parseValues(numbers));	
failWhenContainsNegatives(values);	
return sumOf(values);	
}	
private String[] parseValues(String numbers) {	
if (numbers.isEmpty()) {	
return new String[] {};	
}	
if (containsCustomDelimiters(numbers)) {	
return parseCustomDelimitedValues(numbers);	
}	

!
!
!

!

!

}	
private List<Integer> convertToInteger(String[] numbers) {	
List<Integer> result = new ArrayList<>();	

!
!
!

}	
private boolean containsCustomDelimiters(String numbers) {	
return numbers.startsWith("//");	
}	
private String[] parseCustomDelimitedValues(String numbers) {	
int newlineIndex = numbers.indexOf('n');	
String delimiters = numbers.substring(2, newlineIndex);	
String numberList = numbers.substring(newlineIndex + 1);	
String[] customDelimiters = parseCustomDelimiters(delimiters);	

!

!

for (String customDelimiter : customDelimiters) {	
numberList = numberList.replaceAll(	
quoteRegularExpression(customDelimiter), ",");	
}	

!

return result;	
}	
private void failWhenContainsNegatives(List<Integer> values) {	
List<Integer> negatives = new ArrayList<>();	
for (Integer value : values) {	
if (value < 0) negatives.add(value);	
}	
if (!negatives.isEmpty()) {	
String message = "Error: negatives not allowed " + negatives;	
throw new RuntimeException(message);	
}	
}	

return result;	

	

for (String number : numbers) {	
result.add(toInteger(number));	
}	

!

for (Integer value : values) {	
result += value;	
}	

!

return parseStandardDelimiters(numbers);	

!
!

private int sumOf(List<Integer> values) {	
int result = 0;	

!
!
!
!
!
}

return numberList.split(",");	
}	
private String[] parseCustomDelimiters(String rawCustomDelimiters) {	
return rawCustomDelimiters.replaceAll("[", "").split("]");	
}	
private String quoteRegularExpression(String customSeparator) {	
return "Q" + customSeparator + "E";	
}	
private String[] parseStandardDelimiters(String numbers) {	
return numbers.split("[,n]");	
}	
private Integer toInteger(String number) {	
Integer value = Integer.parseInt(number);	
return value <= 1000 ? value : 0;	
}
public class StringCalculator {	

!
public int add(String numbers) {	
List<Integer> values = convertToInteger(parseValues(numbers));	

!
failWhenContainsNegatives(values);	

!
return sumOf(values);	
}
public class StringCalculator {	

!
public int add(String numbers) {	
List<Integer> values = convertToInteger(parseValues(numbers));	

!
failWhenContainsNegatives(values);	

!
return sumOf(values);	
}
The Lead

Understanding without all the detail	

Details are effectively organized
Writing Source Code
Using Inverted Pyramid
Compose Method	

!

You canā€™t rapidly understand
a methodā€™s logic.	

!

Transform the logic into a
small number of intentionrevealing steps at the same
level of detail.
Composed Method	

!

Compose methods out of
calls to other methods, each
of which is at roughly the
same level of abstraction.
Composed Method and SLAP	

!

Composed method
encourages factoring (or
refactoring) code into small,
cohesive, readable chunks.	

	

SLAP stands for the Single ā€Ø
Level of Abstraction Principle.
Example
public int add(String numbers) {
List<Integer> negatives = new ArrayList<>();
int sum = 0;
for (String number : parseValues(numbers)) {
Integer value = Integer.parseInt(number);
if (value < 0) {
negatives.add(value);
} else if (value <= 1000) {
sum += value;
}
}
if (!negatives.isEmpty()) {
throw new RuntimeException("Error: negatives not allowed " +
negatives);
}
return sum;
}
public int add(String numbers) {
List<Integer> negatives = new ArrayList<>();
int sum = 0;
for (String number : parseValues(numbers)) {
Integer value = Integer.parseInt(number);
if (value < 0) {
negatives.add(value);
} else if (value <= 1000) {
sum += value;
}
}
if (!negatives.isEmpty()) {
throw new RuntimeException("Error: negatives not allowed " +
negatives);
}
return sum;
}

You canā€™t rapidly understandā€Ø
a methodā€™s logic.
public int add(String numbers) {	
List<Integer> values = convertToInteger(parseValues(numbers));	

!
failWhenContainsNegatives(values);	

!
return sumOf(values);	
}

Compose methods out of
calls to other methods, each
of which is at roughly the
same level of abstraction.
public int add(String numbers) {	
List<Integer> values = convertToInteger(parseValues(numbers));	

!
failWhenContainsNegatives(values);	

!
return sumOf(values);	
}

Understanding without all the detail	

The Lead

Details are effectively organized
Example
The Lead
The Lead
The Lead
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (numbers.startsWith("//")) {	
int newlineIndex = numbers.indexOf('n');	
	
String delimiters = numbers.substring(2, newlineIndex);	
String numberList = numbers.substring(newlineIndex + 1);	
	
String[] customDelimiters = delimiters.	
replaceAll("[", "").split("]");	
	
for (String customDelimiter : customDelimiters) {	
numberList = numberList.	
replaceAll("Q" + customDelimiter + "E", ",");	
}	
	
return numberList.split(",");	
}	

!
return numbers.split("[,n]");	
}
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (numbers.startsWith("//")) {	
int newlineIndex = numbers.indexOf('n');	
	
String delimiters = numbers.substring(2, newlineIndex);	
String numberList = numbers.substring(newlineIndex + 1);	
	
String[] customDelimiters = delimiters.	
replaceAll("[", "").split("]");	
	
for (String customDelimiter : customDelimiters) {	
numberList = numberList.	
replaceAll("Q" + customDelimiter + "E", ",");	
}	
	
return numberList.split(",");	
}	

!
return numbers.split("[,n]");	
}
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (numbers.startsWith("//")) {	
return parseCustomDelimitedValues(numbers);	
}	

!
return numbers.split("[,n]");	
}
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (numbers.startsWith("//")) {	
return parseCustomDelimitedValues(numbers);	
}	

!
return numbers.split("[,n]");	
}

SLAP stands for the Single ā€Ø
Level of Abstraction Principle.
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (numbers.startsWith("//")) {	
return parseCustomDelimitedValues(numbers);	
}	

!
return numbers.split("[,n]");	
}

SLAP stands for the Single ā€Ø
Level of Abstraction Principle.
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (numbers.startsWith("//")) {	
return parseCustomDelimitedValues(numbers);	
}	

!
return numbers.split("[,n]");	
}
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (containsCustomDelimiters(numbers)) {	
return parseCustomDelimitedValues(numbers);	
}	

!
return numbers.split("[,n]");	
}
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (containsCustomDelimiters(numbers)) {	
return parseCustomDelimitedValues(numbers);	
}	

!
return parseStandardDelimiters(numbers);	
}
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (containsCustomDelimiters(numbers)) {	
return parseCustomDelimitedValues(numbers);	
}	

!
return parseStandardDelimiters(numbers);	
}

SLAP stands for the Single ā€Ø
Level of Abstraction Principle.
private String[] parseValues(String numbers) {	
if (numbers.isEmpty())	
return new String[] {};	

!
if (containsCustomDelimiters(numbers)) {	
return parseCustomDelimitedValue(numbers);	
}	

!
return parseStandardDelimiters(numbers);	
}

Understanding without all the detail	

The Lead

Details are effectively organized
Applying Inverted Pyramid
The Lead
The Lead
Compose Method
Liabilities

ā€¢ Can lead to an overabundance of small methods.	

ā€¢ Can make debugging difļ¬cult because logic is ā€Ø
spread out across many small methods.

Refactoring to Patterns
Compose Method
Beneļ¬ts

ā€¢

Efļ¬ciently communicates what a method does ā€Ø
and how it does what it does.	


ā€¢

Simpliļ¬es a method by breaking it up into ā€Ø
well-named chunks of behaviour at the ā€Ø
same level of detail.
Refactoring to Patterns
ā€œThe Leadā€

The Lead

ā€œThe Bodyā€
ā€œThe Tailā€
The Lead

Beneļ¬ts for Developers

1. Developers can leave source code at any
point and understand it, even if they do
not have all the details.	

2. For those developers who need to see
more implementation details, it conducts
them through the source code.
Exercise
1
ā€¢
ā€¢

Grab an index card to write on	

Write down 2 things you are going to
consider next time you write code
1
ā€¢

Take turns sharing what you wrote with
everyone at your table	


ā€¢

This is optional. Unlike in kindergarten,
you donā€™t have to share
In some sense techniques for controllingā€Ø
complexity is what computer science is about.
Harold Abelson
The Lead

Beneļ¬ts for Developers

1. Understanding without all the details	

2. Details are effectively organized
You know you are working on clean codeā€Ø
when each routine you read turns out to be
pretty much what you expected.
Ward Cunningham
Books

Refactoring to Patterns	

Joshua Kerievsky
Implementation Patterns	

Kent Beck
The Productive Programmer	

Neal Ford
Clean Code	

Robert C. Martin
Photos

www.ļ¬‚ickr.com/photos/ā€Ø
ecu_digital_collections/3288382289/

www.morgueļ¬le.com/ā€Ø
archive/display/848917

More Related Content

Similar to What Can Journalists Teach Developers About Writing Source Code?

Programming RPi for IoT Applications.pdf
Programming RPi for IoT Applications.pdfProgramming RPi for IoT Applications.pdf
Programming RPi for IoT Applications.pdfrakeshk213994
Ā 
Java Tutorial
Java Tutorial Java Tutorial
Java Tutorial Akash Pandey
Ā 
Health monitoring and dependency injection - CNUG November 2019
Health monitoring and dependency injection - CNUG November 2019Health monitoring and dependency injection - CNUG November 2019
Health monitoring and dependency injection - CNUG November 2019Alex Thissen
Ā 
Indexing in Cassandra
Indexing in CassandraIndexing in Cassandra
Indexing in CassandraEd Anuff
Ā 
A Related Matter: Optimizing your webapp by using django-debug-toolbar, selec...
A Related Matter: Optimizing your webapp by using django-debug-toolbar, selec...A Related Matter: Optimizing your webapp by using django-debug-toolbar, selec...
A Related Matter: Optimizing your webapp by using django-debug-toolbar, selec...Christopher Adams
Ā 
java review by prof kmt.ppt
java review by prof kmt.pptjava review by prof kmt.ppt
java review by prof kmt.pptssuser1d3c311
Ā 
First Do No Harm - 360|AnDev
First Do No Harm - 360|AnDevFirst Do No Harm - 360|AnDev
First Do No Harm - 360|AnDevAnnyce Davis
Ā 
Better Code through Lint and Checkstyle
Better Code through Lint and CheckstyleBetter Code through Lint and Checkstyle
Better Code through Lint and CheckstyleMarc Prengemann
Ā 
Code transformation With Spoon
Code transformation With SpoonCode transformation With Spoon
Code transformation With SpoonGĆ©rard Paligot
Ā 
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...DroidConTLV
Ā 
Write code that writes code!
Write code that writes code!Write code that writes code!
Write code that writes code!Jason Feinstein
Ā 
Mongo and Harmony
Mongo and HarmonyMongo and Harmony
Mongo and HarmonySteve Smith
Ā 
Building confidence in concurrent code with a model checker: TLA+ for program...
Building confidence in concurrent code with a model checker: TLA+ for program...Building confidence in concurrent code with a model checker: TLA+ for program...
Building confidence in concurrent code with a model checker: TLA+ for program...Scott Wlaschin
Ā 
Chapter-6.pdf
Chapter-6.pdfChapter-6.pdf
Chapter-6.pdfssuser01a3d0
Ā 
Devoxx BE - How to fail at benchmarking
Devoxx BE - How to fail at benchmarkingDevoxx BE - How to fail at benchmarking
Devoxx BE - How to fail at benchmarkingPierre Laporte
Ā 
Programming in python Unit-1 Part-1
Programming in python Unit-1 Part-1Programming in python Unit-1 Part-1
Programming in python Unit-1 Part-1Vikram Nandini
Ā 

Similar to What Can Journalists Teach Developers About Writing Source Code? (20)

Programming RPi for IoT Applications.pdf
Programming RPi for IoT Applications.pdfProgramming RPi for IoT Applications.pdf
Programming RPi for IoT Applications.pdf
Ā 
Java Tutorial
Java Tutorial Java Tutorial
Java Tutorial
Ā 
Health monitoring and dependency injection - CNUG November 2019
Health monitoring and dependency injection - CNUG November 2019Health monitoring and dependency injection - CNUG November 2019
Health monitoring and dependency injection - CNUG November 2019
Ā 
Indexing in Cassandra
Indexing in CassandraIndexing in Cassandra
Indexing in Cassandra
Ā 
BDD Primer
BDD PrimerBDD Primer
BDD Primer
Ā 
A Related Matter: Optimizing your webapp by using django-debug-toolbar, selec...
A Related Matter: Optimizing your webapp by using django-debug-toolbar, selec...A Related Matter: Optimizing your webapp by using django-debug-toolbar, selec...
A Related Matter: Optimizing your webapp by using django-debug-toolbar, selec...
Ā 
java review by prof kmt.ppt
java review by prof kmt.pptjava review by prof kmt.ppt
java review by prof kmt.ppt
Ā 
First Do No Harm - 360|AnDev
First Do No Harm - 360|AnDevFirst Do No Harm - 360|AnDev
First Do No Harm - 360|AnDev
Ā 
Better Code through Lint and Checkstyle
Better Code through Lint and CheckstyleBetter Code through Lint and Checkstyle
Better Code through Lint and Checkstyle
Ā 
Lesson1
Lesson1Lesson1
Lesson1
Ā 
Code transformation With Spoon
Code transformation With SpoonCode transformation With Spoon
Code transformation With Spoon
Ā 
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Write code that writes code! A beginner's guide to Annotation Processing - Ja...
Ā 
Write code that writes code!
Write code that writes code!Write code that writes code!
Write code that writes code!
Ā 
Chapter 6
Chapter 6Chapter 6
Chapter 6
Ā 
Mongo and Harmony
Mongo and HarmonyMongo and Harmony
Mongo and Harmony
Ā 
Building confidence in concurrent code with a model checker: TLA+ for program...
Building confidence in concurrent code with a model checker: TLA+ for program...Building confidence in concurrent code with a model checker: TLA+ for program...
Building confidence in concurrent code with a model checker: TLA+ for program...
Ā 
Chapter-6.pdf
Chapter-6.pdfChapter-6.pdf
Chapter-6.pdf
Ā 
Devoxx BE - How to fail at benchmarking
Devoxx BE - How to fail at benchmarkingDevoxx BE - How to fail at benchmarking
Devoxx BE - How to fail at benchmarking
Ā 
Feasting On Brains With Taverna Public
Feasting On Brains With Taverna PublicFeasting On Brains With Taverna Public
Feasting On Brains With Taverna Public
Ā 
Programming in python Unit-1 Part-1
Programming in python Unit-1 Part-1Programming in python Unit-1 Part-1
Programming in python Unit-1 Part-1
Ā 

More from Alistair McKinnell

Succeeding with Specification by Example
Succeeding with Specification by ExampleSucceeding with Specification by Example
Succeeding with Specification by ExampleAlistair McKinnell
Ā 
Don't Settle for Poor Names (Or Poor Design)
Don't Settle for Poor Names (Or Poor Design)Don't Settle for Poor Names (Or Poor Design)
Don't Settle for Poor Names (Or Poor Design)Alistair McKinnell
Ā 
Don't Settle for Poor Names
Don't Settle for Poor NamesDon't Settle for Poor Names
Don't Settle for Poor NamesAlistair McKinnell
Ā 
Advanced Developer Testing
Advanced Developer TestingAdvanced Developer Testing
Advanced Developer TestingAlistair McKinnell
Ā 
Commonality and Variability Analysis: Avoiding Duplicate Code
Commonality and Variability Analysis: Avoiding Duplicate CodeCommonality and Variability Analysis: Avoiding Duplicate Code
Commonality and Variability Analysis: Avoiding Duplicate CodeAlistair McKinnell
Ā 
Agile Tour Shanghai December 2011
Agile Tour Shanghai December 2011Agile Tour Shanghai December 2011
Agile Tour Shanghai December 2011Alistair McKinnell
Ā 
Agile Transition in Trouble? Using the Kotter Change Model as a Diagnostic Tool
Agile Transition in Trouble? Using the Kotter Change Model as a Diagnostic ToolAgile Transition in Trouble? Using the Kotter Change Model as a Diagnostic Tool
Agile Transition in Trouble? Using the Kotter Change Model as a Diagnostic ToolAlistair McKinnell
Ā 
Struggling to Create Maintainable Unit Tests?
Struggling to Create Maintainable Unit Tests?Struggling to Create Maintainable Unit Tests?
Struggling to Create Maintainable Unit Tests?Alistair McKinnell
Ā 

More from Alistair McKinnell (14)

Succeeding with Specification by Example
Succeeding with Specification by ExampleSucceeding with Specification by Example
Succeeding with Specification by Example
Ā 
Don't Settle for Poor Names (Or Poor Design)
Don't Settle for Poor Names (Or Poor Design)Don't Settle for Poor Names (Or Poor Design)
Don't Settle for Poor Names (Or Poor Design)
Ā 
Don't Settle for Poor Names
Don't Settle for Poor NamesDon't Settle for Poor Names
Don't Settle for Poor Names
Ā 
The Boy Scout Rule
The Boy Scout RuleThe Boy Scout Rule
The Boy Scout Rule
Ā 
Advanced Developer Testing
Advanced Developer TestingAdvanced Developer Testing
Advanced Developer Testing
Ā 
Ubiquitous Testing
Ubiquitous TestingUbiquitous Testing
Ubiquitous Testing
Ā 
Commonality and Variability Analysis: Avoiding Duplicate Code
Commonality and Variability Analysis: Avoiding Duplicate CodeCommonality and Variability Analysis: Avoiding Duplicate Code
Commonality and Variability Analysis: Avoiding Duplicate Code
Ā 
Simple Design
Simple DesignSimple Design
Simple Design
Ā 
Agile Tour Shanghai December 2011
Agile Tour Shanghai December 2011Agile Tour Shanghai December 2011
Agile Tour Shanghai December 2011
Ā 
Pair Programming
Pair ProgrammingPair Programming
Pair Programming
Ā 
Agile Transition in Trouble? Using the Kotter Change Model as a Diagnostic Tool
Agile Transition in Trouble? Using the Kotter Change Model as a Diagnostic ToolAgile Transition in Trouble? Using the Kotter Change Model as a Diagnostic Tool
Agile Transition in Trouble? Using the Kotter Change Model as a Diagnostic Tool
Ā 
The Story of a Story
The Story of a StoryThe Story of a Story
The Story of a Story
Ā 
The Testing Landscape
The Testing LandscapeThe Testing Landscape
The Testing Landscape
Ā 
Struggling to Create Maintainable Unit Tests?
Struggling to Create Maintainable Unit Tests?Struggling to Create Maintainable Unit Tests?
Struggling to Create Maintainable Unit Tests?
Ā 

Recently uploaded

DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
Ā 
Elevate Developer Efficiency & build GenAI Application with Amazon Qā€‹
Elevate Developer Efficiency & build GenAI Application with Amazon Qā€‹Elevate Developer Efficiency & build GenAI Application with Amazon Qā€‹
Elevate Developer Efficiency & build GenAI Application with Amazon Qā€‹Bhuvaneswari Subramani
Ā 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
Ā 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...apidays
Ā 
Mcleodganj Call Girls šŸ„° 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls šŸ„° 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls šŸ„° 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls šŸ„° 8617370543 Service Offer VIP Hot ModelDeepika Singh
Ā 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
Ā 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
Ā 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
Ā 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
Ā 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
Ā 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
Ā 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
Ā 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
Ā 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
Ā 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
Ā 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
Ā 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
Ā 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
Ā 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
Ā 

Recently uploaded (20)

DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
Ā 
Elevate Developer Efficiency & build GenAI Application with Amazon Qā€‹
Elevate Developer Efficiency & build GenAI Application with Amazon Qā€‹Elevate Developer Efficiency & build GenAI Application with Amazon Qā€‹
Elevate Developer Efficiency & build GenAI Application with Amazon Qā€‹
Ā 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
Ā 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Ā 
Mcleodganj Call Girls šŸ„° 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls šŸ„° 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls šŸ„° 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls šŸ„° 8617370543 Service Offer VIP Hot Model
Ā 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
Ā 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
Ā 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Ā 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
Ā 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
Ā 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Ā 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
Ā 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Ā 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Ā 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Ā 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
Ā 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
Ā 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Ā 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
Ā 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
Ā 

What Can Journalists Teach Developers About Writing Source Code?

  • 1. What Can Journalists Teach Developers About Writing Source Code? Alex Aitken @alexaitken Alistair McKinnell @amckinnell
  • 2. In some sense techniques for controllingā€Ø complexity is what computer science is about. Harold Abelson
  • 3. Agenda What Is Inverted Pyramid ? ! Writing Source Code Using Inverted Pyramid
  • 4. What Is Inverted Pyramid ?
  • 5. The inverted pyramid is a metaphor ā€Ø used by journalists to illustrate how ā€Ø information should be prioritized.
  • 6. ā€œThe Leadā€ The Lead ā€œThe Bodyā€ ā€œThe Tailā€
  • 7. ā€œThe Leadā€ The Lead ā€œThe Bodyā€ ā€œThe Tailā€ ā€œThe Leadā€: the mostā€Ø important information
  • 8. ā€œThe Leadā€ The Lead ā€œThe Bodyā€ ā€œThe Tailā€ ā€œThe Leadā€: the mostā€Ø important information ā€œThe Bodyā€: the crucialā€Ø information
  • 9. ā€œThe Leadā€ The Lead ā€œThe Bodyā€ ā€œThe Tailā€ ā€œThe Leadā€: the mostā€Ø important information ā€œThe Bodyā€: the crucialā€Ø information ā€œThe Tailā€: any extraā€Ø information
  • 10. The Lead Beneļ¬ts for Readers 1. Readers can leave an article at any point and understand it, even if they do not have all the details. 2. For those readers who wish to proceed, it conducts them through the article details.
  • 12. 1 ā€¢ ā€¢ ā€¢ Arrange cards as above 1ā€“2 groups per table 3ā€“4 people per group 22 2 2
  • 13. Some Boos at Graduation After Judge Bars Prayer Associated Press May 21, 2001 WASHINGTON, Ill. - A top student who gave a traditional farewell speech at a high school graduation was booed and another student was applauded for holding a moment of silence after a judge barred prayer at the ceremony. ā€¢ ā€¢ ā€¢ ā€¢ 22 2 2 Experience inverted pyramid Read one card at a time You have 4 minutes Itā€™s not important to read all cards
  • 14. Some Boos at Graduation After Judge Bars Prayer Associated Press May 21, 2001 ā€œThe Leadā€ WASHINGTON, Ill. - A top student who gave a traditional farewell speech at a high school graduation was booed and another student was applauded for holding a moment of silence after a judge barred prayer at the ceremony. A federal judge issued a restraining order days before Sunday's ceremony at Washington Community High School blocking any student-led prayer. It was the ļ¬rst time in the 80-year history of the school that no graduation prayers were said. The Lead ā€œThe Bodyā€ Natasha Appenheimer, the class valedictorian, traditionally a top student chosen to give the class graduation speech, was booed when she received her diploma. Her family, backed by the American Civil Liberties Union, had ļ¬led the lawsuit that led to the restraining order. Meanwhile, some stood and applauded class speaker Ryan Brown when he bowed his head for a moment of silence before his speech. About 200 people attended a prayer vigil before the ceremony, and a placard-carrying atheist and a Pentecostal minister got into a shouting match. In spite of the turbulent atmosphere, Appenheimer said she wasn't upset by the way things turned out. ā€œThe Tailā€ "It's my graduation. I'm happy," she said. The lawsuit "was worth it. We changed things, we righted a wrong and made something better than it was before. I learned that when you believe in something, you should stand up for it." Graduate Annie White disagreed, saying many class members wanted to demonstrate that "God was a part of our graduation." Superintendent Lee Edwards said the school district might appeal McDade's ruling. He said the invocation and benediction prayers usually said at the ceremony were innocuous, and "You would have to have been working pretty hard to be offended." School district ofļ¬cials defended the prayer on grounds that students, not administrators, were in charge of graduation. The Supreme Court's landmark 1962 decision outlawed organized prayer in public schools. In 1992, the justices barred clergy-led prayers at graduations, and last year, the court barred ofļ¬cials from letting students lead crowds in prayer before football games.
  • 15. public class StringCalculator { ! ! ! ! ! public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); failWhenContainsNegatives(values); return sumOf(values); } private String[] parseValues(String numbers) { if (numbers.isEmpty()) { return new String[] {}; } if (containsCustomDelimiters(numbers)) { return parseCustomDelimitedValues(numbers); } ! ! ! ! ! } private List<Integer> convertToInteger(String[] numbers) { List<Integer> result = new ArrayList<>(); ! ! ! } private boolean containsCustomDelimiters(String numbers) { return numbers.startsWith("//"); } private String[] parseCustomDelimitedValues(String numbers) { int newlineIndex = numbers.indexOf('n'); String delimiters = numbers.substring(2, newlineIndex); String numberList = numbers.substring(newlineIndex + 1); String[] customDelimiters = parseCustomDelimiters(delimiters); ! ! for (String customDelimiter : customDelimiters) { numberList = numberList.replaceAll( quoteRegularExpression(customDelimiter), ","); } ! return result; } private void failWhenContainsNegatives(List<Integer> values) { List<Integer> negatives = new ArrayList<>(); for (Integer value : values) { if (value < 0) negatives.add(value); } if (!negatives.isEmpty()) { String message = "Error: negatives not allowed " + negatives; throw new RuntimeException(message); } } return result; for (String number : numbers) { result.add(toInteger(number)); } ! for (Integer value : values) { result += value; } ! return parseStandardDelimiters(numbers); ! ! private int sumOf(List<Integer> values) { int result = 0; ! ! ! ! ! } return numberList.split(","); } private String[] parseCustomDelimiters(String rawCustomDelimiters) { return rawCustomDelimiters.replaceAll("[", "").split("]"); } private String quoteRegularExpression(String customSeparator) { return "Q" + customSeparator + "E"; } private String[] parseStandardDelimiters(String numbers) { return numbers.split("[,n]"); } private Integer toInteger(String number) { Integer value = Integer.parseInt(number); return value <= 1000 ? value : 0; }
  • 16. Beneļ¬ts for Readers public class StringCalculator { ! ! ! The Lead ! public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); private int int ! for result += value; failWhenContainsNegatives(values); return sumOf(values); } } ! ! return } 1. Readers can leave an article at any point ! ! ! and understand it, even if they do not ! have all the details. ! ! private String[] parseValues(String numbers) { if (numbers.isEmpty()) { return } private return } private int if (containsCustomDelimiters(numbers)) { return } String delimiters = numbers.substring(2, newlineIndex); String numberList = numbers.substring(newlineIndex + 1); return parseStandardDelimiters(numbers); } ! String[] customDelimiters = parseCustomDelimiters(delimiters); private List<Integer> convertToInteger(String[] numbers) { List<Integer> result = for for (String number : numbers) { result.add(toInteger(number)); } numberList = numberList.replaceAll( quoteRegularExpression(customDelimiter), } ! ! 2. For those readers who wish to proceed, it ! ! conducts them through the article details. ! ! return } return result; } private return } private void failWhenContainsNegatives(List<Integer> values) { List<Integer> negatives = for (Integer value : values) { if (value < 0) negatives.add(value); } ! if (!negatives.isEmpty()) { String message = throw } } ! ! ! ! } private return } private return } private Integer value = Integer.parseInt(number); return }
  • 17. The Lead Beneļ¬ts for Developers 1. Readers can leave an article at any point and understand it, even if they do not have all the details. 2. For those readers who wish to proceed, it conducts them through the article details.
  • 18. The Lead Beneļ¬ts for Developers 1. ā€ØDevelopers can leave source code at any ā€Øpoint and understand it, even if they do not have all the details. 2. For those readers who wish to proceed, it conducts them through the article details.
  • 19. The Lead Beneļ¬ts for Developers 1. Developers can leave source code at any point and understand it, even if they do not have all the details. 2. For those developers who need to see more implementation details, it conducts them through the source code.
  • 20. The Lead Beneļ¬ts for Developers 1. Understanding without all the details 2. Details are effectively organized
  • 22. Lead ā€¢ ā€¢ Body Body Body Same groups as last exercise Arrange cards as above Tail Tail Tail
  • 25. public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); failWhenContainsNegatives(values); return sumOf(values); } Body Body Body Tail Tail Tail ā€¢ ā€¢ Flip over the card labelled Lead ā€¢ Share that understanding with your group What can you say about the add() method from reading the Lead card ?
  • 26. public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); failWhenContainsNegatives(values); private String[] parseValues(String numbers) { if (numbers.isEmpty()) { return new String[] {}; } return sumOf(values); if (containsCustomDelimiters(numbers)) { return parseCustomDelimitedValues(numbers); } } Body Body return parseStandardDelimiters(numbers); } Tail Tail Tail ā€¢ ā€¢ Flip over the Body cards one at a time ā€¢ ā€¢ Next, ļ¬‚ip over the Tail cards Ask yourself: What do I notice about the code after reading each card ? Itā€™s not important to read all cards
  • 27. public class StringCalculator { ! ! ! ! ! public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); failWhenContainsNegatives(values); return sumOf(values); } private String[] parseValues(String numbers) { if (numbers.isEmpty()) { return new String[] {}; } if (containsCustomDelimiters(numbers)) { return parseCustomDelimitedValues(numbers); } ! ! ! ! ! } private List<Integer> convertToInteger(String[] numbers) { List<Integer> result = new ArrayList<>(); ! ! ! } private boolean containsCustomDelimiters(String numbers) { return numbers.startsWith("//"); } private String[] parseCustomDelimitedValues(String numbers) { int newlineIndex = numbers.indexOf('n'); String delimiters = numbers.substring(2, newlineIndex); String numberList = numbers.substring(newlineIndex + 1); String[] customDelimiters = parseCustomDelimiters(delimiters); ! ! for (String customDelimiter : customDelimiters) { numberList = numberList.replaceAll( quoteRegularExpression(customDelimiter), ","); } ! return result; } private void failWhenContainsNegatives(List<Integer> values) { List<Integer> negatives = new ArrayList<>(); for (Integer value : values) { if (value < 0) negatives.add(value); } if (!negatives.isEmpty()) { String message = "Error: negatives not allowed " + negatives; throw new RuntimeException(message); } } return result; for (String number : numbers) { result.add(toInteger(number)); } ! for (Integer value : values) { result += value; } ! return parseStandardDelimiters(numbers); ! ! private int sumOf(List<Integer> values) { int result = 0; ! ! ! ! ! } return numberList.split(","); } private String[] parseCustomDelimiters(String rawCustomDelimiters) { return rawCustomDelimiters.replaceAll("[", "").split("]"); } private String quoteRegularExpression(String customSeparator) { return "Q" + customSeparator + "E"; } private String[] parseStandardDelimiters(String numbers) { return numbers.split("[,n]"); } private Integer toInteger(String number) { Integer value = Integer.parseInt(number); return value <= 1000 ? value : 0; }
  • 28. public class StringCalculator { ! public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); ! failWhenContainsNegatives(values); ! return sumOf(values); }
  • 29. public class StringCalculator { ! public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); ! failWhenContainsNegatives(values); ! return sumOf(values); }
  • 30. The Lead Understanding without all the detail Details are effectively organized
  • 31. Writing Source Code Using Inverted Pyramid
  • 32. Compose Method ! You canā€™t rapidly understand a methodā€™s logic. ! Transform the logic into a small number of intentionrevealing steps at the same level of detail.
  • 33. Composed Method ! Compose methods out of calls to other methods, each of which is at roughly the same level of abstraction.
  • 34. Composed Method and SLAP ! Composed method encourages factoring (or refactoring) code into small, cohesive, readable chunks. SLAP stands for the Single ā€Ø Level of Abstraction Principle.
  • 36. public int add(String numbers) { List<Integer> negatives = new ArrayList<>(); int sum = 0; for (String number : parseValues(numbers)) { Integer value = Integer.parseInt(number); if (value < 0) { negatives.add(value); } else if (value <= 1000) { sum += value; } } if (!negatives.isEmpty()) { throw new RuntimeException("Error: negatives not allowed " + negatives); } return sum; }
  • 37. public int add(String numbers) { List<Integer> negatives = new ArrayList<>(); int sum = 0; for (String number : parseValues(numbers)) { Integer value = Integer.parseInt(number); if (value < 0) { negatives.add(value); } else if (value <= 1000) { sum += value; } } if (!negatives.isEmpty()) { throw new RuntimeException("Error: negatives not allowed " + negatives); } return sum; } You canā€™t rapidly understandā€Ø a methodā€™s logic.
  • 38. public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); ! failWhenContainsNegatives(values); ! return sumOf(values); } Compose methods out of calls to other methods, each of which is at roughly the same level of abstraction.
  • 39. public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers)); ! failWhenContainsNegatives(values); ! return sumOf(values); } Understanding without all the detail The Lead Details are effectively organized
  • 44. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (numbers.startsWith("//")) { int newlineIndex = numbers.indexOf('n'); String delimiters = numbers.substring(2, newlineIndex); String numberList = numbers.substring(newlineIndex + 1); String[] customDelimiters = delimiters. replaceAll("[", "").split("]"); for (String customDelimiter : customDelimiters) { numberList = numberList. replaceAll("Q" + customDelimiter + "E", ","); } return numberList.split(","); } ! return numbers.split("[,n]"); }
  • 45. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (numbers.startsWith("//")) { int newlineIndex = numbers.indexOf('n'); String delimiters = numbers.substring(2, newlineIndex); String numberList = numbers.substring(newlineIndex + 1); String[] customDelimiters = delimiters. replaceAll("[", "").split("]"); for (String customDelimiter : customDelimiters) { numberList = numberList. replaceAll("Q" + customDelimiter + "E", ","); } return numberList.split(","); } ! return numbers.split("[,n]"); }
  • 46. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (numbers.startsWith("//")) { return parseCustomDelimitedValues(numbers); } ! return numbers.split("[,n]"); }
  • 47. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (numbers.startsWith("//")) { return parseCustomDelimitedValues(numbers); } ! return numbers.split("[,n]"); } SLAP stands for the Single ā€Ø Level of Abstraction Principle.
  • 48. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (numbers.startsWith("//")) { return parseCustomDelimitedValues(numbers); } ! return numbers.split("[,n]"); } SLAP stands for the Single ā€Ø Level of Abstraction Principle.
  • 49. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (numbers.startsWith("//")) { return parseCustomDelimitedValues(numbers); } ! return numbers.split("[,n]"); }
  • 50. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (containsCustomDelimiters(numbers)) { return parseCustomDelimitedValues(numbers); } ! return numbers.split("[,n]"); }
  • 51. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (containsCustomDelimiters(numbers)) { return parseCustomDelimitedValues(numbers); } ! return parseStandardDelimiters(numbers); }
  • 52. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (containsCustomDelimiters(numbers)) { return parseCustomDelimitedValues(numbers); } ! return parseStandardDelimiters(numbers); } SLAP stands for the Single ā€Ø Level of Abstraction Principle.
  • 53. private String[] parseValues(String numbers) { if (numbers.isEmpty()) return new String[] {}; ! if (containsCustomDelimiters(numbers)) { return parseCustomDelimitedValue(numbers); } ! return parseStandardDelimiters(numbers); } Understanding without all the detail The Lead Details are effectively organized
  • 57. Compose Method Liabilities ā€¢ Can lead to an overabundance of small methods. ā€¢ Can make debugging difļ¬cult because logic is ā€Ø spread out across many small methods. Refactoring to Patterns
  • 58. Compose Method Beneļ¬ts ā€¢ Efļ¬ciently communicates what a method does ā€Ø and how it does what it does. ā€¢ Simpliļ¬es a method by breaking it up into ā€Ø well-named chunks of behaviour at the ā€Ø same level of detail. Refactoring to Patterns
  • 59. ā€œThe Leadā€ The Lead ā€œThe Bodyā€ ā€œThe Tailā€
  • 60. The Lead Beneļ¬ts for Developers 1. Developers can leave source code at any point and understand it, even if they do not have all the details. 2. For those developers who need to see more implementation details, it conducts them through the source code.
  • 62. 1 ā€¢ ā€¢ Grab an index card to write on Write down 2 things you are going to consider next time you write code
  • 63. 1 ā€¢ Take turns sharing what you wrote with everyone at your table ā€¢ This is optional. Unlike in kindergarten, you donā€™t have to share
  • 64. In some sense techniques for controllingā€Ø complexity is what computer science is about. Harold Abelson
  • 65. The Lead Beneļ¬ts for Developers 1. Understanding without all the details 2. Details are effectively organized
  • 66. You know you are working on clean codeā€Ø when each routine you read turns out to be pretty much what you expected. Ward Cunningham
  • 67. Books Refactoring to Patterns Joshua Kerievsky Implementation Patterns Kent Beck The Productive Programmer Neal Ford Clean Code Robert C. Martin