Skip to content

Instantly share code, notes, and snippets.

@trikitrok
trikitrok / Working Effectively with Legacy Code.md
Created April 16, 2024 19:58 — forked from jeremy-w/Working Effectively with Legacy Code.md
Notes on Michael Feathers' *Working Effectively with Legacy Code*.

Working Effectively with Legacy Code

Notes by Jeremy W. Sherman, October 2013, based on:

Feathers, Michael. Working Effectively with Legacy Code. Sixth printing, July 2007.

Foreword:

  • Software systems degrade into a mess.
  • Requirements ALWAYS change.
  • Your goal as a software developer: Create designs that tolerate change.
@trikitrok
trikitrok / Robert Annett - Modern Legacy Systems.md
Created April 16, 2024 19:58 — forked from jeremy-w/Robert Annett - Modern Legacy Systems.md
Notes taken while listening to Robert Annett's talk on Modern Legacy Systems at QCon London 2012.
@trikitrok
trikitrok / Working Effectively with Legacy Code, Block 2.md
Created April 16, 2024 19:55 — forked from jeremy-w/Working Effectively with Legacy Code, Block 2.md
Notes on chapters 11, 15, 17, and 20 of Michael Feathers' *Working Effectively with Legacy Code.* Read as part of the BNR Book Club, October 2013.

Working Effectively with Legacy Code

Michael C. Feathers

Notes by Jeremy W. Sherman, 14 Oct 2013.

Chapter 11: I need to make a change. What methods should I test?

Use effect sketches to figure out where to target your characterization tests prior to making changes. Big fan-in means a big bang for your test-writing buck.

  • Prior to changing, write characterization tests to pin down existing behavior.
  • Characterization test: A test that characterizes the actual behavior of a piece of code (186).
// Adapted from Code Smell: Null Check, Joe Eames https://medium.com/thinkster-io/code-smell-null-check-a0c4851fafbf
const DEFAULT_DISCOUNT: number = 1.0;
class DiscountCalculator {
private customerRepository: CustomerRepository;
constructor(customerRepository: CustomerRepository) {
this.customerRepository = customerRepository;
}
// Adapted from Code Smell: Null Check, Joe Eames https://medium.com/thinkster-io/code-smell-null-check-a0c4851fafbf
const DEFAULT_DISCOUNT = 1.0;
class DiscountCalculator {
constructor(customerRepository) {
this.customerRepository = customerRepository;
}
// ...

Sixth iteration - New drink makers!

We move to new markets that use different drink makers.

In this iteration, your task is to make our CoffeeMachine work with two new models of drink maker:

  • DrinkMaker-1000
  • DrinkMaker-3000

Use cases

// From Fixing Object oriented abusers, Manh Phan https://ducmanhphan.github.io/2020-01-24-Fixing-object-oriented-abusers/
class CheckoutHandlder {
// ...
convertToCurrency(price, currencyTo) {
if (currencyTo === "EUR") {
return price * 0.9;
} else if (currencyTo === "CAD") {
return price * 1.35;
} else {
// From Rachel M. Carmena's https://github.com/rachelcarmena/code-smells
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
class CoolStack extends Array {
push(...items) {
return super.push(...items);
}
public pop() {
return super.pop();
// From Code Smells – Part II, Ana Nogal https://www.ananogal.com/blog/code-smells-part-two/
class EmployeeType {
static Worker = new EmployeeType("Worker")
static Supervisor = new EmployeeType("Supervisor")
static Manager = new EmployeeType("Manager")
constructor(type) {
this.type = type
}
// As a direct chain of calls
class FlightBooking {
constructor(plane) {
this.plane = plane;
}
// ...
isSeatAvailable(rowNumber, seat) {
return this.plane.getRows()[rowNumber - 1].isAvailable(seat);
}