what can journalists teach developers about writing source code?

68
What Can Journalists Teach Developers About Writing Source Code? Alex Aitken @alexaitken Alistair McKinnell @amckinnell

Upload: alistair-mckinnell

Post on 01-Nov-2014

395 views

Category:

Technology


2 download

DESCRIPTION

Today's programs are more complicated than ever. Overwhelming detail threatens to prevent developers from writing code that can be understood and safely changed. Exactly how to organize all this detail is a significant challenge. Luckily there is something that developers can learn from journalists. The Inverted Pyramid is a writing style that journalists use to organize the details in newspaper articles. It provides two important benefits for readers. First, readers can leave an article at any point and understand it, even if they do not have all the details. Second, for those readers who wish to proceed, it conducts them through the article details.

TRANSCRIPT

Page 1: What Can Journalists Teach Developers About Writing Source Code?

What Can Journalists Teach Developers About Writing Source Code?

Alex Aitken @alexaitken

Alistair McKinnell @amckinnell

Page 2: What Can Journalists Teach Developers About Writing Source Code?

In some sense techniques for controllingcomplexity is what computer science is about.

Harold Abelson

Page 3: What Can Journalists Teach Developers About Writing Source Code?

Agenda

What Is Inverted Pyramid ? !

Writing Source Code Using Inverted Pyramid

Page 4: What Can Journalists Teach Developers About Writing Source Code?

What Is Inverted Pyramid ?

Page 5: What Can Journalists Teach Developers About Writing Source Code?

The inverted pyramid is a metaphor used by journalists to illustrate how information should be prioritized.

Page 6: What Can Journalists Teach Developers About Writing Source Code?

The Lead

“The Lead”

“The Body”

“The Tail”

Page 7: What Can Journalists Teach Developers About Writing Source Code?

“The Lead”: the most important information

The Lead

“The Lead”

“The Body”

“The Tail”

Page 8: What Can Journalists Teach Developers About Writing Source Code?

The Lead

“The Lead”

“The Body”

“The Tail”

“The Lead”: the most important information

“The Body”: the crucial information

Page 9: What Can Journalists Teach Developers About Writing Source Code?

The Lead

“The Lead”

“The Body”

“The Tail”

“The Lead”: the most important information

“The Body”: the crucial information

“The Tail”: any extra information

Page 10: What Can Journalists Teach Developers About Writing Source Code?

The Lead

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.

Benefits for Readers

Page 11: What Can Journalists Teach Developers About Writing Source Code?

Exercise

Page 12: What Can Journalists Teach Developers About Writing Source Code?

• Arrange cards as above • 1–2 groups per table • 3–4 people per group

1 2222

Page 13: What Can Journalists Teach Developers About Writing Source Code?

• 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 PrayerAssociated PressMay 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. 2222

Page 14: What Can Journalists Teach Developers About Writing Source Code?

The Lead

“The Lead”

“The Body”

“The Tail”

Some Boos at Graduation After Judge Bars Prayer Associated PressMay 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.

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 first time in the 80-year history of the school that no graduation prayers were said.

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

"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 officials 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 officials from letting students lead crowds in prayer before football games.

Page 15: What Can Journalists Teach Developers About Writing Source Code?

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); }! return parseStandardDelimiters(numbers); }! private List<Integer> convertToInteger(String[] numbers) { List<Integer> result = new ArrayList<>();! for (String number : numbers) { result.add(toInteger(number)); }! 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); } }

private int sumOf(List<Integer> values) { int result = 0;! for (Integer value : values) { result += value; }! return result; }! 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 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; }!}

Page 16: What Can Journalists Teach Developers About Writing Source Code?

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 }! if (containsCustomDelimiters(numbers)) { return }! return parseStandardDelimiters(numbers); }! private List<Integer> convertToInteger(String[] numbers) { List<Integer> result = ! for (String number : numbers) { result.add(toInteger(number)); }! return result; }! 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 int int! for result += value; }! return }! private return }! private int! String delimiters = numbers.substring(2, newlineIndex); String numberList = numbers.substring(newlineIndex + 1); String[] customDelimiters = parseCustomDelimiters(delimiters);! for numberList = numberList.replaceAll( quoteRegularExpression(customDelimiter), }! return }! private return }! private return }! private return }! private Integer value = Integer.parseInt(number);! return }!}

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.

Benefits for ReadersThe Lead

Page 17: What Can Journalists Teach Developers About Writing Source Code?

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.

Benefits for DevelopersThe Lead

Page 18: What Can Journalists Teach Developers About Writing Source Code?

1.

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

Benefits for Developers

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

The Lead

Page 19: What Can Journalists Teach Developers About Writing Source Code?

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.

Benefits for DevelopersThe Lead

Page 20: What Can Journalists Teach Developers About Writing Source Code?

1. Understanding without all the details

2. Details are effectively organized

Benefits for DevelopersThe Lead

Page 21: What Can Journalists Teach Developers About Writing Source Code?

Exercise

Page 22: What Can Journalists Teach Developers About Writing Source Code?

• Same groups as last exercise • Arrange cards as above

TailTailTailBodyBodyBodyLead

Page 23: What Can Journalists Teach Developers About Writing Source Code?

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)

Page 24: What Can Journalists Teach Developers About Writing Source Code?

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)

“//#\n2#4#6”

Page 25: What Can Journalists Teach Developers About Writing Source Code?

• Flip over the card labelled Lead • What can you say about the add()

method from reading the Lead card ? • Share that understanding with your group

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

failWhenContainsNegatives(values);

return sumOf(values);}

TailTailTail

BodyBodyBodyBody

BodyBodyBody

Page 26: What Can Journalists Teach Developers About Writing Source Code?

• Flip over the Body cards one at a time • Ask yourself: What do I notice about the

