Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 设计模式以删除多个带有相关对象的if/else子句_C#_Design Patterns - Fatal编程技术网

C# 设计模式以删除多个带有相关对象的if/else子句

C# 设计模式以删除多个带有相关对象的if/else子句,c#,design-patterns,C#,Design Patterns,我继承了以下(糟糕的)代码,我想知道如何最好地重构它 代码库中到处都有大型if/else子句,其中一个类似于以下内容: public class BaseResultItem { public int Property1 { get; set; } } public class ResultItem1 : BaseResultItem { public int Property2 { get; set; } } public class ResultItem2 : BaseR

我继承了以下(糟糕的)代码,我想知道如何最好地重构它

代码库中到处都有大型if/else子句,其中一个类似于以下内容:

public class BaseResultItem
{
    public int Property1 { get; set; }
}

public class ResultItem1 : BaseResultItem
{
    public int Property2 { get; set; }
}

public class ResultItem2 : BaseResultItem
{
    public int Property3 { get; set; }
}

public class BaseHistoryItem
{
    public int Property1 { get; set; }
}

public class HistoryItem1 : BaseHistoryItem
{
    public int Property2 { get; set; }
}

public class HistoryItem2 : BaseHistoryItem
{
    public int Property3 { get; set; }
}

public class HistoryBuilder
{
    public BaseHistoryItem BuildHistory(BaseResultItem result)
    {
        BaseHistoryItem history = new BaseHistoryItem            
        {
            Property1 = result.Property1
        };

        if (result is ResultItem1)
        {
            ((HistoryItem1)history).Property2 = ((ResultItem1)result).Property2;
        }
        else if (result is ResultItem2)
        {
            ((HistoryItem2)history).Property3 = ((ResultItem2)result).Property3;
        }

        return history;
    }
}
请注意,这是一个简化的示例,实际代码中涉及更多的类。到处都有类似的if/else条款

我一直在看抽象工厂模式,但我有一些问题


基本上,我假设为了避免if/else问题,我需要传递实际的dervied类型。因此BuildHistory不应该使用基类型,也许应该有多个方法,每个派生类型一个?

一般的“设计模式”只是使用面向对象的多态性,而不是类型检查。因此:BaseResultItem中的BuildHistory方法被子体覆盖


任何检查对象具体类型的代码(在重构意义上)。支持不同类型的不同行为是OO的意义所在

使用多态性删除类型检查

if (result is ResultItem1)
{
    ((HistoryItem1)history).Property2 = ((ResultItem1)result).Property2;
}
然后变得像

result.addToHistory( history );
如果出于某种原因,您不想将逻辑分散在item类中,请查看。在本例中,您有如下情况:

public class Visitor {
     History history;
     public visit ( ResultItem1 item )  { ... }
     public visit ( ResultItem2 item )  { ... }
     ...
}

public class ResultItem1 {
     public accept( Visitor v ) { v.visit( this ); }
}
访客中的双重分派删除了类型检查,这稍微更优雅一些


我不太明白各种各样的历史是如何与各种各样的物品联系在一起的。因此,这只是一个可能遵循的方向的草图。

如果您不能将DTO类更改为,那么您可以尝试将HistoryBuilder子类化,以处理不同的子类。然后使用适当的HistoryBuilderX从ResultItem创建HistoryItem。然后问题是如何为提供的ResultItem获取适当的HistoryBuilderX

尽管如此,如果不能更改BaseResultItem类以包含GetBuilder函数,则需要使用一些if..else if。。用于检查ResultItems的类类型的构造


或者创建一个注册表,其中每个ResultItem类都使用其相应的HistoryBuilderX类注册。但这可能有些过分。

结果类和历史类只是DTO。任何逻辑都需要在单独的生成器类中。DTO和构建器之间的关系很重要。是否使用new显式创建BaseHistoryItem,然后将其强制转换为HistoryItem1和HistoryItem2?我不明白。你最好使用访客设计模式