diff --git a/_learning_hours/code_reading/code_smells_intro.md b/_learning_hours/code_reading/code_smells_intro.md index fc7e746..8d63b4a 100644 --- a/_learning_hours/code_reading/code_smells_intro.md +++ b/_learning_hours/code_reading/code_smells_intro.md @@ -10,6 +10,8 @@ author: emilybache It's useful to have a vocabulary for talking about refactoring. It will help you to communicate when doing strong-style pairing or mob programming. Code smells is perhaps a less-known concept than refactoring and knowing these names will also help you to communicate about code, and identify targets for refactoring. In this learning hour we'll talk about what a code smell is and learn the names of some common ones. +There is a video on Emily Bache's YouTube channel for this learning hour: ["How to Smell Bad Code"](https://youtu.be/L-cN7NI-Fes) + ## Learning Goals * Describe the term "Code Smell" * Use 'Scanning' to find the 'Long Method' code smell quickly diff --git a/_learning_hours/refactoring/change_signature.md b/_learning_hours/refactoring/change_signature.md index 01393ff..4bbc29f 100644 --- a/_learning_hours/refactoring/change_signature.md +++ b/_learning_hours/refactoring/change_signature.md @@ -11,6 +11,9 @@ affiliation: ProAgile Let's practice using this refactoring, especially if refactoring tools are new to the team. +There is a video on Emily Bache's YouTube channel for this learning hour: ["Unlock the Power of Refactoring in Everyday OO Design"](https://youtu.be/sngRW3zPiiE) + + ## Learning Goals * describe what the "Change Signature" refactoring does diff --git a/_learning_hours/refactoring/conditional_to_polymorphism.md b/_learning_hours/refactoring/conditional_to_polymorphism.md index aca65bf..9c4a4f7 100644 --- a/_learning_hours/refactoring/conditional_to_polymorphism.md +++ b/_learning_hours/refactoring/conditional_to_polymorphism.md @@ -12,6 +12,8 @@ affiliation: Praqma This refactoring replaces conditional logic with classes and polymorphism. The code smell that leads you to it is having a lot of similar switch statements that switch on type. In this session we'll practice doing it, and hopefully see just how good modern IDE tooling is for this kind of task. +There is a video on Emily Bache's YouTube channel for this learning hour: ["Everyday Design Improvements in OO Code"](https://youtu.be/NCEWAqEFPic) + ## Learning Goals * Use refactoring tools and keyboard shortcuts while refactoring diff --git a/_learning_hours/refactoring/extract_function.md b/_learning_hours/refactoring/extract_function.md index bdc2352..93b87a6 100644 --- a/_learning_hours/refactoring/extract_function.md +++ b/_learning_hours/refactoring/extract_function.md @@ -9,7 +9,10 @@ author: emilybache # Vocabulary for Refactoring -It's useful to have a vocabularly for talking about refactoring. It will help you to communicate when doing strong-style pairing or mob programming. In this learning hour we'll learn what refactorings are and the names of some of them. We'll also practice applying Extract Function in order to address a Long Function smell. +It's useful to have a vocabulary for talking about refactoring. It will help you to communicate when doing strong-style pairing or mob programming. In this learning hour we'll learn what refactorings are and the names of some of them. We'll also practice applying Extract Function in order to address a Long Function smell. + +There is a video on Emily Bache's YouTube channel for this learning hour: ["Refactoring Skills: Extract Function"](https://youtu.be/lOAktlPd8uk) + ## Learning Goals diff --git a/_learning_hours/refactoring/identify_paragraphs.md b/_learning_hours/refactoring/identify_paragraphs.md index b7a904e..1b0f4d5 100644 --- a/_learning_hours/refactoring/identify_paragraphs.md +++ b/_learning_hours/refactoring/identify_paragraphs.md @@ -12,6 +12,9 @@ via: emilybache [Long function]({% link _code_smells/long_function.md %}) is a common code smell. Learning to identify paragraphs that can be extracted as methods is often a good strategy in this situation. This learning hour is about understanding concepts and people will probably not be able to use this technique fluently without a follow-up session. It is adapted from a longer session that is detailed [in this repo](https://github.com/LearnWithLlew/RefactoringToCleanerCode.Slides). +There is a video on Emily Bache's YouTube channel for this learning hour: ["Reduce Method Sprawl with Code Paragraphs"](https://youtu.be/tPz1riXOrYk) + + ## Learning Goals * Recognize paragraphs in a long method diff --git a/_learning_hours/refactoring/law_of_demeter.md b/_learning_hours/refactoring/law_of_demeter.md index 21ca757..ccacb52 100644 --- a/_learning_hours/refactoring/law_of_demeter.md +++ b/_learning_hours/refactoring/law_of_demeter.md @@ -13,6 +13,8 @@ affiliation: ProAgile This learning hour introduces the Law of Demeter and some concrete techniques for tackling code that breaks it. +There is a video on Emily Bache's YouTube channel on this topic but using a different exercise ["Law of Demeter"](https://youtu.be/Wa49D-akQb8) + ## Session outline * 10 min connect: Recognize these smells? diff --git a/_learning_hours/refactoring/misconceptions.md b/_learning_hours/refactoring/misconceptions.md index 5fe4d14..7810dbe 100644 --- a/_learning_hours/refactoring/misconceptions.md +++ b/_learning_hours/refactoring/misconceptions.md @@ -11,6 +11,8 @@ author: emilybache In this session we talk about what refactoring is and why we do it. We work on improving some names to improve readability. +There is a video on Emily Bache's YouTube channel which shows a variant on this learning hour: ["Refactoring, what you need to know"](https://youtu.be/K7xSsNpeM8I) + ## Session Outline * 15 min connect: refactoring warm-up questions diff --git a/_learning_hours/refactoring/split_variable.md b/_learning_hours/refactoring/split_variable.md new file mode 100644 index 0000000..a636afd --- /dev/null +++ b/_learning_hours/refactoring/split_variable.md @@ -0,0 +1,46 @@ +--- +theme: refactoring +title: Split Variable +name: split_variable +kata: tennis +difficulty: 3 +author: emilybache +--- + +# Split Variable + +Practice this refactoring. + +There is a video on Emily Bache's YouTube channel for this learning hour ["Prepare a Code Paragraph for Extraction with Split Variable"](https://youtu.be/wPmJz2ynb3k) + +## Session Outline + +* 5 min connect: Identify Paragraphs +* 5 min concept: Split Variable +* 10 min demo: show the patterns and the shape of the refactoring +* 25 min concrete: practice Split Variable +* 5 min conclusions: note down learnings + +## Connect: Identify Paragraphs +If the group is not familiar with code paragraphs then you should do a learning hour on that before this one. The purpose of this connect exercise is to remind them what they already know about code paragraphs by having them review some code and identify paragraphs. + +For example, show them [Theatrical Players](https://github.com/emilybache/Theatrical-Players-Refactoring-Kata). + +## Concept: Split Variable Refactoring +The reason to do split variable is often so that you can more easily extract a method for a code paragraph. Refer to [Split Variable]({% link _refactorings/split_variable.md %}) for a description of this refactoring. There are several code katas I commonly use that use it. It's a small refactoring move that's hard to practice in isolation so I usually show it several times in these different situations. + +## Demo: show the patterns and the shape of the refactoring +Depending on how confident your group will be able to do these refactorings, you may or may not need to show all of these as demos. + +1. **Plain re-use**. In Tennis 3 there is a variable 's' that is re-used both as a score name and a player name. The variable is re-used so you need to redeclare it for each new use. + +2. **Accumulating variable** In Tennis 7 there is a variable 'result' that is appended to throughout the long method 'getScore'. Before you can extract methods for each part, it is convenient to split the 'score' variable into for example 'tieScore' and 'regularScore'. This kind of accumulating variable can also be an integer like the 'volumeCredits' in Theatrical Players. + +3. **Calculated Datamember** In Office Cleaner 9 there is a method 'parseInput' that calculates two datamembers - coordHashSet and position. If you want to extract parts of this calculation to a testable pure function then it will need to be passed the current state of these datamembers explicitly. You split the assignment of the datamember from the calculation of its value by introducing a new variable for the calculation, then assigning it at the end. + +## Concrete: do split variable +Set the group loose on the refactoring in all the examples you've shown. Make sure they have access to the list of the safe steps for all variants of this refactoring, and remind them to use their tools. + +## Conclusions: when will you use this? +How will you notice you need 'split variable'? What will you do then? This is a [Write important takeaway]({% link _activities/conclusions/write_important_takeaway.md %}) conclusion. + diff --git a/_learning_hours/small_steps/demo_tdd_intro.md b/_learning_hours/small_steps/demo_tdd_intro.md index 25aa5f3..e303de8 100644 --- a/_learning_hours/small_steps/demo_tdd_intro.md +++ b/_learning_hours/small_steps/demo_tdd_intro.md @@ -12,6 +12,8 @@ This is often the first exercise I do with new teams. You have to TDD a function The first time I demonstrate this kata I usually don't show triangulation, and only do the four test cases listed in the problem description. That means I go straight to using the modulo operator when implementing the first test case. That keeps the demo shorter, and means you don't need to explain triangulation as a concept. +There is a video on Emily Bache's YouTube channel for this learning hour - ["TDD - What it is and why you should care"](https://youtu.be/OhT0_Xg-vZU) + ## Learning Goals * Describe the Red-Green-Refactor cycle * Design a pure function that takes an integer and returns a boolean, using TDD diff --git a/_learning_hours/small_steps/example_guided_design.md b/_learning_hours/small_steps/example_guided_design.md index 14561e8..fb3a804 100644 --- a/_learning_hours/small_steps/example_guided_design.md +++ b/_learning_hours/small_steps/example_guided_design.md @@ -10,6 +10,8 @@ author: emilybache This can make a good follow up after [Design in the red step](design_with_a_test.html). +There are two videos on Emily Bache's YouTube channel for learning hours on this topic - ["Usage First Design in TDD"](https://youtu.be/4xNPMbV4J4w) and ["Incremental TDD"](https://youtu.be/5BftptSNrAg) + ## Learning Objectives * Recognize the difference between a specification and an example diff --git a/_learning_hours/small_steps/smaller_steps.md b/_learning_hours/small_steps/smaller_steps.md index 1d07493..337015c 100644 --- a/_learning_hours/small_steps/smaller_steps.md +++ b/_learning_hours/small_steps/smaller_steps.md @@ -11,6 +11,8 @@ affiliation: ProAgile Inspired by Mike Hill's "Many more, much smaller steps". +There is a video on Emily Bache's YouTube channel which takes up these topics, but uses a different exercise - ["Incremental Coding for Continuous Delivery"](https://youtu.be/DIB7DVvNfnA) + ## Session Outline * 5 min connect: advantages of incremental releases diff --git a/_learning_hours/test_design/benefits_of_arrange_act_assert.md b/_learning_hours/test_design/benefits_of_arrange_act_assert.md index ab56c96..e15a7a5 100644 --- a/_learning_hours/test_design/benefits_of_arrange_act_assert.md +++ b/_learning_hours/test_design/benefits_of_arrange_act_assert.md @@ -11,6 +11,8 @@ affiliation: ProAgile This session is an intro to the topic for people who havn't written many test cases before and where the other [Arrange Act Assert](arrange_act_assert.html) learning hour is too big of a step from where they are. +There is a video on Emily Bache's YouTube channel which shows a version of this learning hour - ["3 parts of a test"](https://youtu.be/8KB5aF6QXe8) + ## Learning Goals * Recognize a test written with the Arrange - Act - Assert pattern diff --git a/_learning_hours/test_doubles/when_you_need_a_fake.md b/_learning_hours/test_doubles/when_you_need_a_fake.md index 200dcf1..4215039 100644 --- a/_learning_hours/test_doubles/when_you_need_a_fake.md +++ b/_learning_hours/test_doubles/when_you_need_a_fake.md @@ -11,6 +11,8 @@ via: emilybache In this exercise you need to use a spy or fake to test the code. +There is a video on Emily Bache's YouTube channel that goes through this learning hour ["The Fake Designer Handbag of Unit Testing"](https://youtu.be/m-1eeYq1uMI). + ## Session Outline * 10 min connect: How can you test this? @@ -32,4 +34,4 @@ Ask people to write tests for each of the bugs using test doubles. Each test sho ### Conclusions: How do you know when you need a test double? -Why did we need a test double in order to test this code? Ask [When should you use this]({% link _activities/conclusions/when_to_use_this.md %})? \ No newline at end of file +Why did we need a test double in order to test this code? Ask [When should you use this]({% link _activities/conclusions/when_to_use_this.md %})? diff --git a/_learning_hours/test_doubles/when_you_need_a_mock.md b/_learning_hours/test_doubles/when_you_need_a_mock.md new file mode 100644 index 0000000..de03eef --- /dev/null +++ b/_learning_hours/test_doubles/when_you_need_a_mock.md @@ -0,0 +1,43 @@ +--- +theme: test_doubles +title: When you need a mock +kata: auction +difficulty: 3 +author: emilybache +--- + +# When you need a mock + +In this exercise you need to use a mock or spy to test the code. + +There is a video on Emily Bache's YouTube channel that goes through this learning hour ["Mock objects: the Police Enforcer of Unit Testing"](https://youtu.be/4bCuxMhtf_E). + +## Session Outline + +* 10 min connect: How can you test this? +* 5 min concept: Explanation of test doubles +* 30 mins concrete: Write a test using a test double +* 5 min conclusion: Do you like your design? + +### Connect: How can you test this? + +Today's exercise is [Auction Test Design Kata](https://github.com/emilybache/Auction-TestDesign-Kata). Review the code in +"AuctionMessageTranslator". It is supposed to parse text messages it receives from an external source, and notify a listener. The messages are about the progress of an online auction. + +There are bugs, marked with comments. The listener interface is under development. This listener wants to know what is happening in the auction so it can decide whether to make a bid. + +How could you write tests that would fail because of each bug? Discuss in pairs. Don't write any code at this point, just talk. + +### Concept: Test Doubles + +Explain what a test double is and how we could use one in this problem. You could explain the various different kinds of test double including spy and mock. + +### Concrete: Write a test using a test double + +Ask people to write tests for each of the bugs using a mock. Each test should fail because of a bug, and pass if you change the code to fix the bug. Through this work you should design the methods in the "AuctionEventListener" interface. + +When you have fixed the bugs, add support for the additional message outlined in the README file in the repo. + +### Conclusions: Do you like your design? + +Compare the designs you have come up with for the AuctionEventListener interface. Why did we use a test double to develop this code? Ask [When should you use this]({% link _activities/conclusions/when_to_use_this.md %})? diff --git a/_learning_hours/test_doubles/when_you_need_a_spy.md b/_learning_hours/test_doubles/when_you_need_a_spy.md index 7a25a1b..b987e74 100644 --- a/_learning_hours/test_doubles/when_you_need_a_spy.md +++ b/_learning_hours/test_doubles/when_you_need_a_spy.md @@ -11,6 +11,8 @@ via: emilybache In this exercise you need to use a spy or a mock to test the code. +There is a video on Emily Bache's YouTube channel that goes through this learning hour ["The Undercover Agent in Unit Testing"](https://youtu.be/OuRtBe07T9A) + ## Session Outline * 10 min connect: How can you test this? @@ -32,4 +34,4 @@ Ask people to write tests for each of the bugs using test doubles. Each test sho ### Conclusions: How do you know when you need a test double? -Why did we need a test double in order to test this code? Ask [When should you use this]({% link _activities/conclusions/when_to_use_this.md %})? \ No newline at end of file +Why did we need a test double in order to test this code? Ask [When should you use this]({% link _activities/conclusions/when_to_use_this.md %})? diff --git a/_learning_hours/test_doubles/when_you_need_a_stub.md b/_learning_hours/test_doubles/when_you_need_a_stub.md index edd7d5c..f399a9e 100644 --- a/_learning_hours/test_doubles/when_you_need_a_stub.md +++ b/_learning_hours/test_doubles/when_you_need_a_stub.md @@ -11,6 +11,8 @@ via: emilybache In this exercise you need to use a stub to test the code. +There is a video on Emily Bache's YouTube channel that goes through this learning hour ["Using a Test Double to find bugs"](https://youtu.be/rFtYJtbAb_g). + ## Session Outline * 10 min connect: How can you test this bug? @@ -36,4 +38,4 @@ Ask people to write a test using a test double. It should fail because of the bu ### Conclusions: How do you know when you need a test double? -Why did we need a test double in order to test this code? Ask [When should you use this]({% link _activities/conclusions/when_to_use_this.md %})? \ No newline at end of file +Why did we need a test double in order to test this code? Ask [When should you use this]({% link _activities/conclusions/when_to_use_this.md %})? diff --git a/_learning_hours/testable_design/beck_simple_design.md b/_learning_hours/testable_design/beck_simple_design.md index 9bab8b8..df23464 100644 --- a/_learning_hours/testable_design/beck_simple_design.md +++ b/_learning_hours/testable_design/beck_simple_design.md @@ -13,6 +13,8 @@ Beck's rules of simple design In this learning hour we learn about Kent Beck's rules of simple design. There is no 'concrete' part of this learning hour, you don't get to practice using these rules. You should probably follow up this learning hour with a second one where you do so. +There is a YouTube video on Emily Bache's channel for this learning hour - ["You Aren't Gonna Need It: in TDD Design is Simple"](https://youtu.be/OrxqfrTPns0) + ## Session Outline * 5 min connect: vote for favourite design guidelines diff --git a/_learning_hours/testable_design/naming.md b/_learning_hours/testable_design/naming.md index 4a1b14c..c0bd744 100644 --- a/_learning_hours/testable_design/naming.md +++ b/_learning_hours/testable_design/naming.md @@ -40,6 +40,8 @@ The end goal is to have a clear language for the code, that speaks of the domain. This learning hour is a step in that direction. +There is a video on Emily Bache's YouTube channel that shows a variant on this learning hour ["Trustworthy Code with Naming as a Process"](https://youtu.be/PPQHJpWG4GA) + ## Learning objective Being able to explain how to give a piece of code a name that can be trusted. @@ -158,4 +160,4 @@ or if remote, without an editor. > Change the name to signal that it is now complete. ## Conclusions -Pair up and explain how to get to an *honest complete* name and why we want that. \ No newline at end of file +Pair up and explain how to get to an *honest complete* name and why we want that. diff --git a/_refactorings/split_variable.md b/_refactorings/split_variable.md new file mode 100644 index 0000000..4041d51 --- /dev/null +++ b/_refactorings/split_variable.md @@ -0,0 +1,54 @@ +--- +layout: refactoring +title: Split Variable +source: Emily Bache +source_url: https://refactoring.com/catalog/splitVariable.html +code_smells: variable_with_long_scope +learning_hours: split_variable +--- + +# Split Variable +This is one of the refactorings in Martin Fowler's book although I think his definition is unnecessarily narrow and I usually extend it to additional situations. + +## Examine +There are three common situations to use split variable: + +1. The same variable is re-used for different purposes. This is the first form of split variable, and the one that Martin Fowler discusses in his book. +2. An accumulating variable where you want to split off part of the calculation to another scope. +3. A global or class data member that is used in many places but only calculated in one place, and you want to split the calculation to a different (smaller) scope. + +## Prepare +Identify the variable you want to split, and make sure your tests are all passing. + +## Implement +Steps for each of the three situations: + +1. Same variable is re-used for different purposes + * Tests all passing. + * Identify a variable that needs to be split, 'x'. + * Within the lines of code you select for the first thing it does, use textual search and replace - rename 'x' to something better. + * After those lines, re-declare 'x' as a new variable. + * Tests all passing. + +2. An accumulating variable + * Tests all passing + * Identify a variable that needs to be split, 'x' + * Create a new local variable 'initial_x' and initialize it to 'x' + * Create a new local variable 'increment_x' and initialize it to an empty value eg zero + * Within the lines of code you select use textual search and replace - rename 'x' to 'increment_x' + * After those lines, re-assign x = initial_x + increment_x + * Tests all passing + +3. A global or class variable + * Tests all passing + * Identify a variable that needs to be split, 'x' + * Create a new variable 'x_local' - copy the declaration of 'x' and copy the same initial value as 'x' + * Within the lines of code you select for the new scope, use textual search and replace to replace x with x_local + * After that section of code, re-assign 'x' to the value of 'x_local' + * Tests all passing + +## Clear +It usually makes sense to review the names of the new variables and adjust them now you can see how each is used. + +## Follow up +Often you now want to extract a method to calculate one or more of the new variables.