关于iphone:我想用多态来重构我的恶臭代码。

I want to do refactoring on my bad smell code using polymorphism. it's a removing 'if' statements issue

我是iOS应用程序开发人员。在清除代码中的臭味时,我遇到了一些重构问题。就是这样。

我的项目使用XML数据,

1
2
3
4
5
<resource>
   <item type='textbox' ... />
   <item type='checkbox' ... />
   <item type='selectbox' ... />
</resource>

我用这个代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Item *item = nil;
for (Element *itemElement in resourceChilds)
{
   ...
   if ([[itemElement valueForAttributeNamed:@"type"] isEqualToString:@"textbox"])
   {
      item = [[Textbox alloc] initWithProperty:itemAttributes];
      ...
   }
   else if ([[itemElement valueForAttributeNamed:@"type"] isEqualToString:@"checkbox"])
   {
      item = [[Checkbox alloc] initWithProperty:itemAttributes];
      ...
   }
   else if ([[itemElement valueForAttributeNamed:@"type"] isEqualToString:@"selectbox"])
   {
      item = [[Selectbox alloc] initWithProperty:itemAttributes];
      ...
   }
   ...
}

"item"类是"textbox"、"checkbox"和"selectbox"类的父类。

"itemAttributes"对象是nsDictionary的一个实例。

正如您在上面通过"initWithProperty:itemAttributes"看到的,我已经将"type"属性值提供给了"item"实例。我认为可以在"item"实例中使用此信息将其专门化为文本框、复选框或SelectBox。

有没有办法删除这些"if"语句并重构它?欢迎提出任何建议。我真的很感激你和我分享你的时间。

谢谢,

迈克科尔斯


@反气旋的建议是有帮助的。您不需要去掉IFS,但是您可以使代码简单得多。以下是您应该做的一些事情:

  • 将for循环中的代码提取到自己的方法中,类似于itemForItemElement:

  • 创建itemClassForItemElementType:方法。这种方法将大大简化itemForItemElement:的实现,但仍使用ifs。

  • 或者更新itemClassForItemElementType:以使用nsdictionary返回类。这是不必要的,但是如果您希望映射是动态的,也可以这样做,比如在外部文件中创建一个映射。这里您将使用@anticyclope链接中建议的代码。

  • 如果你将逻辑复制到多个地方,一系列的ifs是要避免的,但是如果你只复制一次它就不会那么糟糕了。

    确保对所有这些更改进行单元测试。