Foreword | p. xvii |
Preface | p. xxi |
Acknowledgments | p. xxv |
About the Author | p. xxvii |
What Is Software Engineering? | p. 1 |
Introduction | p. 3 |
Engineering-The Practical Application of Science | p. 3 |
What Is Software Engineering? | p. 4 |
Reclaiming "Software Engineering" | p. 5 |
How to Make Progress | p. 6 |
The Birth of Software Engineering | p. 7 |
Shifting the Paradigm | p. 8 |
Summary | p. 9 |
What Is Engineering? | p. 11 |
Production Is Not Our Problem | p. 11 |
Design Engineering, Not Production Engineering | p. 12 |
A Working Definition of Engineering | p. 17 |
Engineering != Code | p. 17 |
Why Does Engineering Matter? | p. 19 |
The Limits of "Craft" | p. 19 |
Precision and Scalability | p. 20 |
Managing Complexity | p. 21 |
Repeatability and Accuracy of Measurement | p. 22 |
Engineering, Creativity, and Craft | p. 24 |
Why What We Do Is Not Software Engineering | p. 25 |
Trade-Offs | p. 26 |
The Illusion of Progress | p. 26 |
The Journey from Craft to Engineering | p. 27 |
Craft Is Not Enough | p. 28 |
Time for a Rethink? | p. 28 |
Summary | p. 30 |
Fundamentals of an Engineering Approach | p. 31 |
An Industry of Change? | p. 31 |
The Importance of Measurement | p. 32 |
Applying Stability and Throughput | p. 34 |
The Foundations of a Software Engineering Discipline | p. 36 |
Experts at Learning | p. 36 |
Experts at Managing Complexity | p. 37 |
Summary | p. 38 |
Optimize for Learning | p. 41 |
Working Iteratively | p. 43 |
Practical Advantages of Working Iteratively | p. 45 |
Iteration as a Defensive Design Strategy | p. 46 |
The Lure of the Plan | p. 48 |
Practicalities of Working Iteratively | p. 54 |
Summary | p. 55 |
Feedback | p. 57 |
A Practical Example of the Importance of Feedback | p. 58 |
Feedback in Coding | p. 60 |
Feedback in Integration | p. 61 |
Feedback in Design | p. 63 |
Feedback in Architecture | p. 65 |
Prefer Early Feedback | p. 67 |
Feedback in Product Design | p. 68 |
Feedback in Organization and Culture | p. 68 |
Summary | p. 70 |
Incrementalism | p. 71 |
Importance of Modularity | p. 72 |
Organizational Incrementalism | p. 73 |
Tools of Incrementalism | p. 74 |
Limiting the Impact of Change | p. 76 |
Incremental Design | p. 77 |
Summary | p. 79 |
Empiricism | p. 81 |
Grounded in Reality | p. 82 |
Separating Empirical from Experimental | p. 82 |
"I Know That Bug!" | p. 82 |
Avoiding Self-Deception | p. 84 |
Inventing a Reality to Suit Our Argument | p. 85 |
Guided by Reality | p. 88 |
Summary | p. 89 |
Being Experimental | p. 91 |
What Does "Being Experimental" Mean? | p. 92 |
Feedback | p. 93 |
Hypothesis | p. 94 |
Measurement | p. 95 |
Controlling the Variables | p. 96 |
Automated Testing as Experiments | p. 97 |
Putting the Experimental Results of Testing into Context | p. 98 |
Scope of an Experiment | p. 100 |
Summary | p. 100 |
Optimize for Managing Complexity | p. 103 |
Modularity | p. 105 |
Hallmarks of Modularity | p. 106 |
Undervaluing the Importance of Good Design | p. 107 |
The Importance of Testability | p. 108 |
Designing for Testability Improves Modularity | p. 109 |
Services and Modularity | p. 115 |
Deployability and Modularity | p. 116 |
Modularity at Different Scales | p. 118 |
Modularity in Human Systems | p. 118 |
Summary | p. 120 |
Cohesion | p. 121 |
Modularity and Cohesion: Fundamentals of Design | p. 121 |
A Basic Reduction in Cohesion | p. 122 |
Context Matters | p. 125 |
High-Performance Software | p. 128 |
Link to Coupling | p. 129 |
Driving High Cohesion with TDD | p. 129 |
How to Achieve Cohesive Software | p. 130 |
Costs of Poor Cohesion | p. 132 |
Cohesion in Human Systems | p. 133 |
Summary | p. 133 |
Separation of Concerns | p. 135 |
Dependency Injection | p. 139 |
Separating Essential and Accidental Complexity | p. 139 |
Importance of DDD | p. 142 |
Testability | p. 144 |
Ports & Adapters | p. 145 |
When to Adopt Ports & Adapters | p. 147 |
What Is an API? | p. 148 |
Using TDD to Drive Separation of Concerns | p. 149 |
Summary | p. 150 |
Information Hiding and Abstraction | p. 151 |
Abstraction or Information Hiding | p. 151 |
What Causes "Big Balls of Mud"? | p. 152 |
Organizational and Cultural Problems | p. 152 |
Technical Problems and Problems of Design | p. 154 |
Fear of Over-Engineering | p. 157 |
Improving Abstraction Through Testing | p. 159 |
Power of Abstraction | p. 160 |
Leaky Abstractions | p. 162 |
Picking Appropriate Abstractions | p. 163 |
Abstractions from the Problem Domain | p. 165 |
Abstract Accidental Complexity | p. 166 |
Isolate Third-Party Systems and Code | p. 168 |
Always Prefer to Hide Information | p. 169 |
Summary | p. 170 |
Managing Coupling | p. 171 |
Cost of Coupling | p. 171 |
Scaling Up | p. 172 |
Microservices | p. 173 |
Decoupling May Mean More Code | p. 175 |
Loose Coupling Isn't the Only Kind That Matters | p. 176 |
Prefer Loose Coupling | p. 177 |
How Does This Differ from Separation of Concerns? | p. 178 |
DRY Is Too Simplistic | p. 179 |
Async as a Tool for Loose Coupling | p. 180 |
Designing for Loose Coupling | p. 182 |
Loose Coupling in Human Systems | p. 182 |
Summary | p. 184 |
Tools to Support Engineering in Software | p. 185 |
The Tools of an Engineering Discipline | p. 187 |
What Is Software Development? | p. 188 |
Testability as a Tool | p. 189 |
Measurement Points | p. 192 |
Problems with Achieving Testability | p. 193 |
How to Improve Testability | p. 196 |
Deployability | p. 197 |
Speed | p. 199 |
Controlling the Variables | p. 200 |
Continuous Delivery | p. 201 |
General Tools to Support Engineering | p. 202 |
Summary | p. 203 |
The Modem Software Engineer | p. 205 |
Engineering as a Human Process | p. 207 |
Digitally Disruptive Organizations | p. 207 |
Outcomes vs. Mechanisms | p. 210 |
Durable and Generally Applicable | p. 211 |
Foundations of an Engineering Discipline | p. 214 |
Summary | p. 215 |
Index | p. 217 |
Table of Contents provided by Ingram. All Rights Reserved. |