我正在尝试确定用于业务密钥验证Web服务的最佳设计模式。基本逻辑流程编码如下。该程序将采用一个参数并使用一个字段来帮助确定在搜索可以找到此业务密钥的多个系统时所采用的路径。首先搜索System1,如果未找到,则搜索System2和System3。 System1搜索逻辑取决于传递给原始验证方法的参数中的字段。
我不确定使用哪种设计模式。看起来像命令,责任链,模板方法都可以在这里使用。
通过以下实施,我发现了以下问题:
如果找不到业务密钥,每个SearchSystemX方法需要知道返回null,以便“控制”方法将继续搜索其他系统。
每个SearchSystemX必须知道如何填充业务对象,目前只是由一个简单的原始字符串实现,但仅限于此。
请让我知道你的想法。
public string Validate (string parms) {
string returnValue = null;
returnValue = SearchSystem1(parms);
if (returnValue == null) {
returnValue = SearchSystem2(parms);
if (returnValue != null) {
returnValue = SearchSystem3(parms);
}
else if (returnValue == null) {
if (parms == "Criteria1") {
returnValue = SearchSystem4(parms);
if (returnValue == null) {
throw new ApplicationException("ID Invalid");
}
}
else if (parms == "Criteria2") {
throw new ApplicationException("ID Invalid");
}
}
}
return returnValue;
private string SearchSystem1 (string parms) {
string returnValue = null;
if (parms == "Criteria1") {
returnValue = SearchSystem1UsingColumn1(parms);
}
else if (parms == "Criteria2") {
returnValue = SearchSystem1UsingColumn2(parms);
if (returnValue == null) {
returnValue = SearchSystem1UsingColumn4(parms);
}
}
if (returnValue != null) {
returnValue = FetchXYCoordinate(parms);
}
return returnValue;
}
谢谢!
答案 0 :(得分:3)
每个处理对象都包含一组逻辑,用于描述它可以处理的命令对象的类型,以及如何将它不能传递给链中的下一个处理对象
因此,您定义并抽象SearchSystem
(或SystemSearch)并添加如下子类:
class SearchSystem
{
//link to the next in the chain
SearchSystem next;
// Basic search, If cannot handle forward to the next.
public Result search( Criteria c )
{
Result r = doSearch( c );
if( r != null )
{
return r;
}
return next.search( c );
}
// subclass specific system search
abstract Result doSearch( Criteria c );
}
class SearchSystemOne: SearchSystem
{
Result doSearch( Criteria c )
{
// do some system 1 speficif stuff
// and return either and instance or null
}
}
class SearchSystemTwo: SearchSystem
{
Result doSearch( Criteria c )
{
// do some system 2 speficif stuff
// and return either and instance or null
}
}
.... etc etc.
// End of the chain
class SearchSystemOver: SearchSystem
{
public Result search( Criteria c )
{
throw new ApplicationException("Criteria not foud", c );
}
Result doSearch( Criteria c )
{
// didn't we throw exception already?
}
}
实例化
SearchSystem one = new SearchSystemOne();
SearchSystem two = new SearchSystemTwo();
SearchSystem three = new SearchSystemThree();
SearchSystem four = new SearchSystemFour();
SearchSystem over = new SearchSystemOver();
构建链
one.next = two;
two.next = three;
three.next = four;
four.next = over;
最后搜索它。
SearchSystem searcher = one;
searcher.search( Criteria.addName("Oscar").addLastName("Reyes"));
答案 1 :(得分:1)
可能是Strategy Pattern。
它允许您抽象出用于执行逻辑的算法,将它们封装在自己的对象中,然后在整个应用程序中交替使用它们(允许调用者定义要使用的算法)。
答案 2 :(得分:1)
我可能会通过为搜索系统定义一个接口来使用策略模式:
public interface ISearchStrategy
{
string Search(string criteria);
}
然后将它们传递给validate方法(虽然验证类可以从其他地方获取它们。)
public string Validate(string parms, IEnumerable<ISearchStrategy> searchStrategies)
{
string returnValue = null;
foreach(var strategy in searchStrategies)
{
if(returnValue == null)
{
returnValue = strategy.Search(parms);
}
}
if(returnValue == null) throw new ApplicationException("ID invalid");
return returnValue;
}
答案 3 :(得分:1)
在不了解您的域名的情况下,我只能建议稍微调整一下。首先是使用guard clauses。
此外,您还提到了SearchSystems如何知道如何构建业务对象。我会确保SearchSystems可以被多态地处理(这样你就有了重构策略或某种依赖注入的途径)。另外,我赞成在一系列SearchSystem方法上使用SystemSearcher。然后我会向SearchSystems注入一个业务对象工厂。我还会用TryXXX语义来设计行为。
public interface ISearchSystem
{
bool TryGet(string parms, out string businessObject);
}
public class System1Searcher : ISearchSystem
{
public System1Searcher(BusinessObjectFactory factory) { _factory = factory; }
private field BusinessObjectFactory _factory;
public bool TryGet(string parms, out string businessObject)
{
// do internal logic
return _factory.Create(string stuff);
}
}
public class Service
{
// is "Validate" the correct metaphor for this logic?
public string Validate(string parms)
{
string returnValue = null;
if (new System1Searcher().TryGet(parms, out returnValue)
return returnValue;
if (new System2Searcher().TryGet(parms, out returnValue)
return returnValue;
if (new System3Searcher().TryGet(parms, out returnValue)
return returnValue;
if (new System4Searcher().TryGet(parms, out returnValue)
return returnValue;
// this message should be written in terms of the logic of this method
// such as "Parameters invalid"
throw new ApplicationException("ID Invalid");
}
}