Learn about the repository design pattern for persistence management.
Concepts
CRUD
data store
Data Access Object (DAO)
entity
persistence
repository pattern
Lesson
You briefly studied a mult-layered application when studying a program's command-line interface. The layers of a program help separate the various concerns needed to implement the program's functionality. Logic for interacting with the user, whether via a CLI or via a GUI, are placed in the presentation later, as you already learned. In a common three-tier application, the data layer is concerned with saving the information in some data store such as the database in the diagram below.
Repository Pattern
The term data store is more general than file system or database. An application may use various mechanisms to allow its data to persist even when the application is shut down or restarted. To allow the application to use various persistence mechanisms—some of which may not even be known at the time the application is first written—the repository pattern is used to abstract access to the data store behind a general repository interface.
Repositories generally work with some entities, which usually represent the business objects of the application. The specific methods a repository provides depends on the needs of the application and the types of data stores to be supported, but here are the fundamental functionalities provided by a repository:
The ability to create new entities.
The ability to read the entities. This may involve querying for specific types of entities, or find an entity with a specific identifier.
The ability to update or change the entities.
The ability to delete entities when they are no longer needed.
Here is an example of a repository interface that might be used for accessing a fleet of vehicles for a transportation company. Can you identify the CRUD methods?
Review
Gotchas
Don't put implementation assumptions into the repository contract.
Self Evaluation
What purpose does a repository serve?
What are some different examples of how a repository might be implemented?
Task
Your booker project currently has a lot of code for working with publications directly in the Booker application class. Even the code for creating the publications is there. In the future you may want to load these publications from a database, or retrieve them directly from the Internet in real time.
Create and implement a repository for your publications.
Refactor your persistence-related publication methods into a PublicationRepository interface.
Include only those methods you need now and/or think appropriate. Don't try to plan ahead too much about future needs.
Move your existing implementation of those methods into a SnapshotPublicationRepository to hold a snapshot of the popular publications on a historical date (i.e. those publications you have been working with since creating the Booker application).
This repository doesn't actually access any data storage.
The collection of publications should no longer be a static variable; construct whatever collections you need as an instance variable when the repository is created.
The SnapshotPublicationRepository is to be a read-only repository! Even if the PublicationRepository interface provides for modification, the SnapshotPublicationRepository implementation must not allow such methods to be called. Consider how read-only collections are implemented.
Create a unit test of your repository implementation.
Many if not all of your tests will already be written in some form; they merely need to be moved out of the Booker unit test class and into a repository unit test class.
This is a refactoring effort. There should be no change in the main program functionality. You are only changing the program structure and model to be more easily maintained and to support new features.