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.
php/*
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.
Copyright: © ¯_(ツ)_/¯
To do refactoring properly, I need a solid suite of tests to spot my inevitable mistakes.
If you want to refactor, you have to write tests
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.
Whenever I have a collection of something, ... I like to see what happens when it's empty
When you get a bug report, start by writing a unit test that exposes the bug
A weekly podcast about programming, development, and design through the lens of amazing books, chapter-by-chapter.
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;
}
}
class Organization doesn't need to know / care which is stored and which is calculatedclass 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/sliceorders.filter(0 => "high" === o.priority || "rush" === o.priority)
becomes ⬇️
orders.filter(o => o.priority.higherThan(new Priority("normal")));
- 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
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
}
};
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.
editor choice
S06E04 - Iteration
A weekly podcast about development and design through the lens of amazing books, chapter-by-chapter
Refactors Before -
Picks:
A weekly podcast about programming, development, and design through the lens of amazing books, chapter-by-chapter.
Why should we refactor?
Getting buy in for refactors:
When to refactor:
When to not refactor:
Legacy Code
Refactoring Tools for future episodes?
Picks
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...
Change Function Declaration
Extract Function
Replace temp w/ query
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
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
Refactoring process:
Considerations + Thoughts
My Pick:
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
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/
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
Reasons to test:
Knowing What to test:
Knowing When to Test
Knowing How to test:
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 **
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