How can I develop common search criteria?

Suppose we have an application (on the server) that has a set of resources: these resources are indexed by name through a dictionary, that is, Dictionary<string, Resource> resources .

The client sends the names of one or more resources to the server (using WCF) (for example, it sends a List<string> ). There can only be a subset of resources on the server requested by the client, so when the server receives this list, it sends back a list containing only the names of the resources found.

I would like to summarize the search criteria that the client sends to the server so that in the future it will be easy to expand the application (both on the client side and on the server side) with more complex search criteria. To achieve this, I decided to create the ISearchCriteria interface, so the client must send an object of the class that implements this interface.

 public interface ISearchCriteria { // the names of the resources which match with the search criteria ICollection<string> GetCompliantResources(); } 

However, it seems to me that this solution is not very correct, because the GetComplianceResources method should interact with the dictionary on the server, but the client should not know anything about this dictionary ... I could use a strategy template, linking each specific strategy with specific search criteria. In this way, control logic can be separated from data (i.e., Search Criteria).

UPDATE (strategy template and DTO)

 // Both on the server and on the client public interface ISearchCriteria { // empty } // Both on the server and on the client public class DefaultSearchCriteriaDTO : ISearchCriteria { List<string> ResourceNames { get; set; } List<int> OtherCriteria { get; set; } } // Both on the server and on the client public class MySearchCriteriaDTO : ISearchCriteria { string SearchString { get; set; } } // On the server. public interface IStrategy<T> : where T : ISearchCriteria { public List<string> Match(T criteria); } // On the server public class DefaultStrategy : IStrategy<T> where T : DefaultSearchCriteriaDTO { public List<string> Match(T criteria) { // search for resources and returns those found } } 
  • Is there any design pattern for this purpose?
  • Are there any better alternatives?
+4
source share
4 answers

Instead of requiring the client to send you the class that you expect to do, ask them to send you POCO:

 public class SearchCriteria { List<string> ResourceNames { get; set; } // Add more properties here in the future as you identify additional criteria } 

When you add related POCO properties, people using an older version of your API can still work in their code if the binding protocol interprets the absence of the property so that it does not indicate that the property should not be set.

This object that you send to clients will not have any logic: it plays the role of a data transfer object. Your server is responsible for matching resource names with its internal dictionary to determine which of the provided resources is available.

Update

Looking at your intentional use of a strategy template, I think that you are excessive. First, I donโ€™t even know if WCF can communicate with different types of parameters depending on what type of object the user is trying to send: there are at least some bindings (for example, JSON) that will not allow this. Even if this is possible, this approach seems wrong and that the empty interface creates a serious smell of code. I would say, keep your service interface intuitive and simple, with well-defined methods and types of parameters.

If you expect users to search by different โ€œstrategiesโ€, each of which will require a different set of parameters, create a different method for each potential search algorithm ( SearchByResourceNames(List<string resourceNames) , SearchByDomain(int domainId) , etc.) ..).

On the other hand, if you want the user to be able to mix and match different types of criteria, just use the SearchCriteria DTO and let the client fill in any properties that they want to fulfill.

+4
source

Honestly, I would not have implemented it until there was a need for it.

As of now, you are going to program around situations that can never exist. How do you know when you're done?

Note: YAGNI .

+7
source

I would create an ISearchCriteria using a method that returns a bool and accepts a Resource as parameter. The ISearchCriteria method is called for each resource and returns true if you want the resource to be included in the return list. You can also implement this using delegates instead of interfaces, for example:

 public delegate bool IsValidResource(Resource currentResource); 
0
source

See if Criteria Pattern @Wikipedia can help you! This software template is based on a specification template.

0
source

Source: https://habr.com/ru/post/1398680/


All Articles