Плохо ли иметь функции с большим количеством параметров? Какая альтернатива? - PullRequest
4 голосов
/ 08 февраля 2011

У меня есть функция поиска, которая запрашивает базу данных и имеет ~ 15 необязательных параметров.Очевидно, что это не красиво, и называть это немного беспорядком.PHP не допускает перегрузки методов, поэтому я только что создал огромные сигнатуры функций.

В других местах я видел предложения, такие как создание класса параметров: Недостатки использования большого количества параметров

Но это кажется слишком тяжелым.Я мог бы передать ассоциативный массив, но, хотя это уменьшает количество параметров, я считаю, что за ним труднее следовать, поскольку нет встроенной документации, в которой указано, какие ключи должны существовать в массиве.

Существуют ли другиеспособ справиться с этим изящно?Обычно в других языках у меня был бы действительно уродливый метод private, который принимает до дюжины параметров, а затем создавал бы public методы с тем же именем, которые принимают подмножество этих параметров и внутренне вызывают закрытый метод.

Ответы [ 6 ]

4 голосов
/ 08 февраля 2011

В PHP вы можете использовать ассоциативный массив:

someFunction(array(
    "a" => 3243,
    "b" => 2354,
    "c" => 33453,
    "d" => 324353,
    "e" => 321243,
    "f" => 321243,
    "g" => 312243,
    "h" => 321243,
))

Или свойства объекта, для которого вызывается функция (если это имеет смысл). PHPMailer отправляет письма следующим образом:

// instantiate the class
$mailer = new PHPMailer();

// Set the subject
$mailer->Subject = 'This is a test';

// Body
$mailer->Body = 'This is a test of my mail system!';

// Add an address to send to.
$mailer->AddAddress('foo@host.com', 'Eric Rosebrock');

if(!$mailer->Send())
{
    echo 'There was a problem sending this mail!';
}

И у него есть много дополнительных параметров. Можно было бы также использовать метод с сотнями параметров, но это гораздо более читабельно.

РЕДАКТИРОВАТЬ: Эти решения также лучше поддерживают дополнительные параметры. В случае свойств это просто, в случае ассоциативного массива вы можете объединить массив с массивом значений по умолчанию.

2 голосов
/ 08 февраля 2011

Как правило, длинный список параметров представляет собой так называемый неприятный запах в коде, который можно удалить с помощью рефакторинга, называемого объектом параметра Introduce. См. это для справки.

Cheeres

1 голос
/ 08 февраля 2011

Проблема «слишком большого количества параметров», на мой взгляд, является лишь проявлением гораздо более глубокой лежащей в основе проблемы: плохой архитектуры. Если функция действительно нуждается во всех этих значениях параметров, велика вероятность, что она делает намного больше, чем должна.

Это должно быть напоминанием: "О, давайте пересмотрим не использование процедуры X для выполнения всего этого, а мысль о том, что действительно должно быть сделано X и что должно быть сделано Y и Z.

1 голос
/ 08 февраля 2011

Да, хорошее эмпирическое правило - иметь не более 3-4 параметров.Если вам нужно больше, чем обычно, вы должны использовать массив или объект в качестве одного из параметров.Но в некоторых случаях, если вы думаете, что вам действительно нужно больше параметров, тогда, конечно, почему бы и нет.Если это делает ваш код легким для понимания и использования, то почему бы и нет.

0 голосов
/ 08 февраля 2011

Было бы неплохо преобразовать вашу функцию в класс.Есть два основных преимущества:

  • Аргументы функции преобразуются в свойства и могут быть прокомментированы

  • Код функции, который я считаю довольно большим, можно разделитьв набор небольших частных методов

0 голосов
/ 08 февраля 2011

Вы можете создать класс, в котором параметры будут храниться в виде свойств, что позволит вам устанавливать каждое свойство по своему усмотрению, а затем создать метод, который использует эти свойства для запроса базы данных.Конструктор может установить значения по умолчанию для этих свойств.Это просто делает вызов немного проще.

$function = ClassFunction();
$function->arg1 = 'Some value.';
$function->arg2 = true;
$function->arg3 = 5;

$result = $function->call_method();    // This uses default values for any property not set.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...