Оптимизация метода с помощью логического флага - PullRequest
0 голосов
/ 26 января 2012

У меня есть метод, целью которого является получение элементов коллекции.

Коллекция может содержать различные предметы, например, ручки, карандаши и бумаги.

1-й параметр позволяет мне указать методу, чтобы он извлекал только те элементы itemTypes, которые я передаю (например, просто ручки и карандаши).

2-й параметр помечает функцию для использования типов элементов коллекции по умолчанию, вместо этого.

getCollectionItems($itemTypes,$useCollectionDefaultItemTypes) {
    foreach() {
        foreach() {
            foreach() {
               // lots of code...

               if($useCollectionDefaultItemTypes) {
                 // get collection's items using collection->itemTypes
               }
               else {
                 // get collection's items using $itemTypes
               }

               // lots of code...
            }
        }    
    }
}

Что странно, так это то, что если я установлю для $ useCollectionDefaultItemTypes значение true, функции не нужно будет использовать первый параметр.Я рассматривал возможность рефакторинга этого метода на два, таких как:

getCollectionItems($itemTypes); // get the items using $itemTypes
getCollectionItems(); // get the items using default settings

Проблема заключается в том, что у методов будет много дублирующегося кода, за исключением области оператора if.

Есть ли лучшийспособ оптимизировать это?

Ответы [ 3 ]

1 голос
/ 26 января 2012

Обычно плохая идея писать методы, использующие такие флаги.Я видел, что написано в нескольких местах ( здесь в # 16, дядя Боб здесь и в других местах).Это делает метод трудным для понимания, чтения и рефакторинга.

Альтернативным вариантом будет использование замыканий .Ваш код может выглядеть примерно так:

$specificWayOfProcessing = function($a) {
  //do something with each $a
};

getCollectionItems($processer) {
  foreach() {
    foreach() {
      foreach() {
        // lots of code...
        $processor(...)
        // lots of code...
      }
    }    
  }
}

getCollectionItems($specificWayOfProcessing);

Этот дизайн лучше, потому что

  1. Он более гибкий.Что происходит, когда вам нужно выбирать между тремя разными вещами?
  2. Теперь вы можете намного проще протестировать код внутри цикла
  3. Теперь его легче читать, потому что последняя строка говорит вам, что«получают элементы коллекции, используя особый способ обработки» - это звучит как английское предложение.
1 голос
/ 26 января 2012

Да, есть лучший способ сделать это - хотя этот вопрос не вопрос оптимизации, а вопрос стиля.(Дублированный код мало влияет на производительность!)

Самый простой способ реализовать это в соответствии с вашей первоначальной идеей - это сделать форму без аргументов getCollectionItems(), определить аргументы по умолчанию, а затем вызватьего версия, требующая аргумента:

getCollectionItems($itemTypes) {
    foreach() {
        foreach() {
            foreach() {
                // lots of code...
                // get collection's items using $itemTypes
            }
            // lots of code...
        }
    }    
}

getCollectionItems() {
    getCollectionItems(collection->itemTypes)
}

В зависимости от того, какой язык вы используете, вы можете даже свернуть их в одно определение функции с аргументом по умолчанию:

getCollectionItems($itemTypes = collection->itemTypes) {
    foreach() {
        foreach() {
            foreach() {
                // lots of code...
                // get collection's items using $itemTypes
            }
            // lots of code...
        }
    }    
}

Преимущество состоит в том, что вы четко выражаете свою первоначальную идею: вы используете $itemTypes, если он указан, и collection->itemTypes, если нет.

(Это, конечно, предполагает, что вы говоритео одной «коллекции», вместо того, чтобы одна из этих итераций foreach выполняла итерации по коллекциям. Если да, идея использовать значение null является хорошей.)

1 голос
/ 26 января 2012

Передайте $itemTypes как null, когда вы его не используете.Попросите if выписку проверить, если $itemTypes === null;если это так, используйте настройки по умолчанию.

Если это php, который, как я полагаю, есть, вы можете сделать подпись вашего метода function getCollectionItems($itemTypes = null), а затем вы можете вызвать getCollectionItems(), и он будет вызываться так, как если бы вы набрали getCollectionItems(null).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...