Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-CRUD operations in repository classes

I have a Repository class for sales persons like so:

public class SalesPersonRepository : ISalesPersonRepository
{
     public int Add(SalesPerson salesPerson)
     {
          // Add the salesperson to the data store and return the Id
     }

     public void Update(int id, SalesPerson salesPerson)
     {
         // Update the sales person's record in the data store
     }

     public SalesPerson Get (int id)
     {
         // Fetch and return the salesperson's record
     }

    // a couple of other methods like GetAll and Delete
}

As you can see, I am using a SalesPerson class in which I have represented a salesperson and in my repository class, I'm using standard CRUD operations like the ones above.

However, when I run into a requirement like this: "Fetch the number of sales for the last 30, 60 and 90 days for the salesperson", "Fetch the number of customers for the salesperson" etc., I am not certain if I should return this data in the SalesPerson object.

I could add define properties like SalesPerson.ThirtyDaySaleCount, SalesPerson.SixtyDaySaleCount, SalesPerson.NinetyDaySaleCount, and assign them in the repository method, but obviously, this doesn't seem like good design.

Moreover, when I am fetching the 30, 60, 90 day sale count for the salesperson, I'm NOT interested in the other things that are defined in the SalesPerson class, like first name, last name, and other information.

So how do I return data for these specialized scenarios? Should I create specialized classes just for these, or should I just go ahead and put everything in the SalesPerson class?

PS: I know that SalesPerson is an anemic object, and I should probably think of making it non-anemic, but my immediate concern is that non-CRUD requirements are coming in thick and fast and I need to solve for that first.

like image 489
SirG Avatar asked Jan 27 '26 04:01

SirG


2 Answers

Create a specialized ReportingRepository returning a specialized form of SalesPerson, or use CQRS.

like image 61
guillaume31 Avatar answered Jan 28 '26 16:01

guillaume31


They are just another way to see the same data of the SalesPerson.
I think some concepts of CQRS can be adapted to your situation. In your case I would have something like:

interface SalesReportingService {
    Integer countSalesOfPeronsInPreviousDays(SalesPersonId id, Integer days)
}

The value that you need is a number, so the code component who need this information can use this service that will calculate it (isolating that use case from knowing how to calculate it, it express just the dependency on the query).
Then the implementation of the service can be done as the easier way with a direct implementation like SqlSalesReportingService (or MongoDbSalesReportingService or YourPersistenceTechSalesReportingService), or you can re-use the already created repositories.

like image 27
rascio Avatar answered Jan 28 '26 17:01

rascio



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!