One issue causing confusion about whether to choose a repository or a service is where to put business logic methods like getEntityItemBySomeAttribute(attribute).
The use of Specifications in a standard query method seems to solve this problem.
Where you would want to choose the Service instead is when the logic of the query spans multiple repositories or a combination of repositories and external services -- this is DDD guidance.
Be mindful of the difference between APIs and SPIs. APIs should be final concrete classes and SPIs should be Interfaces. The clients of APIs are callers while the clients of SPIs are implementers.
I've noticed that repositories are typically SPIs while services are typically APIs.
Refs:
http://wiki.apidesign.org/index.php?title=APIvsSPI&useskin=monobook
https://docs.oracle.com/javase/tutorial/ext/basics/spi.html
http://stackoverflow.com/questions/12317126/onion-architecture-repository-vs-service
http://thinkinginobjects.com/2012/08/26/dont-use-dao-use-repository/ -- notes that DAOs are no longer favored because they are too general and loosely typed.
-------
2015-09-03
Current common practice appears to have a topology like Service<T> --injected with--> Repository<T> --injected with--> JDBCTemplate or DataSource. see http://stackoverflow.com/a/24083073/2066936
Showing posts with label Repository. Show all posts
Showing posts with label Repository. Show all posts
Thursday, November 27, 2014
Monday, June 11, 2012
ORM vs. Repository
All other ORMs I've ever encountered are completely at odds with the Repository pattern. This goes for both L2S and EF, because they require not only that you derive from a particular base class, but also that Entities have default constructors.Mark Seemann http://www.manning-sandbox.com/message.jspa?messageID=105843
Tuesday, May 1, 2012
Domain Model vs. BLL
Just to be clear, I like to think of a Business Model and Business Logic as two separate layers. Your business model are your POCOs (Plain old CLR objects). Your business logic layer would be responsible for performing validations, transactions, etc using both your business model and an interface to your DAL that could be wired up a number of ways (Spring, Castle, or your own home grown IoC container).
Trent - http://www.techques.com/question/1-458098/Business-Logic-Layer-and-Data-Access-layer:-circular-dependency
I'd like to remove the coupling to allow us to support different address repositories as we can with the .Save within our CustomerRepository (via RepositoryFactory). I'd also like to remove any knowledge of repositories from my domain objects. Although it isn't always possible I prefer for application code to have knowledge of repositories NOT my domain objects.http://web.archive.org/web/20100420152400/http://steve.emxsoftware.com/Domain%20Driven%20Design/DDD%20Reconstituting%20objects%20from%20multiple%20Repositories
Monday, April 30, 2012
Data Mapper Pattern
Additionally, sometimes people split the Data Mapper part into the mapping part ("this attribute maps to this column") and a separate service part ("here's how to insert data"), which further separates the concerns.John Feminella - http://stackoverflow.com/questions/1977120/data-mapper-an-domain-object-should-never-call-its-data-mapper
In the DataMapper pattern you have one domain object that holds all the business logic, for exmaple user.getLinkToProfile() (or something similar) but knows nothing about the database in question, in addition to this you have a mapper-object that is responsible for saving, updating, selecting, etc. user objects from the database which would have UserMapper::find(1), UserMapper.save(user)thr - http://stackoverflow.com/questions/93773/how-does-the-activerecord-pattern-differ-from-the-domain-object-or-data-mapper-p
http://blog.steveklabnik.com/posts/2012-05-07-mixins--a-refactoring-anti-pattern discusses use of DataMapper to reduce surface area of ActiveRecord classes. Essentially an ActiveRecord should not have any public methods; properties are set by DataMapper or Repository through its constructor.
Friday, April 13, 2012
Repository Pattern
There are two ways that the repository can query business entities. It can submit a query object to the client's business logic or it can use methods that specify the business criteria. In the latter case, the repository forms the query on the client's behalf. The repository returns a matching set of entities that satisfy the query.http://msdn.microsoft.com/en-us/library/ff649690.aspx
A good practice that’s gaining well-deserved popularity is wrapping data access code in façade classes known as repositories. A repository consists of an interface and an implementation class. You typically have a repository for each significant class in the model. A significant class in an object model is a class that controls its own persistence and stands on its own in the domain without depending on other classes. In general, for example, Customer is a significant class, whereas OrderDetails is not, because you’ll always use order details if you have an order. In DDD, a significant class is said to be an aggregate root.http://msdn.microsoft.com/en-us/magazine/hh456393.aspx
A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes.http://martinfowler.com/eaaCatalog/repository.html
I suspect that Customer should be a separate aggregate without a list of orders, and Order should be an aggregate with a list of order lines. If you need to perform operations on each order for a customer then use orderRepository.GetOrdersForCustomer(customerID); make your changes then use orderRespository.Save(order);David Masters - http://stackoverflow.com/questions/5017969/repository-pattern-without-an-orm
In many systems every Entity has a Repository. Repository is a term gaining popularity over the Dao acronym. Repository is a nice word I guess, but we all call them Daos; so let's just go with it. Each Entity has a Dao. Let the Entity drive the Dao design. Let your domain drive the Dao design. For god's sakes though, don't get on a high horse and try to define it for them with some junk you found on the internet.http://raykrueger.blogspot.com/2007/09/best-generic-dao-interface-ever.html
Linkgoron
----
I would like to offer a mild defense of repositories. First I want to wholeheartedly agree that the generic repository and the repository-per-class pattern are useless crap. - Jamie Ide
http://ayende.com/blog/4784/architecting-in-the-pit-of-doom-the-evils-of-the-repository-abstraction-layer
The Repository represents the domain’s contract with a data store (another common word we may use here is that it is the seam).
http://codebetter.com/gregyoung/2009/01/16/ddd-the-generic-repository/
Note that repository doesn’t talk in terms of “data”, it talks in terms of Aggregate Roots. You can tell your repository to add an Aggregate Root into its collection, or you can ask it for a particular Aggregate Root. When you remember that Aggregate Roots may comprise one or many Entities and Value Objects, this makes it fairly different to a traditional DAL that returns you back a set of rows from your database tables.http://www.codeproject.com/Articles/339725/Domain-Driven-Design-Clear-Your-Concepts-Before-Yo
In such systems it can be worthwhile to build another layer of abstraction over the mapping layer where query construction code is concentrated. ... A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects...http://martinfowler.com/eaaCatalog/repository.html
Subscribe to:
Posts (Atom)
I'd say that's the biggest mistake they've done with the Specification <t class. They've abstracted away a part of the language which they shouldn't have. They should've used Expression <func<t,bool>