

iteration
John Jacob & JP Sio - Web Developers
A podcast about development and design.
We do our best to be code-agnostic but we talk a lot about Rails, JavaScript, React, React Native, design, business and startups.
We do our best to be code-agnostic but we talk a lot about Rails, JavaScript, React, React Native, design, business and startups.
Episodes
Mentioned books

Jul 1, 2019 • 39min
Building Tests
Chapter 4 - Building Tests
To do refactoring properly, I need a solid suite of tests to spot my inevitable mistakes.
The Value of Self-Testing Code
make sure all tests are fully automatic and that they check their own results
a suite of tests is a powerful bug detector that decapitates the time it takes to find bugs
If you want to refactor, you have to write tests
A First Test
simplicity of feedback from tests. just dots
personally like verbose test output
Add Another Test
Testing should be risk driven; remember, I'm trying to find bugs, now or in the future. Therefore I don't test accessor methods that just read and write a field. They are so simple that I'm not likely to find a bug there.
My focus is to test areas that I'm most worried about going wrong.
Probing the Boundaries
Seeing what happens when things go wrong
Whenever I have a collection of something, ... I like to see what happens when it's empty
What happens when negative numbers are passed to a function that expects positive numbers? Division by zero?
How do you probe boundaries?
Much More Than This
When you get a bug report, start by writing a unit test that exposes the bug
Picks
JP: Taking time off

