
Object-Oriented System Design Principles
Description
Book Introduction
Let's start with this book on object-oriented system design!
Easy to understand concepts through simple examples, deepen your understanding with practical code!
Object orientation is a means designed to deal with complexity rationally.
Designing object-oriented systems properly requires a lot of experience and training, and there are countless thick books on the subject.
But ultimately, object-oriented design is about asking questions about the systems that operate through objects.
We need to ask ourselves how to reduce complexity, keep code units small, maintain consistency in object state, properly control dependencies, reduce the cognitive load on developers through appropriate abstractions, while increasing the scalability of the system, and increase cohesion and decrease coupling through modularization.
To understand the meaning of these questions and how to apply them to object systems, I think it is better to expand your understanding by looking at practical code through simple examples rather than complex theories.
This book is just that kind of book.
It presents several tips for good object-oriented design, provides easy-to-understand code examples for each concept, and tells you what to do and what not to do when developing object-oriented systems.
Developers who want to learn object-oriented design can easily grasp the concepts through examples, and developers who are already familiar with object-oriented design can better understand the concepts of object-oriented design by comparing the advice in this book with their own experiences.
(From the translator's note)
Easy to understand concepts through simple examples, deepen your understanding with practical code!
Object orientation is a means designed to deal with complexity rationally.
Designing object-oriented systems properly requires a lot of experience and training, and there are countless thick books on the subject.
But ultimately, object-oriented design is about asking questions about the systems that operate through objects.
We need to ask ourselves how to reduce complexity, keep code units small, maintain consistency in object state, properly control dependencies, reduce the cognitive load on developers through appropriate abstractions, while increasing the scalability of the system, and increase cohesion and decrease coupling through modularization.
To understand the meaning of these questions and how to apply them to object systems, I think it is better to expand your understanding by looking at practical code through simple examples rather than complex theories.
This book is just that kind of book.
It presents several tips for good object-oriented design, provides easy-to-understand code examples for each concept, and tells you what to do and what not to do when developing object-oriented systems.
Developers who want to learn object-oriented design can easily grasp the concepts through examples, and developers who are already familiar with object-oriented design can better understand the concepts of object-oriented design by comparing the advice in this book with their own experiences.
(From the translator's note)
- You can preview some of the book's contents.
Preview
index
Chapter 1: Everything is Complexity Management
1.1 Object-oriented design and the trials of time
1.2 Simple object-oriented system design
__1.2.1 Simple code
__1.2.2 Consistent Objects
__1.2.3 Proper Dependency Management
__1.2.4 Good abstraction
__1.2.5 Handling External Dependencies and Infrastructure Appropriately
__1.2.6 Good modularization
1.3 Simple design as an everyday activity
__1.3.1 Reducing complexity is similar to personal hygiene
__1.3.2 Complexity may be necessary, but it should not be permanent.
__1.3.3 It is cost-effective to continuously address complexity.
__1.3.4 High-quality code promotes good practices
__1.3.5 Controlling complexity is not as difficult as you think
__1.3.6 It is the developer's responsibility to keep the design simple.
__1.3.7 This is a good enough design
1.4 Briefly review the architecture of information systems.
1.5 Example: People Grow!
1.6 Practice Problems
1.7 Summary
Chapter 2 Keeping Your Code Small
2.1 Make your code units smaller
__2.1.1 Split complex methods into private methods
__2.1.2 Move complex code units to other classes
__2.1.3 When not to break code into smaller units
__2.1.4 Look at the whole thing before refactoring
__2.1.5 Example: Importing Employee Data
2.2 Make your code readable and documented.
__2.2.1 Keep looking for a good name
__2.2.2 Document your decisions
__2.2.3 Add comments to your code
__2.2.4 Example: Determining when to send an email notifying of a change in offering content
2.3 Separate new complexity from existing classes.
__2.3.1 Separate complex business logic into its own class.
__2.3.2 Break down the major business flows
__2.3.3 Example: Waiting List for an Offering
2.4 Practice Problems
2.5 Summary
Chapter 3 Maintaining Object Consistency
3.1 Always be consistent
__3.1.1 Let classes be responsible for their own consistency.
__3.1.2 Encapsulate the entire task and complex consistency checks.
__3.1.3 Example: Employee Entity
3.2 Design an effective data validation mechanism.
__3.2.1 Explicitly define preconditions
__3.2.2 Create a validation component
__3.2.3 Use nulls carefully and avoid them if possible.
__3.2.4 Example: Adding Staff to a Course
3.3 Encapsulate state checking
__3.3.1 Command, don't ask questions
__3.3.2 Example: Checking for vacant positions in an offering
3.4 Provide only necessary getters and setters.
__3.4.1 Getters that don't change state and don't expose too much information to clients
__3.4.2 Setters are only used for properties that describe an object.
__3.4.3 Example: Getters and Setters of the Offering Class
3.5 Model the aggregate to ensure invariants of the object set.
__3.5.1 Don't break the rules of aggregate routes
__3.5.2 Example: Offering Aggregate
3.6 Practice Problems
3.7 Summary
Chapter 4: Managing Dependencies
4.1 Separate high-level and low-level code
__4.1.1 Design stable code
__4.1.2 Interface Discovery 098
__4.1.3 When there is no need to separate high-level and low-level code
__4.1.4 Example: Message Processing Tasks
4.2 Avoid relying on unnecessary details or elements.
__4.2.1 Request or return only classes you own
__4.2.2 Example: Replacing an HTTP Bot with the Chat SDK
__4.2.3 Don't give your clients more than they need
__4.2.4 Example: Offering List
4.3 Separate classes that depend on too many other classes
__4.3.1 Example: Separating the MessageSender Service
4.4 Inject dependencies (use dependency injection)
__4.4.1 Do not use static methods for operations that change state.
__4.4.2 Always inject collaborators: otherwise do as you wish
__4.4.3 Strategies for creating classes and dependencies together
__4.4.4 Example: Dependency injection of MessageSender and its collaborators
4.5 Practice Problems
4.6 Summary
Chapter 5: Designing Abstraction Well
5.1 Design abstractions and extension points
__5.1.1 Identifying the Need for Abstraction
__5.1.2 Designing Extension Points
__5.1.3 Properties of a Good Abstraction
__5.1.4 Learn from Abstraction
__5.1.5 Learn about abstraction
__5.1.6 Abstraction and Combination
__5.1.7 Example: Awarding Badges to Employees
5.2 Generalize important business rules
__5.2.1 Separate general business rules from specific data.
__5.2.2 Example: Generalizing Badge Rules
5.3 Prefer simple abstractions
__5.3.1 Empirical Rules
__5.3.2 Simple is always better
__5.3.3 At this point, we need to consider abstraction.
__5.3.4 Don't be afraid to model abstractions from the beginning
__5.3.5 Example: Revisiting the Badge Example
5.4 Practice Problems
5.5 Summary
Chapter 6: Dealing with External Dependencies and Infrastructure
6.1 Separate domain code and infrastructure
__6.1.1 Is an interface needed?
__6.1.2 Hide details in your code, but don't hide them from developers.
__6.1.3 Changing Infrastructure: Is It Worthless or Will It Actually Happen?
__6.1.4 Example: Database Access and Messaging Bot
6.2 Make the most of your infrastructure
__6.2.1 Do your best not to break the design.
__6.2.2 Example: Canceling Registration
6.3 Rely only on what you own.
__6.3.1 Don't fight the framework
__6.3.2 Beware 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: Exception Handling in SDKBot
6.5 Practice Problems
6.6 Summary
Chapter 7: Achieving Modularity
7.1 Build a deep module
__7.1.1 Find ways to reduce the impact of changes
__7.1.2 Continuously refine domain boundaries
__7.1.3 Keep related items close by
__7.1.4 Avoid accidental coupling, but if unavoidable, document it.
7.2 Design the interface clearly
__7.2.1 Keep module interfaces simple
__7.2.2 Modules with backward compatibility
__7.2.3 Provide clean extension points
__7.2.4 Code as if people with different requirements would use the module
__7.2.5 Modules must have clear ownership and participation rules.
7.3 Avoid intimacy between modules
__7.3.1 Make modules and clients responsible for breaking intimacy
__7.3.2 Do not depend on inner classes
__7.3.3 Monitor the web of dependencies
__7.3.4 Monolith or Microservice?
__7.3.5 Consider events as a way to separate modules
__7.3.6 Example: Notification System
7.4 Practice Problems
7.5 Summary
Chapter 8: A Practical Approach
8.1 Be practical, but only as much as is necessary.
8.2 Refactor boldly, but break it down into smaller units.
8.3 Accept that your code isn't perfect.
8.4 Consider a redesign
8.5 You are responsible for your junior developers.
8.6 References
8.7 Practice Problems
8.8 Summary
Search
1.1 Object-oriented design and the trials of time
1.2 Simple object-oriented system design
__1.2.1 Simple code
__1.2.2 Consistent Objects
__1.2.3 Proper Dependency Management
__1.2.4 Good abstraction
__1.2.5 Handling External Dependencies and Infrastructure Appropriately
__1.2.6 Good modularization
1.3 Simple design as an everyday activity
__1.3.1 Reducing complexity is similar to personal hygiene
__1.3.2 Complexity may be necessary, but it should not be permanent.
__1.3.3 It is cost-effective to continuously address complexity.
__1.3.4 High-quality code promotes good practices
__1.3.5 Controlling complexity is not as difficult as you think
__1.3.6 It is the developer's responsibility to keep the design simple.
__1.3.7 This is a good enough design
1.4 Briefly review the architecture of information systems.
1.5 Example: People Grow!
1.6 Practice Problems
1.7 Summary
Chapter 2 Keeping Your Code Small
2.1 Make your code units smaller
__2.1.1 Split complex methods into private methods
__2.1.2 Move complex code units to other classes
__2.1.3 When not to break code into smaller units
__2.1.4 Look at the whole thing before refactoring
__2.1.5 Example: Importing Employee Data
2.2 Make your code readable and documented.
__2.2.1 Keep looking for a good name
__2.2.2 Document your decisions
__2.2.3 Add comments to your code
__2.2.4 Example: Determining when to send an email notifying of a change in offering content
2.3 Separate new complexity from existing classes.
__2.3.1 Separate complex business logic into its own class.
__2.3.2 Break down the major business flows
__2.3.3 Example: Waiting List for an Offering
2.4 Practice Problems
2.5 Summary
Chapter 3 Maintaining Object Consistency
3.1 Always be consistent
__3.1.1 Let classes be responsible for their own consistency.
__3.1.2 Encapsulate the entire task and complex consistency checks.
__3.1.3 Example: Employee Entity
3.2 Design an effective data validation mechanism.
__3.2.1 Explicitly define preconditions
__3.2.2 Create a validation component
__3.2.3 Use nulls carefully and avoid them if possible.
__3.2.4 Example: Adding Staff to a Course
3.3 Encapsulate state checking
__3.3.1 Command, don't ask questions
__3.3.2 Example: Checking for vacant positions in an offering
3.4 Provide only necessary getters and setters.
__3.4.1 Getters that don't change state and don't expose too much information to clients
__3.4.2 Setters are only used for properties that describe an object.
__3.4.3 Example: Getters and Setters of the Offering Class
3.5 Model the aggregate to ensure invariants of the object set.
__3.5.1 Don't break the rules of aggregate routes
__3.5.2 Example: Offering Aggregate
3.6 Practice Problems
3.7 Summary
Chapter 4: Managing Dependencies
4.1 Separate high-level and low-level code
__4.1.1 Design stable code
__4.1.2 Interface Discovery 098
__4.1.3 When there is no need to separate high-level and low-level code
__4.1.4 Example: Message Processing Tasks
4.2 Avoid relying on unnecessary details or elements.
__4.2.1 Request or return only classes you own
__4.2.2 Example: Replacing an HTTP Bot with the Chat SDK
__4.2.3 Don't give your clients more than they need
__4.2.4 Example: Offering List
4.3 Separate classes that depend on too many other classes
__4.3.1 Example: Separating the MessageSender Service
4.4 Inject dependencies (use dependency injection)
__4.4.1 Do not use static methods for operations that change state.
__4.4.2 Always inject collaborators: otherwise do as you wish
__4.4.3 Strategies for creating classes and dependencies together
__4.4.4 Example: Dependency injection of MessageSender and its collaborators
4.5 Practice Problems
4.6 Summary
Chapter 5: Designing Abstraction Well
5.1 Design abstractions and extension points
__5.1.1 Identifying the Need for Abstraction
__5.1.2 Designing Extension Points
__5.1.3 Properties of a Good Abstraction
__5.1.4 Learn from Abstraction
__5.1.5 Learn about abstraction
__5.1.6 Abstraction and Combination
__5.1.7 Example: Awarding Badges to Employees
5.2 Generalize important business rules
__5.2.1 Separate general business rules from specific data.
__5.2.2 Example: Generalizing Badge Rules
5.3 Prefer simple abstractions
__5.3.1 Empirical Rules
__5.3.2 Simple is always better
__5.3.3 At this point, we need to consider abstraction.
__5.3.4 Don't be afraid to model abstractions from the beginning
__5.3.5 Example: Revisiting the Badge Example
5.4 Practice Problems
5.5 Summary
Chapter 6: Dealing with External Dependencies and Infrastructure
6.1 Separate domain code and infrastructure
__6.1.1 Is an interface needed?
__6.1.2 Hide details in your code, but don't hide them from developers.
__6.1.3 Changing Infrastructure: Is It Worthless or Will It Actually Happen?
__6.1.4 Example: Database Access and Messaging Bot
6.2 Make the most of your infrastructure
__6.2.1 Do your best not to break the design.
__6.2.2 Example: Canceling Registration
6.3 Rely only on what you own.
__6.3.1 Don't fight the framework
__6.3.2 Beware 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: Exception Handling in SDKBot
6.5 Practice Problems
6.6 Summary
Chapter 7: Achieving Modularity
7.1 Build a deep module
__7.1.1 Find ways to reduce the impact of changes
__7.1.2 Continuously refine domain boundaries
__7.1.3 Keep related items close by
__7.1.4 Avoid accidental coupling, but if unavoidable, document it.
7.2 Design the interface clearly
__7.2.1 Keep module interfaces simple
__7.2.2 Modules with backward compatibility
__7.2.3 Provide clean extension points
__7.2.4 Code as if people with different requirements would use the module
__7.2.5 Modules must have clear ownership and participation rules.
7.3 Avoid intimacy between modules
__7.3.1 Make modules and clients responsible for breaking intimacy
__7.3.2 Do not depend on inner classes
__7.3.3 Monitor the web of dependencies
__7.3.4 Monolith or Microservice?
__7.3.5 Consider events as a way to separate modules
__7.3.6 Example: Notification System
7.4 Practice Problems
7.5 Summary
Chapter 8: A Practical Approach
8.1 Be practical, but only as much as is necessary.
8.2 Refactor boldly, but break it down into smaller units.
8.3 Accept that your code isn't perfect.
8.4 Consider a redesign
8.5 You are responsible for your junior developers.
8.6 References
8.7 Practice Problems
8.8 Summary
Search
Detailed image

Publisher's Review
Object-oriented systems, design them properly!
Learn the 6 principles & practical approach!
Object-oriented design, keep it simple!
Most of a developer's work is maintaining and evolving existing systems.
Building maintainable software systems requires good object-oriented design, and a key element of good object-oriented design is simplicity.
Even if a system is well designed initially, its complexity increases with each modification.
As new classes, methods, and features are added, the amount of state and abstraction to manage increases.
Keeping designs simple in the face of natural complexity growth is challenging, but managing complexity is essential for effectively maintaining and evolving software systems.
Learn six design principles that will help you control complexity and keep your object-oriented design simple.
Let's delve deeper into these six clear and practical principles!
A collection of practical design principles that will help you keep your object-oriented codebase simple as it grows and changes, along with practical techniques that can be applied to any object-oriented language.
We will divide this principle into the following six aspects and explore them in depth, one by one.
To help you understand each principle more deeply, we've prepared easy-to-understand illustrations, real-world system examples, and thought-provoking practice problems.
How to keep your code small
ㆍ How to maintain object consistency
How to properly manage dependencies
ㆍ How to understand abstraction and design well
How to properly handle and manage infrastructure
How to achieve a well-modular design
Let's look at an example of a backend system from a practical perspective!
We first explain the concept of each principle, then explain how to apply the principle from a practical perspective through code examples.
To illustrate design patterns, we'll use a fictional backend system example called PeopleGrow! throughout this book.
The team building PeopleGrow! is currently facing maintenance issues.
Bugs occur, simple changes affect unexpected areas of the system, and changes take days to complete.
We'll delve into PeopleGrow!'s design decisions and refine them, exploring the context, pros and cons of each principle, and when and when not to apply them.
[Author's Preface]
This book is for software developers who want to improve their object-oriented design skills.
We delve deep into code complexity, consistency, encapsulation, dependency management, abstraction design, infrastructure handling, and modularization.
Even advanced developers already familiar with similar approaches, such as Clean Architecture, will benefit from the unique perspective this book provides.
Readers should have basic knowledge of object-oriented concepts such as classes, polymorphism, and interfaces.
Although the code examples are primarily written in Java pseudo-code, they should be easy to understand for developers familiar with object-oriented programming languages such as C#, Python, and Ruby.
[Beta Tester Review]
Rather than talking about why object-oriented design is good, it covers how to write code and how to implement modules throughout software development.
This book concisely summarizes important information.
- Yoon Byeong-jo, Software Developer, Server Developer
As the structure of services becomes increasingly complex, we will discuss what aspects to focus on when modeling them.
Additionally, you can easily understand each theory of the principles covered in object-oriented programming through service development explained with example code.
- Choi In-ju, SSG.com, Backend Developer
Based on the author's experience, the book's greatest strength is its object-oriented approach to problem-solving for common, everyday cases.
The book's content was translated very easily, and it explains well how to improve good object-oriented code.
Consider carefully whether existing or well-made code needs to be maintained on an ongoing basis.
This book explains what to do and establish principles to maintain good design, such as the criteria for separating code and why ongoing maintenance is difficult.
- Chan-Woong Park, Lotte Rental Development Team
This book explains the essence of object-oriented design in an easy and in-depth way.
I was impressed by how it provided a fresh perspective for everyone, from those new to object-oriented concepts to developers with practical experience.
- Lee Ki-ha, OPDC (Open Platform Developer Community) Cloud Engineer
It presents a practical first step toward effectively managing and containing complexity through the principles of object-oriented design.
A clear and insightful introduction to object-oriented programming that every developer must read.
- Seo Young-won, Curly Software Engineer
This book makes you rethink the essence of object-oriented design.
I was particularly impressed by the part that went beyond simply listing the principles, but instead made me think about the relationships between the principles and the balance points in trade-off situations.
This book is beneficial to everyone, from beginners in object-oriented design to experienced developers and leaders contemplating system architecture.
- Choi Seong-wook, Cloud Security Engineer, Samsung Electronics VD Business Division Security Lab
If you're a developer who already has deep experience with development methodologies, this book will be an even more powerful tool.
This excellent guide bridges theory and practice, and will help you establish your own development philosophy.
- Park Myeong-cheol, Autoplus, 20-year Java developer
Learn the 6 principles & practical approach!
Object-oriented design, keep it simple!
Most of a developer's work is maintaining and evolving existing systems.
Building maintainable software systems requires good object-oriented design, and a key element of good object-oriented design is simplicity.
Even if a system is well designed initially, its complexity increases with each modification.
As new classes, methods, and features are added, the amount of state and abstraction to manage increases.
Keeping designs simple in the face of natural complexity growth is challenging, but managing complexity is essential for effectively maintaining and evolving software systems.
Learn six design principles that will help you control complexity and keep your object-oriented design simple.
Let's delve deeper into these six clear and practical principles!
A collection of practical design principles that will help you keep your object-oriented codebase simple as it grows and changes, along with practical techniques that can be applied to any object-oriented language.
We will divide this principle into the following six aspects and explore them in depth, one by one.
To help you understand each principle more deeply, we've prepared easy-to-understand illustrations, real-world system examples, and thought-provoking practice problems.
How to keep your code small
ㆍ How to maintain object consistency
How to properly manage dependencies
ㆍ How to understand abstraction and design well
How to properly handle and manage infrastructure
How to achieve a well-modular design
Let's look at an example of a backend system from a practical perspective!
We first explain the concept of each principle, then explain how to apply the principle from a practical perspective through code examples.
To illustrate design patterns, we'll use a fictional backend system example called PeopleGrow! throughout this book.
The team building PeopleGrow! is currently facing maintenance issues.
Bugs occur, simple changes affect unexpected areas of the system, and changes take days to complete.
We'll delve into PeopleGrow!'s design decisions and refine them, exploring the context, pros and cons of each principle, and when and when not to apply them.
[Author's Preface]
This book is for software developers who want to improve their object-oriented design skills.
We delve deep into code complexity, consistency, encapsulation, dependency management, abstraction design, infrastructure handling, and modularization.
Even advanced developers already familiar with similar approaches, such as Clean Architecture, will benefit from the unique perspective this book provides.
Readers should have basic knowledge of object-oriented concepts such as classes, polymorphism, and interfaces.
Although the code examples are primarily written in Java pseudo-code, they should be easy to understand for developers familiar with object-oriented programming languages such as C#, Python, and Ruby.
[Beta Tester Review]
Rather than talking about why object-oriented design is good, it covers how to write code and how to implement modules throughout software development.
This book concisely summarizes important information.
- Yoon Byeong-jo, Software Developer, Server Developer
As the structure of services becomes increasingly complex, we will discuss what aspects to focus on when modeling them.
Additionally, you can easily understand each theory of the principles covered in object-oriented programming through service development explained with example code.
- Choi In-ju, SSG.com, Backend Developer
Based on the author's experience, the book's greatest strength is its object-oriented approach to problem-solving for common, everyday cases.
The book's content was translated very easily, and it explains well how to improve good object-oriented code.
Consider carefully whether existing or well-made code needs to be maintained on an ongoing basis.
This book explains what to do and establish principles to maintain good design, such as the criteria for separating code and why ongoing maintenance is difficult.
- Chan-Woong Park, Lotte Rental Development Team
This book explains the essence of object-oriented design in an easy and in-depth way.
I was impressed by how it provided a fresh perspective for everyone, from those new to object-oriented concepts to developers with practical experience.
- Lee Ki-ha, OPDC (Open Platform Developer Community) Cloud Engineer
It presents a practical first step toward effectively managing and containing complexity through the principles of object-oriented design.
A clear and insightful introduction to object-oriented programming that every developer must read.
- Seo Young-won, Curly Software Engineer
This book makes you rethink the essence of object-oriented design.
I was particularly impressed by the part that went beyond simply listing the principles, but instead made me think about the relationships between the principles and the balance points in trade-off situations.
This book is beneficial to everyone, from beginners in object-oriented design to experienced developers and leaders contemplating system architecture.
- Choi Seong-wook, Cloud Security Engineer, Samsung Electronics VD Business Division Security Lab
If you're a developer who already has deep experience with development methodologies, this book will be an even more powerful tool.
This excellent guide bridges theory and practice, and will help you establish your own development philosophy.
- Park Myeong-cheol, Autoplus, 20-year Java developer
GOODS SPECIFICS
- Date of issue: June 25, 2025
- Page count, weight, size: 192 pages | 183*235*10mm
- ISBN13: 9791140713813
You may also like
카테고리
korean
korean