ProgramGuru

Repository Pattern

Repository: separate a useful responsibility

See the responsibility boundary

Business serviceNeeds an order operation
Repository contractNames domain-oriented access
Storage implementationExecutes and maps queries
Domain objectReturns under a defined contract
Business service: Needs an order operation → Repository contract: Names domain-oriented access → Storage implementation: Executes and maps queries → Domain object: Returns under a defined contract

Order rules need to load and save orders, while database queries are repeated throughout the business code. A change in persistence details should not force every rule to understand indexes, row mapping and connection management.

This application-pattern lesson connects local organization with the system contracts discussed elsewhere in the course. The code is an original small local example, not a production persistence or web framework.

What you’ll learn

  • Explain the responsibility Repository separates.
  • Follow its local example and identify the implementation boundary.
  • Compare related patterns and test the required guarantees.

How the responsibility is divided

Repository presents a domain-oriented access boundary over persisted objects. Its operations reflect useful queries and changes rather than exposing every storage command. A repository implementation maps the model to the chosen storage and its actual guarantees.

The example loads an order by identity through a repository contract. It uses a Map for teaching, not a durable database. Replacing it with SQL or another store must preserve defined error, query, concurrency and transaction behaviour.

Follow a small JavaScript example

Read the program and compare the expected output. Its state is local to one execution context; a real implementation needs the persistence, request and effect contracts described in the trade-offs.

JavaScript · local teaching example

const rows = new Map([['O1', {id: 'O1', status: 'ready'}]]);
const orders = {findById: id => rows.get(id)};
function orderStatus(repository, id) {
  const order = repository.findById(id);
  return order ? order.status : 'not found';
}
console.log(orderStatus(orders, 'O1'));

Expected output

ready

Choose a boundary from the situation

Compare boundary choices

Business code needs an order by identity.
A replacement store has different concurrency guarantees.

Compare the visible consequences. With JavaScript enabled, choose an option in each scenario to assemble your decision record.

This is an exploratory design exercise. It does not run infrastructure, measure capacity or replace the lesson’s quiz.

Choose the responsibility and examine what it does and does not promise.

All alternatives and consequences remain visible. Select one per situation to record your reasoning.

Choose it for a concrete need

Use it when a domain-oriented persistence boundary improves separation and testability. Keep important query shape and transaction scope deliberate.

An excessively generic CRUD wrapper can hide expensive queries without providing a useful domain contract. Repositories do not make all databases interchangeable; uniqueness, isolation and mapping differences still matter. Specify whether returned objects are snapshots or mutable tracked entities.

Compare the neighbouring responsibilities

Adapter reconciles an interface mismatch. Repository expresses a domain persistence boundary and may use adapters internally. Unit of Work can coordinate changes across repositories within one supported transaction.

Continue with coordinating one transaction’s changes, adapting component interfaces, storage guarantees and access patterns.

For primary further reading, use the Repository catalog entry and compare the responsibilities with this course’s original example.

Check your pattern reasoning

Does a Repository make every database transparently interchangeable?
Choose one answer. You can try again.

Answer and explanation

No; query and storage guarantees still matter.

The interface must have a realizable contract.

Check your pattern reasoning

Which repository operation is easier for order code to understand?
Choose one answer. You can try again.

Answer and explanation

A bounded domain query with explicit outcomes.

It states the access responsibility and result meaning.

Keep the boundary and its guarantees explicit

Use Repository when its responsibility matches the actual problem. Keep implementation lifetime, concurrency and error behaviour visible rather than treating an organizational label as proof.

Return to the design-pattern guide or apply this alongside storage guarantees and access patterns.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Unit of Work Pattern →