Я хочу провести рефакторинг моего кода с неприятным запахом, используя полиморфизм. это проблема удаления операторов if - PullRequest
0 голосов
/ 29 февраля 2012

Я разработчик приложений для iOS.Я застрял в какой-то проблеме рефакторинга при удалении неприятных запахов в моем коде.это так.

Мой проект использует данные XML,

<resource>
   <item type='textbox' ... />
   <item type='checkbox' ... />
   <item type='selectbox' ... />
</resource>

, и я использую его по этому коду.

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», чтобы специализировать ее на Textbox, Checkbox или Selectbox.

Есть ли способ удалить эти операторы «if» и рефакторинг?Любые предложения приветствуются.И я очень ценю, что вы поделились этим.

Спасибо,

MK

1 Ответ

2 голосов
/ 29 февраля 2012

@ предложение антициклопа полезно.Вам не нужно избавляться от ifs, но вы можете сделать код намного проще.Вот несколько вещей, которые вы должны сделать:

  1. Извлечь код внутри цикла for в свой собственный метод, например, itemForItemElement:.

  2. Создайте метод itemClassForItemElementType:.Этот метод значительно упростит реализацию itemForItemElement:, но все еще использует ifs.

  3. При необходимости обновите itemClassForItemElementType:, чтобы он возвращал класс с использованием NSDictionary.В этом нет необходимости, но это может быть тем, что вам нужно сделать, если вы хотите, чтобы отображение было динамическим, скажем, если вы создадите его во внешнем файле.Здесь вы должны использовать код, предложенный в ссылке из @ anticyclope.

Цепочка ifs - это то, чего следует избегать, если вы дублируете логику в нескольких местах, но если вы только делаете этоесли все не так плохо.

Обязательно проведите юнит-тесты для всех этих изменений.

...