Applying Specification Design Pattern in Laravel

Tram Ho

As a programmer, surely each of us is not unfamiliar with the concept of Design Pattern. They are standard design patterns, templates for common problems in software design. In this article, I will introduce a popular design pattern – Specification and how to implement it in Laravel.

1. What is the Specification Design Pattern?

Specification pattern is a design pattern whereby business rules can be recombined by chaining. Each specification has a rule that must be followed. Specification allows us to encapsulate some business information into a single unit of code and re-use them in different places, making our code more reusable and easy to read and understand. more maintenance.

This approach not only eliminates business duplication, it also allows for combining multiple businesses by multiple Specifications. Makes it easy to set up complex search conditions and check data. There are three main use cases for the Specification Pattern:

  • Search data in DB. Search for records that satisfy the condition.
  • Check objects in memory. In other words, check if an object matches the condition
  • Create a new instance that satisfies the condition.

image.png

Suppose we have a problem that retrieves invoices and sends them to a collection agency if the following three conditions are met: (1) the invoice is past due, (2) the overdue notice has been sent, (3) the invoice has not been sent to the collection agency. This example is intended to show the end result of how the business logic is ‘chained’ together. It is possible to write a method to check the condition that sends an invoice to a collection agency in the Invoice model class. However, such writing violates the Single Responsibility principle in SOLID, furthermore it is not possible to reuse those business logic.

Solution: We have an OverdueSpecification class that is satisfied when the invoice due date is 30 days or more, a NoticeSentSpecification class that is satisfied when the notification has been sent to the customer, and an InCollectionSpecification class that is satisfied when the invoice is has been sent to the collection agency. Using these three specification classes, we create a new specification class called SendToCollection , which will be satisfied when the invoice is past due, when the notification has been sent to the customer and has not been sent to the collection agency.

2. Implement Specification Pattern in Laravel

When querying the database, we often have to combine different query conditions (where, orWhere, whereIn…). For example, get jobs with the corresponding company_id, get a model with the corresponding id, orderBy by column, eager loading relationships… For each condition we will create a corresponding Specification class (like CompanyIdSpecification, IdSpecification, OrderBySpecification, WithRelationsSpecification ), reusable in many places in the code.

Interface SpecificationInterface

AndSpecification class to chain Specifications logically and

Class OrSpecification to chain Specifications logically or

Class NoneSpecification

Class CompanyIdSpecification

Class IdSpecification

Class OrderBySpecification

Class WithRelationsSpecification

Using specification in controller, service or repository class: Example retrieves jobs with company_id = 15, eager loading candidates for each job and sorting jobs by creation time

3. References

Share the news now

Source : Viblo