code after reading each card ? • Next, flip over the Tail cards • It’s not important to read all cards

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

failWhenContainsNegatives(values);

return sumOf(values);}

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

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

return parseStandardDelimiters(numbers);}

Page 27: What Can Journalists Teach Developers About Writing Source Code?

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); }! return parseStandardDelimiters(numbers); }! private List<Integer> convertToInteger(String[] numbers) { List<Integer> result = new ArrayList<>();! for (String number : numbers) { result.add(toInteger(number)); }! 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); } }

private int sumOf(List<Integer> values) { int result = 0;! for (Integer value : values) { result += value; }! return result; }! 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 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; }!}

Page 28: What Can Journalists Teach Developers About Writing Source Code?

public class StringCalculator {! public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers));! failWhenContainsNegatives(values);! return sumOf(values); }

Page 29: What Can Journalists Teach Developers About Writing Source Code?

public class StringCalculator {! public int add(String numbers) { List<Integer> values = convertToInteger(parseValues(numbers));! failWhenContainsNegatives(values);! return sumOf(values); }

Page 30: What Can Journalists Teach Developers About Writing Source Code?

The Lead

Understanding without all the detail

Details are effectively organized

Page 31: What Can Journalists Teach Developers About Writing Source Code?

Writing Source Code Using Inverted Pyramid

Page 32: What Can Journalists Teach Developers About Writing Source Code?

Compose Method !

You can’t rapidly understand a method’s logic.

!

Transform the logic into a small number of intention-revealing steps at the same

level of detail.

Page 33: What Can Journalists Teach Developers About Writing Source Code?

Composed Method !

Compose methods out of calls to other methods, each

of which is at roughly the same level of abstraction.

Page 34: What Can Journalists Teach Developers About Writing Source Code?

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.

Page 35: What Can Journalists Teach Developers About Writing Source Code?

Example

Page 36: What Can Journalists Teach Developers About Writing Source Code?

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;}

Page 37: What Can Journalists Teach Developers About Writing Source Code?

You can’t rapidly understanda method’s logic.

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;}

Page 38: What Can Journalists Teach Developers About Writing Source Code?

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);}

Page 39: What Can Journalists Teach Developers About Writing Source Code?

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

Understanding without all the detail

Details are effectively organized

The Lead

Page 40: What Can Journalists Teach Developers About Writing Source Code?

Example

Page 41: What Can Journalists Teach Developers About Writing Source Code?

The Lead

Page 42: What Can Journalists Teach Developers About Writing Source Code?

The Lead

Page 43: What Can Journalists Teach Developers About Writing Source Code?

The Lead

Page 44: What Can Journalists Teach Developers About Writing Source Code?

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]");}

Page 45: What Can Journalists Teach Developers About Writing Source Code?

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]");}

Page 46: What Can Journalists Teach Developers About Writing Source Code?

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

Page 47: What Can Journalists Teach Developers About Writing Source Code?

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.

Page 48: What Can Journalists Teach Developers About Writing Source Code?

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.

Page 49: What Can Journalists Teach Developers About Writing Source Code?

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

Page 50: What Can Journalists Teach Developers About Writing Source Code?

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

Page 51: What Can Journalists Teach Developers About Writing Source Code?

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

Page 52: What Can Journalists Teach Developers About Writing Source Code?

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.

Page 53: What Can Journalists Teach Developers About Writing Source Code?

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

Details are effectively organized

The Lead

Page 54: What Can Journalists Teach Developers About Writing Source Code?

Applying Inverted Pyramid

Page 55: What Can Journalists Teach Developers About Writing Source Code?

The Lead

Page 56: What Can Journalists Teach Developers About Writing Source Code?

The Lead

Page 57: What Can Journalists Teach Developers About Writing Source Code?

•Can lead to an overabundance of small methods.

•Can make debugging difficult because logic is spread out across many small methods.

Compose Method

Refactoring to Patterns

Liabilities

Page 58: What Can Journalists Teach Developers About Writing Source Code?

• Efficiently communicates what a method does and how it does what it does.

• Simplifies a method by breaking it up into well-named chunks of behaviour at the same level of detail.

Compose Method

Refactoring to Patterns

Benefits

Page 59: What Can Journalists Teach Developers About Writing Source Code?

The Lead

“The Lead”

“The Body”

“The Tail”

Page 60: What Can Journalists Teach Developers About Writing Source Code?

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.

Benefits for DevelopersThe Lead

Page 61: What Can Journalists Teach Developers About Writing Source Code?

Exercise

Page 62: What Can Journalists Teach Developers About Writing Source Code?

• Grab an index card to write on • Write down 2 things you are going to

consider next time you write code

1

Page 63: What Can Journalists Teach Developers About Writing Source Code?

• Take turns sharing what you wrote with everyone at your table

• This is optional. Unlike in kindergarten, you don’t have to share

1

Page 64: What Can Journalists Teach Developers About Writing Source Code?

In some sense techniques for controllingcomplexity is what computer science is about.

Harold Abelson

Page 65: What Can Journalists Teach Developers About Writing Source Code?

1. Understanding without all the details

2. Details are effectively organized

Benefits for DevelopersThe Lead

Page 66: What Can Journalists Teach Developers About Writing Source Code?

Ward Cunningham

You know you are working on clean code when each routine you read turns out to be

pretty much what you expected.

Page 67: What Can Journalists Teach Developers About Writing Source Code?

Refactoring to Patterns Joshua Kerievsky

Implementation Patterns Kent Beck

The Productive Programmer Neal Ford

Clean Code Robert C. Martin

Book

s

Page 68: What Can Journalists Teach Developers About Writing Source Code?

Phot

os www.flickr.com/photos/ecu_digital_collections/3288382289/

www.morguefile.com/archive/display/848917