C# 设计模式以删除多个带有相关对象的if/else子句
我继承了以下(糟糕的)代码,我想知道如何最好地重构它 代码库中到处都有大型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
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?我不明白。你最好使用访客设计模式