It seems that repository pattern is trending in the Android architecture examples that I find (including my example Clean-Contacts) and maybe it is because we are not applying the repository pattern how is meant to be. I talked about clean architecture and I created Clean Contacts repository to demonstrate the architecture but I talked about a pattern that is not doing what his authors really want to achieve. So pointing me out, I’m writing this post to try to clarify with the information I have, what is a repository.
A repository is an Object that mimics a Collection, that’s it. In the original definition you can see how Martin Fowler talks about memory and collections strategies (not data sources), just because it’s easy to implement this pattern if you think about a data base or an in memory collection but it’s not so easy to mimic a API like a collection, only in some cases makes sense.
The repository class has 4 basic methods:
create, update, delete and query. You can also add findOne, count or whatever a collection can handle, but the first four are the principals and should be enough for a basic implementation.
Create, update and delete seems easy, it’s just receive an object and do the basic operations, but what about query? It seems complicated because just with one parameter you have to handle various queries like “find a list of Contacts and sort it by name”. How I can achieve 2 different queries with one method? Accepting on it’s signature a Query pattern.
Query pattern is based on the interpreter pattern. This pattern converts a DSL (Domain specific language) to a language that the other endpoint can understand. Back to the connection query-repository that we were talking about, if we are implementing a Data source access we create a DSL to model a query in a natural language, for example it can be “all Contacts sorted by name”, you can create the language you want in your domain, you have to know how to interpret this later. The Query interprets this language and converts to SQL or a Predicate if you use Guava and in-memory collections. A nice way to implement this behaviour is to create a list of Criteria patterns inside the query and interpret criterias to compose a query.
About this kind of logic:
It belongs to your domain logic, you can think that is a kind of Chain Of Reponsability pattern but is not exactly the same, but hey, you can implement in that way if it’s easier for you or you want to wrap it using a pattern.
The important thing is that this logic belongs to your domain, it’s fine if you create a layer only for a repository, but ensure you are implementing the correct thing and don’t name patterns if the implementing code doesn’t look exactly as the pattern says, because people will have troubles to interpret the code right.
Feeling hungry? Let’s talk about managing transactions with the Repository pattern.
Unit of Work
Unit of work (UOW) is a pattern that can help you with transactions and it’s really helpful if you use the Repository/Query pattern. Martin Fowler describe this pattern as:
Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems.
A basic implementation of this pattern basically maintains in memory the status of the objects with three lists of objects of domain model: new, dirty and removed. Basically, when you create a new object you’ll insert a new object in the new list. If you delete an object you’ll delete it from dirty and removed and if you are updating an object you’ll insert that changes into the dirty list. When you are done with all changes you call commit that will execute in this order the operations: insertNew, updateDirty, deleteRemoved.
I don’t know in what are you actually working but this is really complex to implement and I still don’t have any use case in mobile applications that can take real advantage of this pattern. I’m going to refactor Clean Contacts just moving code and making the domain layer take this decisions and continue handling data as in the previous version but using proper names for each data collaborator.
Do you want to know more about this and other enterprise patterns? In order to discover the thurth I recommend you to read the original martin fowler book: