1.1 Object-oriented design and the test of time · 1.2 Designing simple object-oriented systems · 1.2.1 Simple code · 1.2.2 Consistent objects · 1.2.3 Proper dependency management · 1.2.4 Good abstractions · 1.2.5 Properly handled external dependencies and infrastructure · 1.2.6 Well modularized · 1.3 Simple design as a day-to-day activity · 1.3.1 Reducing complexity is similar to personal hygiene · 1.3.2 Complexity may be necessary but should not be permanent · 1.3.3 Consistently addressing complexity is cost effective · 1.3.4 High-quality code promotes good practices · 1.3.5 Controlling complexity isn’t as difficult as it seems · 1.3.6 Keeping the design simple is a developer’s responsibility · 1.3.7 Good-enough designs · 1.4 A short dive into the architecture of an information system · 1.5 The example project: PeopleGrow! · 1.6 Exercises · 1.7 Summary
2.1 Make units of code small · 2.1.1 Break complex methods into private methods · 2.1.2 Move a complex unit of code to another class · 2.1.3 When not to divide code into small units · 2.1.4 Get a helicopter view of the refactoring before you do it · 2.1.5 Example: Importing employees · 2.2 Make code readable and documented · 2.2.1 Keep looking for good names · 2.2.2 Document decisions · 2.2.3 Add code comments · 2.2.4 Example: Deciding when to send an update email · 2.3 Move new complexity away from existing classes · 2.3.1 Give the complex business logic a class of its own · 2.3.2 Break down large business flows · 2.3.3 Example: Waiting list for offerings · 2.4 Exercises · 2.5 Summary
3.1 Ensure consistency at all times · 3.1.1 Make the class responsible for its consistency · 3.1.2 Encapsulate entire actions and complex consistency checks · 3.1.3 Example: The Employee entity · 3.2 Design effective data validation mechanisms · 3.2.1 Make preconditions explicit · 3.2.2 Create validation components · 3.2.3 Use nulls carefully or avoid them if you can · 3.2.4 Example: Adding an employee to a training offering · 3.3 Encapsulate state checks · 3.3.1 Tell, don’t ask · 3.3.2 Example: Available spots in an offering · 3.4 Provide only getters and setters that matter · 3.4.1 Getters that don’t change state and don’t reveal too much to clients · 3.4.2 Setters only to attributes that describe the object · 3.4.3 Example: Getters and setters in the Offering class · 3.5 Model aggregates to ensure invariants in clusters of objects · 3.5.1 Don’t break the rules of an aggregate root · 3.5.2 Example: The Offering aggregate · 3.6 Exercises · 3.7 Summary
4.1 Separate high-level and low-level code · 4.1.1 Design stable code · 4.1.2 Interface discovery · 4.1.3 When not to separate the higher level from the lower level · 4.1.4 Example: The messaging job · 4.2 Avoid coupling to details or things you don’t need · 4.2.1 Only require or return classes that you own · 4.2.2 Example: Replacing the HTTP bot with the chat SDK · 4.2.3 Don’t give clients more than they need · 4.2.4 Example: The offering list · 4.3 Break down classes that depend on too many other classes · 4.3.1 Example: Breaking down the MessageSender service · 4.4 Inject dependencies, aka dependency injection · 4.4.1 Avoid static methods for operations that change the state · 4.4.2 Always inject collaborators: Everything else is optional · 4.4.3 Strategies to instantiate the class together with its dependencies · 4.4.4 Example: Dependency injection in MessageSender and collaborators · 4.5 Exercises · 4.6 Summary
5.1 Design abstractions and extension points · 5.1.1 Identifying the need for an abstraction · 5.1.2 Designing an extension point · 5.1.3 Attributes of good abstractions · 5.1.4 Learn from your abstractions · 5.1.5 Learn about abstractions · 5.1.6 Abstractions and coupling · 5.1.7 Example: Giving badges to employees · 5.2 Generalize important business rules · 5.2.1 Separate the concrete data from the generalized business rule · 5.2.2 Example: Generalizing the badge rules · 5.3 Prefer simple abstractions · 5.3.1 Rules of thumb · 5.3.2 Simple is always better · 5.3.3 Enough is enough · 5.3.4 Don’t be afraid of modeling abstractions from day one · 5.3.5 Example: Revisiting the badge example · 5.4 Exercises · 5.5 Summary
6.1 Separate infrastructure from the domain code · 6.1.1 Do you need an interface? · 6.1.2 Hide details from the code, not from the developers · 6.1.3 Changing the infrastructure someday: Myth or reality? · 6.1.4 Example: Database access and the message bot · 6.2 Use the infrastructure fully · 6.2.1 Do your best not to break your design · 6.2.2 Example: Cancelling an enrollment · 6.3 Only depend on things you own · 6.3.1 Don’t fight your frameworks · 6.3.2 Be aware of indirect leakage · 6.3.3 Example: Message bot · 6.4 Encapsulate low-level infrastructure errors into high-level domain errors · 6.4.1 Example: Handling exceptions in SDKBot · 6.5 Exercises · 6.6 Summary
7.1 Build deep modules · 7.1.1 Find ways to reduce the effects of changes · 7.1.2 Keep refining your domain boundaries · 7.1.3 Keep related things close · 7.1.4 Fight accidental coupling, or document it when you can’t · 7.2 Design clear interfaces · 7.2.1 Keep the module’s interface simple · 7.2.2 Backward-compatible modules · 7.2.3 Provide clean extension points · 7.2.4 Code as if your module will be used by someone with different needs · 7.2.5 Modules should have clear ownership and engagement rules · 7.3 No intimacy between modules · 7.3.1 Make modules and clients responsible for the lack of intimacy · 7.3.2 Don’t depend on internal classes · 7.3.3 Monitor the web of dependencies · 7.3.4 Monoliths or microservices? · 7.3.5 Consider events as a way to decouple modules · 7.3.6 Example: The notification system · 7.4 Exercises · 7.5 Summary
8.1 Be pragmatic and go only as far as you must · 8.2 Refactor aggressively but in small steps · 8.3 Accept that your code won’t ever be perfect · 8.4 Consider redesigns · 8.5 You owe this to junior developers · 8.6 References · 8.7 Exercises · 8.8 Summary
contractAn API is a defined interface through which software systems invoke functionality or access data from another system.
moduleA module is a separately organized application unit containing its own domain model and related components.
abstractionAn abstraction is a simplified model that exposes relevant behavior or structure while hiding unnecessary implementation details.
infrastructureInfrastructure is the set of external systems, integrations, and technical resources outside the backend's direct control.
encapsulationInformation hiding is the design technique of concealing likely-to-change implementation details behind a stable interface or abstraction.
business logicBusiness logic is the set of rules and behavior that implement an application's problem-domain requirements.
couplingCoupling is the degree to which one software component depends on another component.
consistencyConsistency is the property of related software or domain data satisfying required rules and remaining mutually coherent.
extension pointAn extension point is a deliberately designed location or contract where new behavior can be added with limited changes to existing code.
serviceA service is a component that encapsulates business rules involving one or more domain entities.
dependencyA dependency is a relationship in which one software component relies on another component whose changes may affect it.
small methodA small code unit is a method or class deliberately limited in size and scope to reduce implementation complexity.
implementation detailAn implementation detail is an internal choice about how a software component performs its behavior that clients do not need to know.
wrapperA wrapper class is a class that groups or adapts other components behind a simpler interface.
backward compatibilityBackward compatibility is the ability of a changed software component or interface to continue supporting existing clients and usage patterns.
dependency managementDependency management is the discipline of controlling relationships among software components so that changes remain localized and maintainability is preserved.
application serviceAn application service coordinates application tasks and interactions between components without containing the domain's business rules.
dependency injectionA dependency injection framework is a software framework that constructs objects and supplies their declared dependencies according to configuration or conventions.
aggregate rootAn aggregate root is the designated domain object through which an aggregate's members and consistency rules are accessed and modified.
refactoringRefactoring is the disciplined transformation of existing software structure without changing its externally observable behavior.
business ruleA business rule is a domain-specific condition or policy that determines how an application should make decisions or perform business operations.
aggregateAn aggregate is a cluster of related domain objects treated as a consistency boundary and accessed through a designated root.
commentA code comment is explanatory natural-language text embedded in source code to convey rationale, behavior, caveats, or other information not expressed by the code itself.
preconditionA precondition is a requirement that must hold before an operation can execute correctly.
validationA validation mechanism checks requested values or state changes against validity constraints.
IT systemAn information system is a software system that organizes and processes information for a business or other domain.
databaseA database is a system that persistently stores and retrieves structured application information.
repository patternA repository is a component that encapsulates the logic for retrieving and persisting domain information.
cohesionCohesion is the degree to which a software unit's responsibilities and elements belong together and support a focused purpose.
eventual consistencyEventual consistency is a consistency model in which related data may temporarily disagree but converges to a consistent state after updates propagate.
flexibilityThe capacity of a software design to accommodate variation or alternative implementations without requiring extensive structural changes.
entityAn entity is a domain object that represents a business concept through identifying attributes and behavior that maintains those attributes consistently.
classA programming-language construct that defines the structure and behavior of objects and can be extended or instantiated according to the language's object model.
These guides are generated from the text of Manning books by Manning's knowledge graph and link to the sections they draw on. The full books are available on liveBook and at manning.com.