Repository Pattern
Published: 2020-03-17 11:25:49

Design Patterns are a new idea to me, but the concept is easy enough to understand; it's a general, reusable solution to a commonly occurring problem. The idea came from an architect, Christopher Alexander, and has been adopted in software.

All OO languages can work with classes to store and manipulate data, but a pattern would be a particular way of using objects to create and manipulate other objects that has been proven to work for a specific purpose. Let's take a look at the Repository Pattern.

**What's a Repository?**

A Repository has access to a collection of objects of a single class, on which you can perform CRUD operations.

Eric Evans explained it in his book `Domain Driven Design`: *A Repository represents all objects of a certain type as a conceptual set. It acts like a collection, except with more elaborate querying capability*

**Example 1**

    public interface ContactRepository() {
    
        void createContact(Contact contact)
        void removeContact(Contact contact)
        void updateContact(Contact contact)
        List query(Specification specification)
    }

In this Interface, notice that the methods used are CRUD methods, that they all take an object as their argument, and that the object is the same for each of them.

The `query` method is an exception. Assuming that you are working with a large set of data, potentially in a database, it's not feasible to load them all, all of the time. Instead, you load a specific one or group that match a query.
To implement this, you need a `Specification` object. If you wanted to query by date, the business layer could pass a Date object to the repository, which then returns the results matching that query.

You would likely need other methods for functionality like returning objects before or after a specific date, and that's fine; just make more methods.

**Business Objects and the Business Layer**

The data you are returning is known as a `business object`, as it is complete in a business sense. Take an account or a user, both are complete ideas that may need to be understood and accessed by the `business layer`. Importantly, the business layer doesn't care about how the data persists - so it could be in-memory or a DB - the only thing it cares about is storing and retrieving objects, which it does through the repository.

**How is the Repository Pattern distinct from other patterns?**

As previously stated, the Repository Pattern receives objects and queries using those objects, and only works with a single, complete business object.
If instead you were using the Data Access Object (DAO) Pattern, you might not use a complete business object, so you might return more than a single type of object, and you might not query with objects, but with a variable.

**Summary**

If you're working with data like accounts, you can access those accounts from a class (business layer) by creating an intermediary class (repository) that understands accounts and only accounts. It CRUDs accounts, and can return them to the first class, which doesn't need to know how anything works as long as it gets what it wants.

Business Layer <---> Repository <---> Storage