Five lines of code table of contents Page
Five Lines of Code Table of Contents
Return to Five Lines of Code, Refactoring, Legacy code, Refactoring bibliography, TypeScript bibliography, TypeScript, TypeScript DevOps, Web development bibliography, Software engineering bibliography
" (5LoC 2021)
brief contents
1 Refactoring refactoring
2 Looking under the hood of refactoring
Part 1. Learn by refactoring a computer game
3 Shatter long functions
4 Make type codes work
5 Fuse similar code together
6 Defend the data
Part 2. Taking what you have learned into the real world
7 Collaborate with the compiler
8 Stay away from comments
9 Love deleting code
10 Never be afraid to add code
11 Follow the structure in the code
12 Avoid optimizations and generality
13 Make bad code look bad
14 Wrapping up
Appendix. Installing the tools for part 1
contents
front matter
foreword
preface
acknowledgments
about the author
about the cover illustration
1 Refactoring refactoring
1.1 What is refactoring?
1.2 Skills: What to refactor?
An example code smell
An example rule
1.3 Culture: When to refactor?
Refactoring in a legacy system]]
When should you not refactor?
1.4 Tools: How to refactor (safely)
1.5 Tools you need to get started
Programming language: TypeScript
Editor: Visual Studio Code
Version control: Git
1.6 Overarching example: A 2D puzzle game
Practice makes perfect: A second codebase
1.7 A note on real-world software
2 Looking under the hood of refactoring
2.1 Improving readability and maintainability
Making code better
Maintaining code . . . without changing what it does
2.2 Gaining speed, flexibility, and stability
Favoring composition over inheritance
Changing code by addition rather than modification
2.3 Refactoring and your daily work
Refactoring as a method for learning
2.4 Defining the “domain” in a software context
Part 1. Learn by refactoring a computer game
3 Shatter long functions
3.1 Establishing our first rule: Why five lines?
Rule: Five lines
3.2 Introducing a refactoring pattern to break up functions
Refactoring pattern: Extract method
3.3 Breaking up functions to balancing abstraction
Rule: Either call or pass
Applying the rule
3.4 Properties of a good function name
3.5 Breaking up functions that are doing too much
Rule: if only at the start
Applying the rule
4 Make type codes work
4.1 Refactoring a simple if statement
Rule: Never use if with else
Applying the rule
Refactoring pattern: Replace type code with classes
Pushing code into classes
Refactoring pattern: Push code into classes
Inlining a superfluous method
Refactoring pattern: Inline method
4.2 Refactoring a large if statement
Removing generality
Refactoring pattern: Specialize method
The only switch allowed
Rule: Never use switch
Eliminating the if
4.3 Addressing code duplication
Couldn’t we use an abstract class instead of the interface?
Rule: Only inherit from interfaces
What is up with all this code duplication?
4.4 Refactoring a pair of complex if statements
4.5 Removing dead code
Refactoring pattern: Try delete then compile
5 Fuse similar code together
5.1 Unifying similar classes
Refactoring pattern: Unify similar classes
5.2 Unifying simple conditions
Refactoring pattern: Combine ifs
5.3 Unifying complex conditions
Using arithmetic rules for conditions
Rule: Use pure conditions
Applying condition arithmetic
5.4 Unifying code across classes
Introducing UML class diagrams to depict class relations
Refactoring pattern: Introduce strategy pattern
Rule: No interface with only one implementation
Refactoring pattern: Extract interface from implementation
5.5 Unifying similar functions
5.6 Unifying similar code
6 Defend the data
6.1 Encapsulating without getters
Rule: Do not use getters or setters
Applying the rule
Refactoring pattern: Eliminate getter or setter
Eliminating the final getter
6.2 Encapsulating simple data
Rule: Never have common affixes
Applying the rule
Refactoring pattern: Encapsulate data
6.3 Encapsulating complex data
6.4 Eliminating a sequence invariant
Refactoring pattern: Enforce sequence
6.5 Eliminating enums another way
Enumeration through private constructors
Remapping numbers to classes
Part 2. Taking what you have learned into the real world
7 Collaborate with the compiler
7.1 Getting to know the compiler
Weakness: The halting problem limits compile-[[time knowledge
Strength: Reachability ensures that methods return
Strength: Definite assignment prevents accessing un[[initialized variable]]s
Strength: Access control helps encapsulate data
Strength: Type checking proves properties
Weakness: Dereferencing null crashes our application
Weakness: Arithmetic errors cause overflows or crashes
Weakness: Out-of-bounds errors crash our application
Weakness: Infinite [[loops stall our application
Weakness: Deadlocks and race conditions cause unintended behavior
7.2 Using the compiler
Making the compiler work
Don’t fight the compiler
7.3 Trusting the compiler
Teach the compiler invariants
Pay attention to warnings
7.4 Trusting the compiler exclusively
8 Stay away from comments
8.1 Deleting outdated comments
8.2 Deleting commented-out code
8.3 Deleting trivial comments
8.4 Transforming comments into method names
Using comments for planning
8.5 Keeping invariant-documenting comments
Invariants in the process
9 Love deleting code
9.1 Deleting code may be the next frontier
9.2 Deleting code to get rid of incidental complexity
Technical ignorance from inexperience
Technical waste from time pressure
Technical debt]] from circumstances
Technical drag from growing
9.3 Categorizing code based on intimacy
9.4 Deleting code in a legacy system]]
Using the strangler fig pattern to get insight
Using the strangler fig pattern to improve the code
9.5 Deleting code from a frozen project
Making the desired outcome the default
Minimizing waste with spike and stabilize
9.6 Deleting branches in version control
Minimizing waste by enforcing a branch limit
9.7 Deleting code documentation
Algorithm to determine how to codify knowledge
9.8 Deleting testing [[code
Deleting optimistic tests
Deleting pessimistic tests
Fixing or deleting flaky tests
Refactoring the code to get rid of complicated tests
Specializing tests to speed them up
9.9 Deleting configuration code
Scoping configuration in time
9.10 Deleting code to get rid of libraries
Limiting our reliance on external libraries
9.11 Deleting code from working features
10 Never be afraid to add code
10.1 Accepting uncertainty: Enter the danger
10.2 Using spikes to overcome the fear of building the wrong thing
10.3 Overcoming the fear of waste or risk with a fixed ratio
10.4 Overcoming the fear of imperfection by embracing gradual improvement
10.5 How copy and paste effects change velocity
10.6 Modification by addition through extensibility
10.7 Modification by addition enables backward compatibility]]
10.8 Modification by addition through feature toggles
10.9 Modification by addition through branch by abstraction
11 Follow the structure in the code
11.1 Categorizing structure based on scoped and origin
11.2 Three ways that code mirrors behavior
Expressing behavior in the control flow
Expressing behavior in the structure of the data
Expressing behavior in the data
11.3 Adding code to expose structure
11.4 Observing instead of predicting, and using empirical techniques
11.5 Gaining safety without understanding the code
Gaining safety through testing
Gaining safety through mastery
Gaining safety through tool assistance
Gaining safety through formal verification
Gaining safety through fault tolerance
11.6 Identifying unexploited structures
Exploiting]] whitespace with extraction and encapsulation
Exploiting]] duplication with unification
Exploiting]] common affixes with encapsulation
Exploiting]] the runtime type with dynamic dispatch
12 Avoid optimizations and generality
12.1 Striving for simplicity
12.2 When and how to generalize
Building minimally to avoid generality
Unifying things of similar stability
Eliminating unnecessary generality
12.3 When and how to optimize
Refactoring before optimizing
Optimizing according to the theory of constraints
Guiding optimization with metrics
Choosing good algorithms and data structures
Using caching
Isolating optimized code
13 Make bad code look bad
13.1 Signaling process issues with bad code
13.2 Segregating into pristine and legacy code
The broken window theory
13.3 Approaches to defining bad code
The rules in this book: Simple and concrete
Code smells: Complete and abstract
Cyclomatic complexity: Algorithmic (objective)
Cognitive complexity: Algorithmic (subjective)
13.4 Rules for safely vandalizing code
13.5 Methods for safely vandalizing code
Using enums
Using ints and strings as type codes
Putting magic numbers in the code
Adding comments to the code
Putting whitespace in the code
Grouping things based on naming
Adding context to names
Creating long methods
Giving methods many parameters
Using getters and setters
14 Wrapping up
14.1 Reflecting]] on the journey of this book
Introduction: Motivation
Part 1: Making it concrete
Part 2: Widening the horizon
14.1 Exploring the underlying philosophy
Searching for ever-smaller steps
Searching for the underlying structure
Using the rules for collaboration
Prioritizing the team over individuals
Prioritize simplicity over completeness
Using objects or higher-order functions
14.1 Where to go from here?
Micro-architecture route
Macro-architecture route
Software quality route
Appendix. Installing the tools for part 1
Five Lines of Code Index
" (5LoC 2021)
Fair Use Sources
Fair Use Sources:
* B09H7RKPR4 (5LoC 2021)
{{navbar_refactoring}}
{{navbar_footer}}