DEV Community

loading...
Cover image for Avoid Repository pattern for operations not related to persistence

Avoid Repository pattern for operations not related to persistence

Pedro Massango
Software Engineer at Monstarlab
・2 min read

Versão em Portugês disponível aqui.

Today I want to share a bit about the Repository and Facade pattern. I will attempt to explain their differences, as there seems to be a few common misconceptions about them.

Repository

Let's try to define a repository, from the dictionary: a place, room or container where something is deposited or stored. Interms of programming, the concept can be defined as a class responsible for handling CRUD (create, read, update and delete) operations for a specific domain model through the usage of one or more data sources.

By the definition above, we can see that we should use repositories for CRUD operations only, which means we can have a UserRepository and never a AuthenticationRepository, simply because authentication does not describe a set of CRUD operations (assuming we're talking about login/registration operations).

A common mistake I have seen is that some people define repositories for system access operations for example:

abstract class AuthenticationRepository {

  Future login(String username, String password);

  Future register(String name, String email, String password);
}
Enter fullscreen mode Exit fullscreen mode

Take #1: Only use repository pattern for CRUD operations

Clearly those are not operations for storing/retrieving data and so we should never declare them in a repository. Then what? Facades!

Facade pattern

From Wikipedia, we can define a facade as an object that serves as a front-facing interface masking more complex underlying code.

Now let's move on to defining a repository: a Repository is a type of facade that specializes in masking/abstract complex CRUD operations specifically between data source(s).

A Repository is a more specialized type of Facade

To compare and constrast, facades are more general than repositories -- they can be used for anything other than persistence. You can use facades to abstract complex interactions within multiple bank APIs. For example:

// Or BankOperationsFacade.
abstract class BankOperations {

  Future payTelecomService(double amount, String cardId, String serviceId);

  Future transfer(double amount, String senderId, String recipientId);
}

// Custom implementation for XBank interaction goes here.
class XBankOperations extends BankOperations { }

// Custom implementation for YBank interaction goes here.
class YBankBOperations extends BankOperations { }

Enter fullscreen mode Exit fullscreen mode

Take #2: A Repository is a more specialized type of Facade

Let's review the first piece of code featured in our article, but this time, we'll refactor the name of the class to be something more meaningful.

// Or any other meaningful name.
abstract class AuthenticationFacade {

  Future login(String username, String password);

  Future register(String name, String email, String password);
}
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  • Facades can be applied to anything that's not persistence based
  • Repositories are for wrapping the communication with one or more data sources and abstracting this away from the user of the repository
  • Facades are more generic than repositories.

It is important to make use of those concepts properly to avoid writing code that is hard to understand and to maintain a healthy code base.

That's it, I hope this helps you somehow; please let me know your thoughts in the comments section.

Discussion (0)