Design patterns is a reusable solution to a commonly occurring problem. It can also be considered as a template for how to solve a problem that can be used in many different situations. There are a lot of design patterns in programming among which the repository pattern is one.
Nowadays, we have seen many questions about how to use the repository pattern. To use a repository pattern, we must first understand the underlying principle about it. The main idea to use repository design pattern is to create a bridge between controllers and models. During programming, it is always a best practice to minimize the dependencies between controllers and models. So, using this pattern helps to achieve it.
To be more specific, repository pattern acts as a layer where data access is stored. It hides the details of data access logic from business logic. In other words, we allow business logic to access the data object without having knowledge of underlying data access architecture.
Without using this pattern, we simply access our models directly from our controller as in the following example.
$products]); } } ?>
In the above example, we are simply accessing our database through the model directly. This will increase the coupled between model and controller which is not a best practice for programming. To remove this problem, we can use the repository design pattern.
Repository design pattern uses interfaces as a contract. If you are new to interface in php, you can read about it in the article “Understanding Interface in PHP“.
We must define our interface to use this pattern. First of all, we need to define common operations to create an interface like get all records, edit records, delete records, etc. So, Lets define common methods that are normally used to interact with the database.
After creating interface, we need to implement it in our repository. So, our ProductRepository looks like below:
name = 'Vijay Rana' $user->email = 'vijay@vijayrana.com.np/blog'; $user->password = 'secret' return $user->save(); } public function updateProduct($id) { // update after validation $user = User::find($id); $user->name = 'Vijay Rana' $user->email = 'vijay@vijayrana.com.np/blog'; $user->password = 'secret' return $user->save(); } public function deleteProduct($id) { $product = Product::find($id); $product->delete(); } } ?>
So, our ProductInterface and ProductRepository are ready, we can implement these in our controller. Thus, our ProductContrller after using repository looks like below:
product = $product; } public function getAllProducts() { $products = $this->product->getAllProducts(); return view('products.index', ['products' => $products]); } public function getProductsById($id) { $product = $this->product->getProductsById($id); return view('products.product', ['product' => $product]); } public function createProduct(Request $request) { $this->user->createProduct($request); // do other stuff or return view } public function updateProduct($id) { $this->product->updateProduct($id); //do other stuff after update } public function deleteProduct($id) { return $this->product->deleteProducts($id); } } ?>
Have you noticed, this controller injects Interface rather than the repository. So, this results in loosely coupled with the Product model and is more easily testable.
Now the last part is to bind the interface. So it’s necessary to tell the IoC container that, whenever the ProductController class is getting instantiated, just pass an instance of the concrete ProductRepository class which implemented the type hinted interface given in the constructor method.
So, we need to bind the concrete class to the interface for the IoC container so it can supply the class to the controller as follow:
Conclusion
Repository Pattern is a great way to clean up your controller. By using interface and repositories for communicating with models, it separates the business logic and presentation logic. This pattern also helps to make our code more readable, testable, and reusable.