Jun 24, 2019 • 40min
Encapsulation
Episode 6 - More Code Examples
Drawing from Chapter 7 - Encapsulation
A weekly podcast about programming, development, and design through the lens of amazing books, chapter-by-chapter.
Encapsulate Record (162)
var organization = { name: "JP Sio", country: "USA" };
becomes ⬇️
class Organization {
constructor(data) {
this._name = data.name;
this._country = data.country;
}
get name() {
return this._name;
}
set name(arg) {
this._name = arg;
}
get country() {
return this._country;
}
set country(arg) {
this._country = arg;
}
}
you can hide what is stored and provide methods
consumer of class Organization doesn't need to know / care which is stored and which is calculated
nice getter and setter methods
makes it easier to refactor -> can hide implementation of internals and update the internals while keeping the same external interface
Encapsulate Collection (170)
class Person {
get courses() {
return this._courses;
}
set courses(aList) {
this._courses = aList;
}
}
becomes ⬇️
class Person {
get courses() {
return this._courses.slice();
}
addCourse(aCourse) {
/*...*/
}
}
slice() is key here, does not modify the original array - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
common approach is to provide a getting method for the collection to return a copy
basically, never mutate the original
Replace Primative with Object (174)
orders.filter(0 => "high" === o.priority || "rush" === o.priority)
becomes ⬇️
orders.filter(o => o.priority.higherThan(new Priority("normal")));
this goes back to "Primitive Obsession"
programmers are often hesitant to create their own types and rely only on primitives. i.e. representing a phone number as a string instead of as it's own type
A telephone number may be represented as a string for a while, but later it will need special behavior for formatting, extracting the area code, and the like
create a new class for that bit of data
at first, the class does very little. in fact it probably only wraps a primitive
but now you have a place to put behavior specific to its needs
Inline Function (115) 🥴
Sometimes it's better to not try to split things apart, sometimes it just complicates things.
// before refactor:
function getItemPrice(item) {
if (itemOnSale(item) == true) {
return item.price - 5
} else {
return item.price
}
};
function itemOnSale(product) {
if (product.onSale == true) {
return true;
} else {
return false;
}
};
let original = getItemPrice(sweatshirt);
// after refactor:
function newGetItemPrice(item) {
if (item.onSale == true) {
return item.price - 5
} else {
return item.price
}
};
Extract Class (182) 🥴
Talk through HUGE applicant model (in Ruby)
Broke this into child objects
Applicant Health History
Applicant Habits
Applicant Lifestyle
Applicant Method
Applicant Legal Release
Picks
JP: None :(
John: Quad Lock phone mount - bikes

Jun 17, 2019 • 44min
Bad Smells in Code
Chapter 3 - Bad Smells in Code
The theme of this chapter: just because you know how to refactor, doesn't mean you know when. This chapter talks about the when.
One thing we won't try to give you is precise criteria for when a refactoring is overdue. In our experience, no set of metrics rivals informed human intuition. What we will do is give you indications that there is trouble that can be solved by a refactoring.
Mysterious Name
there can be ambiguity in your naming in many places: variable, class, function, method, database field, etc
Duplicated Code 🔥
keep it dry
Long Functions 🔥
Since the early days of programming, people have realized that the longer a function is, the more difficult it is to understand
Long Parameter List 🔥
long parameter lists can be confusing
Global Data 🔥
the problem with global data is that it can be modified from anywhere in the codebase, making it harder to figure out which code touched it should you need to debug it
Mutable Data
changes to data often lead to unexpected consequences and tricky bugs
mutable data that can be calculated elsewhere is particularly pungent
Divergent Change ✅
if you look at a module and say, "well, I will have to change these three functions every time -------- happens" - this is an indication of divergent change
divergent change occurs when one module is often changed in different ways for different reasons
can be solved with split phase, extract function, extract class, move function
Shotgun Surgery ✅
similar to divergent change.
every you make a change, you need to make a ton of little edits to a lot of different classes
Feature Envy
occurs when a function in one module spends more time communicating with functions or data inside another module than it does within its own.
Data Clumps
grouping data together when it really should be it's own object
Primitive Obsession ✅
programmers are often hesitant to create their own types and rely only on primitives. i.e. representing a phone number as a string instead of as it's own type
Repeated Switches
alleviated with polymorphism
Loops
use pipelines instead, i.e. filter, map, each, reduce
Speculative Generality ✅
editor choice
can be spotted when the only users of a function or class are a test case. this is a classic case of premature optimization. "we'll eventually want to add this feature..."
Message Chains
when a client asks one object for another object, which the client then asks for yet another object, and so on.
Middle Man
when you have too much delegation (due to all of your great encapsulating of implementation details)
the solution is to delegate directly, cut the middle man
Insider Trading
Large Class ✅
class is doing too much
Alternative Classes with Different Interfaces
Data Class
Refused Bequest
Picks:
JP: https://classicleatherfobs.co.uk/product-category/porsche/
John: https://c-command.com/toothfairy/

Jun 10, 2019 • 42min
Refactoring 🛠Getting Into The Weeds
S06E04 - Iteration
A weekly podcast about development and design through the lens of amazing books, chapter-by-chapter
Refactors Before -
Extract Function
Change Function Decleration
Replace Temp with query
Replace conditional with polymorphism
Refactoring in Practice
Introduce Parameter Object - 140
Structure your parameters
This way order doesn’t matter
You can set default values
Grouping data is more clear in the relationship
Replace Constructor with Factory Function 334 -
Encapsulating the creation of objects (the initialize) into a factory Function
In Ruby: Creating a new User and Organization within a UserOrganizationFactory call / Tangent / Related to FormObjects.
In JavaScript: availableVariants - big array with Item, Colors, Sizes - replaced with variantFactory(34,2345,2345,) just passing ID’s
Extract Function into class - 182
Consolidate up a bunch of related functions into a parent class
Split Phase 154 - Variant of Extract Function
When a function is dealing with two different things - look for a way to split it out - was cleaner approach.
JavaScript
Cart.js - logic of API calls associated with the user input
Split this into discrete functions
Ruby
Notification logic was calling Twilio
Encapsulate this into it’s own method
Later then it was a service object to itself
My Cart.js Story - (Refactoring in Vue / JavaScript)
addItem - for adding item to cart
removeItem - for removing item from cart
increaseItemCount - for adjusting line item
decreaseItemCount - for adjusting line item
setLineItemCount - for adding to cart an initial value
First - Rename Methods (Change Function Declaration) 124
addItem - became - addItemToCart
removeItem - became - removeItemFromCart
increaseItem - became - increaseLineItemCount
decreaseItem - became - decreaseLineItemCount
Second - Extract Function 106
Both increaseLineItemCount and decreaseLineItemCount were doing something very similar.
So I created a new function of setLineItemQty
Both my methods of increaseLineItemCount and decreaseLineItemCount were then calling this setLineItemQty that accepted a qty parameter - function.
Second - parameterize Function 310
This did take a refactor of my vue listeners.
Since I had this new setLineItemQty that accepted a qty parameter
I replaced increaseLineItemCount and decreaseLineItemCount a single function of setLineItemQty
Deleted a lot of code
Third - Used inline function 106 to simply alias another function.
Through the above refactors I realized that addItemToCart was doing the same transactional work as setLineItemQty to 1
I removed the body of addItemToCart and replaced it with setLineItemQty with the default params accordingly.
Fourth - Again used inline function 106 to alias another function
Through the above refactors I realized that removeItemFromCart was doing the same transactional work as setLineItemQty to 0
I removed the body of removeItemFromCart and replaced it with setLineItemQty with the default params accordingly
Fifth - I used
I realized that all these functions were just doing the same thing. Adjusting CartLineItemCount.
The final refactor simply deleted removeItemFromCart and addItemToCart
In closing:
Code went from 160 lines to around 60
It’s way DRY
It’s way more reusable
The interface to my cart.js is now just a single function of setLineItemQty
Updated my vue listeners - Every interaction within this front end is just calling setLineItemQty
Picks:
vue.js - https://vuejs.org/ -
Burnout Reddit thrread: https://www.reddit.com/r/cscareerquestions/comments/b6xzr0/how_do_you_keep_from_burning_out_at_your_job/

Apr 1, 2019 • 43min
Principles in Refactoring
Chapter 2 Principles in Refactoring
A weekly podcast about programming, development, and design through the lens of amazing books, chapter-by-chapter.
Define Refactoring
“If someone says their code is broken for a couple days while they are refactoring =, you can be pretty sure they aren’t refactoring.
Adding Features Vs Refactoring
Why should we refactor?
Code rot - overtime the code decays - rushed or poorly executed changes
Regular refactoring helps keep things in shape
Makes things easier to understand
(Delegating issues in clean codebase vs rough)
Refactoring helps find bugs
Refactoring helps us work faster long term - cleaning your workspace
Over time adding new features is easier
Getting buy in for refactors:
Don’t tell your manager / client
Build it into your estimates
You are being paid for your expertise
be confident in somewhat hiding the implementation. (Depends on your role)
When to refactor:
Prepatory Refactoring
Comprehension refactoring
Long term refactor - Ech small change leaves everything is a still working state, not just “up to date”
In code reviews
When to not refactor:
If the code is working fine and it doesn’t need to be changed
If it works like an API
When it will slow down an essential new feature.
Legacy Code
Refactoring Tools for future episodes?
Writing Ruby Gems
Renovate Bot
Picks
JP: Free Event Tickets
John: Eero wifi router

Mar 25, 2019 • 35min
Refactoring - In Practice
In this episode we dive deep into some specific refactors from Refactoring 's Chapter 1. We talk about renaming things, extracting functions, functions, replacing a temp with query and some other hot tips and tricks you can put into your code today.
This episode walks through specific code examples from Chapter 1 of Martin Fowler's Refactoring...
Some of the refactors
Change Function Declaration
Rename things
Names are hard
A few general categories of things you can name
predicate? - Should only return true / false - Javascript start with is - ruby question mark - so isValidPhone(number)
In Ruby - ! For destructive / dangerous actions - update_recent_activity! - name destructive actions or actions with side effects really well.
Formatting? - use - as - number_as_phone(number) or to to_bmi(user.weight, user.height)
Extract Function
Replace temp w/ query
Extending this example:
Instead of:
accounts = get_accounts(user)
transactions = get_transactions(accounts)
we can just do:
transactions = get_transactions(get_accounts(user))
Replace conditional with polymorphism
Notification.deliver! example
Picks
JP: Thanos JS - https://thanosjs.org/
John: Loom https://www.loom.com/ - and http://www.telestream.net/screenflow/overview.htm

Mar 18, 2019 • 40min
New Book - Refactoring
Welcome to iteration. A weekly podcast about programming, development, and design through the lens of amazing books, chapter-by-chapter.
Refactoring
Improving the Design of Existing Code
by Martin Fowler (with Kent Beck)
Introduction
What’s in the book?
Who’s it for?
What’s refactoring?
Refactoring process:
Identify a pain, smell a smell, we’ll talk more about when to refactor in later episodes.
Separate feature additions from refactors
Refactorings are like diets - a lifestyle vs an intensive
Test coverage first
Small changes continually running tests
End goal: lots of small well-named functions that tells a clear story.
Considerations + Thoughts
Tests let JP in react native move faster
Refactoring lets you get things out of your head and into the code. Do this continuously.
Performance and refactoring
My Pick:
How To Code Well - howtocodewell.net
Dark Net Diaries https://darknetdiaries.com/
Selection - Apple's Design Process

Mar 4, 2019 • 47min
In Between Books
S06E01 - DO IT LIVE!
This week is a more casual episode where we talk about recent struggles findings and some of our favorite parts of our most recent book. Practical Object-Oriented Programming in Ruby
We'll be back episode covering a new book - Refactoring by Martin Fowler
A weekly podcast about programming, development, and design through the lens of amazing books, chapter-by-chapter.
CH2 - Designing Classes with a single responsibility
Chapter 7 - Favorite Takeaways/Examples From POODR
Duck Typing -
Modules -
My Team Came up with:
include Listable
include Lister
Any user type can act as a “Lister” and add things to the list
Any object can be “Listable” or “added to a list”
Recent Lessons - Always have a staging environment
Picks:
https://thispersondoesnotexist.com/

Feb 18, 2019 • 32min
Testing... Testing... 123...
Iteration S05E09
Testing… Testing… 123
Publishing February 18th - Hope everyone had a good Valentine’s Day weekend!
A weekly podcast about programming, development, and design through the lens of amazing books, chapter-by-chapter.
Introduction
Writing changeable code is an art on which practice relies on three different skills. First, you must understand object-oriented design. Poorly designed code is naturally difficult to change.
First, you must understand object-oriented design. A poorly designed code is naturally difficult to change.
Second, you must be skilled at refactoring code.
Finally, the art of writing a changeable code requires the ability to write high-value tests. Tests give you the confidence to refactor constantly.
Reasons to test:
Finding Bugs
Supplying Documentation
Deferring Design Decisions
Supporting Abstractions
Exposing Design Flaws
Knowing What to test:
“Most developers write too many tests” - OR NONE! hahaha
Tests should concentrate on the incoming or outgoing messages that cross an object’s boundaries.
Back to the Kitchen Metaphor - Test that ordering a hamburger, returns a hamburger as expected, not that the kitchen staff turns on the grill or slices tomatoes.
Incoming messages should be tested for the state they return.
Outgoing command messages should be tested to ensure they get sent.
Outgoing query messages should not be tested.
Knowing When to Test
Write tests first, whenever it makes sense to do so
Knowing How to test:
Testing Styles: Test Driven Development (TDD) and Behavior Driven Development (BDD).
Proving the Public Interface
Injecting Dependencies as Roles
Testing Inheritance - Test your base class - then include the module to test each of the responses that are in the base class.
Creating Test Doubles - DiameterDouble - A test double is a stylized instance of a role player that is used exclusively for testing - tend to override the base class in my test helper - I’ve run into silent errors this way.
Testing Private Methods - interface. These private messages are like proverbial trees falling in empty forests; they do not exist, in a perfect world they do not need to be tested - testing them is a code smell.
Testing Ducks - create a preferred test interface - mechanic and a guide can both prepare - you can establish a single interface and simply pass the different objects into it.
Testing Inherited Code
Testing Models + Objects Vs interface - where’s the balance?
Tests are indispensable. Well-designed applications are highly abstract and under constant pressure to evolve; without tests these applications can neither be understood nor safely changed. The best tests are loosely coupled to the underlying code and test everything once and in the proper place. They add value without increasing costs.
Next Episode - Recap of Practical Object-Oriented Design and New book announcement!
Picks:
NOUN PROJECT - https://thenounproject.com/
**Super Smash Bros Ultimate **
Neil Davis - @Nei1dor
Aaron Kelton

Feb 11, 2019 • 42min
Composition Imposition
Combining Objects with Composition
Metz, Sandi. Practical Object-Oriented Design in Ruby
A weekly podcast about programming, development, and design through the lens of amazing books, chapter-by-chapter.
“Combining the qualities of two existing subclasses, something that inheritance cannot readily accommodate.”
We talked about inheritance, then modules, now this builds on top of the idea of modules and pushes it further.
Composing a bicycle of parts...
Bicycle > has A parts
Parts has subclasses of - RoadBikeParts and MountainBikeParts
Making the Parts Object More Like an Array - This part was freaky
Parts Factory
Different Configs within the parts factory > an array of all the keys and attributes - road_config - mountain_config
Using all this to make a recumbent bike:
Once this is all set up you have this incredibly powerful interface of a bicycle composed of parts:
Bicycle.new(
size: 'L',
parts: PartsFactory.build(recumbent_config))
Composition VS Aggregation
A Meal is composed of an appetizer - An appetizer does not survive outside of the meal. When the meal is gone by definition the appetizer is gone. A meal is composed of an appetizer.
A band is an aggregate of musicians - when the band breaks up the musicians don’t die.
“Composition” encompasses both aggregation and composition -
“This distinction between composition and aggregation may have a little practical effect on your code.”
Deciding Between Inheritance and Composition
“Think of it this way: For the cost of arranging objects in a hierarchy, you get message delegation for free.”
When in doubt use Composition over inheritance
“The general rule is that faced with a problem that composition can solve, you should be biased towards doing so. If you cannot explicitly defend inheritance as a better solution, use composition.”
John’s Pick: Book: "It Doesn’t Have To Be Crazy At Work" -> David Heinemeier Hansen and Jason Fried
JP: Kahn Academy - digging into math again
Next Week: Final Chapter - Designing Cost-Effective Tests