Book Description
Object Design Style Guide presents dozens of professional techniques for writing OO code. In it, veteran developer Matthias Noback lays out design rules for constructing objects, defining methods, changing and exposing state, and much more. All examples use instantly familiar pseudocode, so you can follow along in the language you prefer. You’ll go case by case as you explore important scenarios and challenges for object design and then walk through a simple web application that demonstrates how different types of objects can work together effectively.
Table of Contents
- Copyright
- Dedication
- Brief Table of Contents
- Table of Contents
- Foreword
- Preface
- Acknowledgments
- About this Book
- Who should read this book
- How this book is organized: A roadmap
- About the code
- liveBook discussion forum
- About the Author
- About the Cover Illustration
- Chapter 1. Programming with objects: A primer
- 1.1. Classes and objects
- 1.2. State
- 1.3. Behavior
- 1.4. Dependencies
- 1.5. Inheritance
- 1.6. Polymorphism
- 1.7. Composition
- 1.8. Class organization
- 1.9. Return statements and exceptions
- 1.10. Unit testing
- 1.11. Dynamic arrays
- Summary
- Chapter 2. Creating services
- 2.1. Two types of objects
- 2.2. Inject dependencies and configuration values as constructor arguments
- 2.3. Inject what you need, not where you can get it from
- 2.4. All constructor arguments should be required
- 2.5. Only use constructor injection
- 2.6. There’s no such thing as an optional dependency
- 2.7. Make all dependencies explicit
- 2.8. Task-relevant data should be passed as method arguments instead o- of constructor arguments
- 2.9. Don’t allow the behavior of a service to change after it has been instantiated
- 2.10. Do nothing inside a constructor, only assign properties
- 2.11. Throw an exception when an argument is invalid
- 2.12. Define services as an immutable object graph with only a few entry points
- Summary
- Answers to the exercises
- Chapter 3. Creating other objects
- 3.1. Require the minimum amount of data needed 3.1 to behave consistently
- 3.2. Require data that is meaningful
- 3.3. Don’t use custom exception classes for invalid argument exceptions
- 3.4. Test for specific invalid argument exceptions by analyzing the ex- xception’s message
- 3.5. Extract new objects to prevent domain invariants from being verif- fied in multiple places
- 3.6. Extract new objects to represent composite values
- 3.7. Use assertions to validate constructor arguments
- 3.8. Don’t inject dependencies; optionally pass them as method arguments
- 3.9. Use named constructors
- 3.10. Don’t use property fillers
- 3.11. Don’t put anything more into an object than it needs
- 3.12. Don’t test constructors
- 3.13. The exception to the rule: Data transfer objects
- Summary
- Answers to the exercises
- Chapter 4. Manipulating objects
- 4.1. Entities: Identifiable objects that track changes and record events
- 4.2. Value objects: Replaceable, anonymous, and immutable values
- 4.3. Data transfer objects: Simple objects with fewer design rules
- 4.4. Prefer immutable objects
- 4.5. A modifier on an immutable object should return a modified copy
- 4.6. On a mutable object, modifier methods should be command methods
- 4.7. On an immutable object, modifier methods should have declarative names
- 4.8. Compare whole objects
- 4.9. When comparing immutable objects, assert equality, not sameness
- 4.10. Calling a modifier method should always result in a valid object
- 4.11. A modifier method should verify that the requested state change is valid
- 4.12. Use internally recorded events to verify changes on mutable objects
- 4.13. Don’t implement fluent interfaces on mutable objects
- Summary
- Answers to the exercises
- Chapter 5. Using objects
- 5.1. A template for implementing methods
- 5.2. Some rules for exceptions
- Summary
- Answers to the exercises
- Chapter 6. Retrieving information
- 6.1. Use query methods for information retrieval
- 6.2. Query methods should have single-type return values
- 6.3. Avoid query methods that expose internal state
- 6.4. Define specific methods and return types for the queries you want to make
- 6.5. Define an abstraction for queries that cross system boundaries
- 6.6. Use stubs for test doubles with query methods
- 6.7. Query methods should use other query methods, not command methods
- Summary
- Answers to the exercises
- Chapter 7. Performing tasks
- 7.1. Use command methods with a name in the imperative form
- 7.2. Limit the scope of a command method, and use events to perform secondary tasks
- 7.3. Make services immutable from the outside as well as on the inside
- 7.4. When something goes wrong, throw an exception
- 7.5. Use queries to collect information and commands to take the next steps
- 7.6. Define abstractions for commands that cross system boundaries
- 7.7. Only verify calls to command methods with a mock
- Summary
- Answers to the exercises
- Chapter 8. Dividing responsibilities
- 8.1. Separate write models from read models
- 8.2. Create read models that are specific for their use cases
- 8.3. Create read models directly from their data source
- 8.4. Build read models from domain events
- Summary
- Answers to the exercises
- Chapter 9. Changing the behavior of services
- 9.1. Introduce constructor arguments to make behavior configurable
- 9.2. Introduce constructor arguments to make behavior replaceable
- 9.3. Compose abstractions to achieve more complicated behavior
- 9.4. Decorate existing behavior
- 9.5. Use notification objects or event listeners for additional behavior
- 9.6. Don’t use inheritance to change an object’s behavior
- 9.7. Mark classes as final by default
- 9.8. Mark methods and properties private by default
- Summary
- Answers to the exercises
- Chapter 10. A field guide to objects
- 10.1. Controllers
- 10.2. Application services
- 10.3. Write model repositories
- 10.4. Entities
- 10.5. Value objects
- 10.6. Event listeners
- 10.7. Read models and read model repositories
- 10.8. Abstractions, concretions, layers, and dependencies
- Summary
- Chapter 11. Epilogue
- 11.1. Architectural patterns
- 11.2. Testing
- 11.3. Domain-driven design
- 11.4. Conclusion
- Appendix: Coding standard for the code samples
- Style guide cheat sheet
- Index
- List of Figures
- List of Tables
- List of Listings