I'm currently working on a project that I came into several years after it was built. The code is mostly procedural with a few objects that act more like buckets of functions than anything else. I want to start fixing it up by consolidating the database access and external API calls into domain models.I have the general idea down, but I don't know how to handle getting lists of my data when I have multiple filters. Having methods called $HelpRequestMapper->getById($id) work fine, but what do I do when the user wants to do multiple filters?Should I have methods for each possible case? Ie, $HelpRequestMapper->getByCompanyAndUserAssignedToAndQueueAndStatusAndPriorityAndSearchString($company_id, $user_id, $queue_id, $status, $priority, $search_string) This seems like it would get unwieldy very fast and not be much better than what we have now.Should I pass in an array/object and build a query from it using something like $HelpRequestMapper->getMultiple($array_of_options) that does some magical query building stuff to get the data I want?Should I do something else?Thanks
designing domain model that can handle large number of data filters?
design patterns;object oriented design
It depends a bit on the implementation of the filter, but you could look into the Decorator Pattern and Strategy Pattern and see if they are of use to you.You could solve this by creating an abstract Filter class with a filter-method that takes a list of objects and returns a list of objects. Each type of filter (CompanyFilter, UserAssignedFilter, QueueFilter...) would be a separate class that extends filter. When creating the filter you would pass the filter criteria in the constructor, and the implementation of the filter-method would take the objects passed to it and only return the ones matching the filter.You could then have a RequestQuery that you can push filters onto which fetches the data, runs the data through all the filters and returns the result.Quick demo in C#public class MyObject{    public string Company { get; set; }    public string UserAssignedTo { get; set; }}public abstract class Filter{    public abstract IEnumerable<MyObject> Apply(IList<MyObject> list);}public class CompanyFilter : Filter{    private string _companyToFilter;    public CompanyFilter(string companyToFilter)    {         _companyToFilter = companyToFilter;    }    public override IEnumerable<MyObject> Apply(IList<MyObject> list)    {        return list.Where(x => x.Company == _companyToFilter);    }}public class UserAssignedToFilter: Filter{    private string _userToFilter;    public UserAssignedToFilter(string userToFilter)    {         _userToFilter = userToFilter;    }    public override IEnumerable<MyObject> Apply(IList<MyObject> list)    {        return list.Where(x => x.UserAssignedTo == _userToFilter);    }}public class RequestQuery{    public IEnumerable<MyObject> FindData(IList<Filter> filtersToApply)    {        IList<MyObject> data = null; //fetch data somewhere        foreach(var filter in filtersToApply)        {            data = filter.Apply(data);        }        return data;    }}