假设我们有一个具有一组资源的应用程序(在服务器上):这些资源通过字典按名称索引,即Dictionary<string, Resource> resources
。
客户端向服务器(使用WCF)发送一个或多个资源的名称(例如,它发送List<string>
)。在服务器上,客户端可能只有一部分资源,因此当服务器收到此列表时,它会发回一个仅包含已找到资源名称的列表。
我想概括客户端发送到服务器的搜索条件,以便将来很容易使用更复杂的搜索条件扩展应用程序(客户端和服务器端)。
为了实现这个目标,我想创建ISearchCriteria
接口,所以客户端应该发送一个实现这个接口的类的对象。
public interface ISearchCriteria
{
// the names of the resources which match with the search criteria
ICollection<string> GetCompliantResources();
}
然而在我看来,这个解决方案不是很正确,因为GetComplianceResources
方法应该与服务器上的字典交互,但是客户端不应该知道关于这个字典的任何内容...我可能会使用策略模式,将每个具体策略与特定搜索条件相关联。这样就可以将控制逻辑与数据分开(即搜索标准)。
更新(策略模式和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
}
}
答案 0 :(得分:7)
答案 1 :(得分:4)
不要让客户向您发送您希望做的事情的课程,让他们发给您一个POCO:
public class SearchCriteria
{
List<string> ResourceNames { get; set; }
// Add more properties here in the future as you identify additional criteria
}
当你向绑定的POCO添加属性时,如果绑定协议解释缺少属性意味着不应该设置属性,则使用旧版API的人仍然可以使用其代码。
客户端发送给您的此对象将没有任何逻辑:它扮演数据传输对象的角色。您的服务器负责将给定的资源名称与其内部字典进行比较,以确定哪些资源可用。
看看你对战略模式的预期用途,我认为你过分复杂了。首先,我甚至不知道WCF是否可以绑定到不同类型的参数,具体取决于用户尝试发送的对象类型:肯定至少有一些绑定(例如JSON)不允许它。即使有可能,这种方法感觉错误,并且 empty interface 正在产生严重的代码异味。我会说,使用定义明确的方法和参数类型,保持服务界面清晰简洁。
如果您希望用户通过各种不同的“策略”进行搜索,每个策略都需要一组不同的参数,请为每种潜在的搜索算法创建不同的方法(SearchByResourceNames(List<string resourceNames)
,{{1等等。)。
另一方面,如果您希望用户能够混合和匹配各种类型的条件,只需使用SearchByDomain(int domainId)
DTO,让客户端填充他们想要搜索的属性。
答案 2 :(得分:0)
我使用返回bool并接受Resource作为参数的方法创建ISearchCriteria。为每个资源调用ISearchCriteria的方法,如果希望资源包含在返回列表中,则返回true。 您也可以使用委托而不是接口来实现它,例如:
public delegate bool IsValidResource(Resource currentResource);
答案 3 :(得分:0)
查看Criteria Pattern @ Wikipedia是否可以为您提供帮助! 这是一种基于规范模式的软件模式。