首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#中基于多输入的动作处理模式设计

C#中基于多输入的动作处理模式设计
EN

Stack Overflow用户
提问于 2017-12-09 04:39:19
回答 5查看 1.8K关注 0票数 0

假设商业模式中有两个属性,例如,国家和类型,我们需要为每个国家和每种类型处理不同的逻辑。

代码语言:javascript
复制
if(country=="us"){
    if(type=="type1){
        usType1Handler.Execute();
    }
    else if(type=="type2"){
        usType2Handler.Execute();
    }
    .
    .
    .
    else{
        usDefaultHandler.Execute();
    }
}
else if(country=="uk"){
    if(type=="type1){
        ukType1Handler.Execute();
    }
    else if(type=="type2"){
        ukType2Handler.Execute();
    }
    .
    .
    .
    else{
        ukDefaultHandler.Execute();
    }
}
else{
    throw exception("unknown country");
}

将有大量的if混合和匹配每个具体的实施具体针对每个国家类型的组合。有什么设计模式可以用来处理这个场景吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2017-12-10 03:34:35

这很简单。只需将所有处理程序添加到字典中,其中键是Country/Type组合,值是处理程序函数。

创建字典并添加所有处理程序:

代码语言:javascript
复制
Dictionary<string, Handler> processor = new Dictionary<string, Handler>()
{
    { "us,type1", usType1Handler },
    { "us,type2", usType2Handler },
    { "us", usDefaultType2Handler },
    { "uk,type1", ukType1Handler },
}
//...etc

然后,只需搜索字典并执行:

代码语言:javascript
复制
string key = String.Join(",", new[] { country, type })
bool success = processor.TryGetValue(key, out Handler handler);
if (success)
{
    handler.Execute();
}
else
{
    throw new Exception("unknown country");
}
票数 2
EN

Stack Overflow用户

发布于 2017-12-09 10:51:13

您可以使用两种模式的组合来改善这种情况,Chain of Responsibility && Strategy Pattern

  1. Strategy Pattern --这个模式将帮助你解决这个国家的条件问题。您必须为我们系统中的每个国家创建一个AbstractCountryStrategy +一个具体的Strategy类。

Strategy类将封装相当简单的代码行(使用其他模式Chain of Responsibility的行)

代码语言:javascript
复制
class USCountryStrategy {

    public void execute(type) {
        new USCountryTypeAHandler()
              .setNext(new USCountryTypeBHandler()
              .setNext(...))
           .executeBasedOn(type)
    }
}
  1. Chain of Responsibility --这个模式将帮助您解决类型的条件(但是对于这个模式,您仍然需要使用一个小的if/else来检查当前处理程序是否附加了下一个处理程序)。

总体思路:对于每种类型,您将有一个小类来检查它是否能够解决您的请求.类似于:

代码语言:javascript
复制
if(paramType.equals(this.type)
    this.execute();
    // if I can solve your request than I'll execute it myself
else if(this.next) 
    this.next.executeBasedOn(paramType);
    // if I can't solve your request than I'll pass it on to the next handler
else 
    throw RuntimeException(...)
    // nobody can solve your request (because I can't && this.next is null)

这是有用的,还是我只是增加了我的代码源代码的复杂性?

是的,当您在代码中切换时,它是有用的,请记住,很快您将不得不更改这个函数/类。一个开关是不可扩展的,很难维护,变得非常复杂快速(“意大利面代码”),您可能需要在您的代码库中使用它两次。

有关更好和完整的示例,请参见https://github.com/kamranahmedse/design-patterns-for-humans

票数 2
EN

Stack Overflow用户

发布于 2017-12-09 05:50:47

在本例中,我建议使用嵌套开关:

代码语言:javascript
复制
switch (country)
{
    case "us":
        switch (type)
        {
            case "type1":
                usType1Handler.Execute();
                break;
            case "type2":
                usType2Handler.Execute();
                break;
            default:
                break;
        }
        break;
    case "uk":
        switch (type)
        {
            case "type1":
                ukType1Handler.Execute();
                break;
            case "type2":
                ukType2Handler.Execute();
                break;
            default:
                break;
        }
        break;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47725365

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档