避免在c#工厂方法中使用多个if语句
本文关键字:if 语句 工厂 方法 | 更新日期: 2023-09-27 18:05:41
我有C# application
,在NoSQL database
中存储数据。该应用程序有一个存储库类,它使用一系列对象将数据从NoSQL形式转换为c#模型使用的数据,反之亦然(本质上是ORM的一种形式)。这些对象实现一个converter
接口,并且每个对象在一个特定的data type (string, bool, etc)
上工作。在内部,它们使用反射来执行转换。这些对象的实例由返回给定类型对象的方法创建。当前的逻辑看起来像下面这样:
if(type == typeof(string)
return new StringConverter(...);
if(type == typeof(int) || type == typeof(uint))
return new IntegerConverter(...);
... // and so on
然而,所有这些if
语句都困扰着我。我知道我可以做一些事情,比如创建一个字典来映射类型到创建方法,但我不确定这是否会导致更易读,易于维护/扩展的代码(?)。如果需要创建类型抽象,最好的方法是什么?欢迎提出任何建议。非常感谢。
理想情况下,嵌套的if-statements
是您想要避免的。我引用了微软的完整代码书。我们的想法是,当你设置了3个关卡时,维护代码的开发人员或你作为开发人员的注意力就会急剧减少。在您的情况下,如果您的逻辑必须硬编码,那么就没有办法避免使用if语句序列。然而,一个聪明的方法是遵循工厂设计模式。《四人帮》
您应该将if代码导出到一个工厂类。
正如您在这里看到的,工厂是一个GoF模式,它产生不同种类的物体。
在工厂类中,这个数量的int类型是可以的。
你应该只避免嵌套if语句,它们使你的代码不可读
考虑到可读性,您应该选择
switch(type.FullName){
case(typeof(int).FullName) => //your logic
...
}
switch-case-Statement是比If-Else更可读的代码,而且速度更快。你可以在这里阅读更多信息:
对于少数项目,差异很小。如果你有很多东西,你一定要使用开关。
如果一个开关包含多于5个项目,则使用a来实现查找表或散列表。这意味着所有的项目都是相同的访问时间,与if:s列表相比,最后一项花费很多时间更多的时间到达,因为它必须评估每个先前的条件第一。
和其他人已经说过,外包你的switch-case
到一个工厂类。
我相信您将类型映射到字典的想法将是您最好的选择,因为这实现了策略模式,并且本身非常具有表现力。
var converterStrategies = new Dictionary<Object, IConverter>();
converterStrategies.Add(typeOf(string), new StringConverter(...));
然后在传递引用类型时使用TryGetValue。
您可以考虑将此字典作为类的私有成员,并在包含类的初始化时填充它。
Gary McLean Hall在他的书《Adaptive Code via c#》中演示了这个模式,它在这种情况下给了我很大的帮助!