@@ -105,78 +105,53 @@ objects.
105
105
106
106
## Data Access Object
107
107
108
+ > ** Data Access Object** (DAO) pattern comes from ** early enterprise application design** , and its
109
+ > formalization can be found in the book "Core J2EE Patterns: Best Practices and Design Strategies" by Deepak Alur, John
110
+ > Crupi, and Dan Malks, published in 2001. DAO abstracts and encapsulates all access to a data source, separating
111
+ > persistence logic from business logic. This allows changes to the underlying data source without affecting the rest of
112
+ > the application, which is especially useful in enterprise contexts where systems might switch databases or data
113
+ > storage
114
+ > mechanisms over time.
115
+
108
116
** DAO** (Data Access Object) is an enterprise pattern that is used as abstraction of data persistence.
109
117
110
118
## Repository
111
119
120
+ > The ** Repository** pattern originates from ** Domain-Driven Design** (DDD), as described by Eric Evans in his book, "
121
+ > Domain-Driven Design: Tackling Complexity in the Heart of Software." (2003) Repositories are not just about managing
122
+ > data; they encapsulate business logic, ensuring that operations adhere to the Ubiquitous Language of the domain.
123
+
112
124
** Repository** is an enterprise pattern that mediates between the domain and persistence layers using a collection-like
113
125
interface for accessing domain objects.
114
126
115
- ### Collection-oriented vs Persistence-oriented
116
-
117
- * ** Collection-oriented** : can be thought as an in-memory set of entities which can track object changes.
127
+ * ** Collection-like repository** : can be thought as an in-memory set of entities which can track object changes.
118
128
Usually, you deal with this kind of repository when you are working with SQL databases and an ORM.
119
129
120
- * ** Persistence-oriented** : as a list or table of entities where you cannot track their changes.
130
+ * ** Persistence-oriented repository ** : as a list or table of entities where you cannot track their changes.
121
131
Persistence-oriented repositories are more common in document (NoSQL) databases and an ODM.
122
132
123
- ### Use Specific repositories instead of Generic
124
-
125
- E.g. UserRepository vs Repository[ User]
126
-
127
- ** Generic repository** is an a priori anti-pattern, since the repository encapsulates the logic of storing aggregates,
128
- not a specific domain model. However, it is allowed to move the general functionality to the base class.
129
-
130
- ### Manage transactions outside the repository
131
-
132
- The transaction management can not be the responsibility of the repository. It is the responsibility of the client
133
- code to manage transactions. Therefore, repositories controlling transaction are considered an anti-pattern.
134
-
135
- ### Use Aggregate-centred repository instead of Model-centred
136
-
137
- E.g. OrderRepository vs OrderRepository+OrderItemRepository
138
-
139
- * ** Aggregate-centred** repository is the only correct approach. Order should be able to save the whole aggregate
140
- at once. This way, you can ensure that the aggregate is always consistent.
141
-
142
- * ** Model-centred** repository is considered an anti-pattern. The trouble with this approach is that it doesn't take
143
- into account the consistency boundaries. You can't save Order and OrderItem separately, because they are part of the
144
- same aggregate. Otherwise, you might end up with inconsistent data.
145
-
146
- If you have a simple business logic, you might not need to use the repository pattern at all since there
147
- is DAO pattern that can be used to access the database directly.
148
-
149
- ### Repository vs ORM Session
150
-
151
- ** ORM Session** is more about data access, while ** Repository** is more about business logic.
152
- Repository may include pagination, filtering, caching, and other business logic, while ORM Session is more about
153
- CRUD operations.
154
-
155
- ### Repository vs Data Access Object
156
-
157
- The ** Repository** pattern originates from ** Domain-Driven Design** (DDD), as described by Eric Evans in his book, "
158
- Domain-Driven Design: Tackling Complexity in the Heart of Software." (2003) Repositories are not just about managing
159
- data; they
160
- encapsulate business logic, ensuring that operations adhere to the Ubiquitous Language of the domain.
161
-
162
- On the other hand, the ** Data Access Object** (DAO) pattern comes from ** early enterprise application design** , and its
163
- formalization can be found in the book "Core J2EE Patterns: Best Practices and Design Strategies" by Deepak Alur, John
164
- Crupi, and Dan Malks, published in 2001. DAO abstracts and encapsulates all access to a data source, separating
165
- persistence logic from business logic. This allows changes to the underlying data source without affecting the rest of
166
- the application, which is especially useful in enterprise contexts where systems might switch databases or data storage
167
- mechanisms over time.
168
-
169
- The primary distinction between Repository and DAO lies in the semantics of the API they expose:
170
-
171
- * ** DAO** : DAO is data-centric, providing database operations such as insert, update, delete, and find. These methods
172
- directly map to database actions, focusing on how data is stored and retrieved.
173
- * ** Repository** : This is domain-driven and aligns with the business logic. It represents a collection of aggregate
174
- roots
175
- or entities. Instead of database operations, repositories offer operations that reflect the domain language. For
176
- instance, in a hotel system, a Repository might provide checkIn, checkout, or checkReservation, abstracting away the
177
- actual data operations.
178
-
179
- Repository could be implemented using DAO's, but you wouldn't do the opposite.
133
+ Best practices:
134
+
135
+ 1 . ** Don't use generic repository** . Generic repository is an a priori anti-pattern, since the repository encapsulates
136
+ the logic of storing aggregates,
137
+ not a specific domain model. However, it is allowed to move the general functionality to the base class.
138
+ 2 . ** Manage transactions outside the repository** . The transaction management can not be the responsibility of the
139
+ repository. It is the responsibility of the client
140
+ code to manage transactions.
141
+ 3 . ** Focus on aggregates, not entities** . E.g. you can't save Order and OrderItem separately, because they are part of
142
+ the
143
+ same aggregate. Otherwise, you might end up with inconsistent data.
144
+
145
+ | Criterion | Repository | Data Access Object (DAO) | ORM Session |
146
+ | ----------------------------| -------------------------------------------------------| ----------------------------------------------------| -----------------------------------------------------|
147
+ | ** Main Idea** | Abstraction over a collection of domain model objects | Abstraction for working with a data source | Object managing ORM transactions and sessions |
148
+ | ** Level of Abstraction** | High (works with domain objects) | Medium (works with database objects) | Low (works with specific SQL queries via ORM) |
149
+ | ** ORM Dependency** | Not tied to ORM (but can use it) | Can use ORM, JDBC, ADO.NET, and other technologies | Part of ORM (e.g., SQLAlchemy, Hibernate) |
150
+ | ** Focus** | Business logic and working with aggregates | Encapsulation of CRUD operations | Managing connections and transactions |
151
+ | ** Where Used** | DDD (Domain-Driven Design), complex systems | Smaller projects, clean architecture | ORM frameworks (SQLAlchemy, Hibernate) |
152
+ | ** Flexibility** | High, can switch between data sources | Medium, requires adaptation for a data source | Low, tightly coupled with ORM |
153
+ | ** Ease of Testing** | High, easily mockable | Medium, testing is possible | Low, requires mocks or a test database |
154
+ | ** Example Implementation** | ` UserRepository.get_active_users() ` | ` UserDAO.get_user_by_id(id) ` | ` session.query(User).filter(User.id == id).first() ` |
180
155
181
156
## Specification
182
157
0 commit comments