Practical API Design: Confessions of a Java Framework Architect
Contents at a Glance
Contents
About the Author
Acknowledgments
Prologue: Yet Another Design Book?
API Design Is Different
Who Should Read This Book?
Is This Book Useful Only for Java?
Learning to Write APIs
Is This Book Really a Notebook?
Theory and Justification
The Art of Building Modern Software
Rationalism, Empiricism, and Cluelessness
Evolution of Software So Far
Gigantic Building Blocks
Beauty, Truth, and Elegance
More Cluelessness!
The Motivation to Create an API
Distributed Development
Modularizing Applications
Nonlinear Versioning
It’s All About Communication
Empirical Programming
The First Version Is Always Easy
Determining What Makes a Good API
Method and Field Signatures
Files and Their Content
Environment Variables and Command-Line Options
Text Messages As APIs
Protocols
Behavior
I18N Support and L10N Messages
Wide Definition of APIs
How to Check the Quality of an API
Comprehensibility
Consistency
Discoverability
Simple Tasks Should Be Easy
Preservation of Investment
Ever-Changing Targets
The First Version Is Never Perfect
Backward Compatibility
Source Compatibility
Binary Compatibility
Functional Compatibility—the Amoeba Effect
The Importance of Being Use Case Oriented
API Reviews
Life Cycle of an API
Incremental Improvements
Do Not Expose More Than You Want
A Method Is Better Than a Field
A Factory Is Better Than a Constructor
Make Everything Final
Do Not Put Setters Where They Do Not Belong
Allow Access Only from Friend Code
Give the Creator of an Object More Rights
Do Not Expose Deep Hierarchies
Code Against Interfaces, Not Implementations
Removing a Method or a Field
Removing or Adding a Class or an Interface
Inserting an Interface or a Class into an Existing Hierarchy
Adding a Method or a Field
Comparing Java Interfaces and Classes
In Weakness Lies Strength
A Method Addition Lover’s Heaven
Are Abstract Classes Useful?
Getting Ready for Growing Parameters
Interfaces vs. Classes
Use Modular Architecture
Types of Modular Design
Intercomponent Lookup and Communication
Writing an Extension Point
The Need for Cyclic Dependencies
Lookup Is Everywhere
Overuse of Lookup
Separate APIs for Clients and Providers
Expressing API/SPI in C and Java
API Evolution Is Different from SPI Evolution
Writer Evolution Between Java 1.4 and 1.5
Split Your API Reasonably
Keep Testability in Mind
API and Testing
The Fade of the Specification
Good Tools Make Any API Easier
Test Compatibility Kit
Cooperating with Other APIs
Beware of Using Other APIs
Leaking Abstractions
Enforcing Consistency of APIs
Delegation and Composition
Prevent Misuses of the API
Do Not Overuse the JavaBeans Listener Pattern
Runtime Aspects of APIs
Fixing Odyssey
Reliability and Cluelessness
Synchronization and Deadlocks
Document the Threading Model
Pitfalls of Java Monitors
Deadlock Conditions
Deadlock Test
Testing Race Conditions
Analyzing Random Failures
Advanced Usage of Logging
Execution Flow Control Using Logging
Preparing for Reentrant Calls
Memory Management
Declarative Programming
Make Objects Immutable
Immutable Behavior
Compatibility of Documents
Extreme Advice Considered Harmful
An API Must Be Beautiful
An API Has to Be Correct
An API Has to Be Simple
An API Has to Have Good Performance
An API Must Be 100 Percent Compatible
An API Needs to Be Symmetrical
Paradoxes of API Design
API Doublethink
The Invisible Job
Overcoming the Fear of Committing to a Stable API
Minimizing Maintenance Cost
Evolving the API Universe
Resuscitating Broken Libraries
Conscious vs. Unconscious Upgrades
Alternative Behavior
Bridges and the Coexistence of Similar APIs
Teamwork
Organizing Reviews Before Committing Code
Convincing Developers to Document Their API
Big Brother Never Sleeps
Accepting API Patches
Using Games to Improve API Design Skills
Overview
Day 1
Problem of Nonpublic API Classes
The Immutability Problem
The Problem of the Missing Implementation
The Problem of Possibly Incorrect Results
Solutions for Day 1
Day 2
I Want to Fix My Mistakes Problem
Solutions for Day 2
Day 3: Judgment Day
Conclusions
What Was Wrong with subclassingsolution and stackbasedsolution?
What Was Wrong with inputandoperation?
What Was Wrong with alwayscreatenewcircuit and welltestedsolution?
What Was Wrong with elementbasedsolution?
Play Too!
Extensible Visitor Pattern Case Study
Abstract Class
Preparing for Evolution
Default Traversal
Clean Definition of a Version
Nonmonotonic Evolution
Data Structure Using Interfaces
Client and Provider Visitors
Triple Dispatch
A Happy End for Visitors
Syntactic Sugar
End-of-Life Procedures
The Importance of a Specification Version
The Importance of Module Dependencies
Should Removed Pieces Lie Around Forever?
Splitting Monolithic APIs
The Future
Principia Informatica
Cluelessness Is Here to Stay
API Design Methodology
Languages Ready for Evolution
The Role of Education
Share!
Bibliography
Index