Эффекты метода сцепления - PullRequest
7 голосов
/ 29 сентября 2010

Я знаю преимущества объединения в PHP, но допустим, что у нас следующая ситуация

$Mail = new MailClass("mail")
        ->SetFrom("X")
        ->SetTo("X")
        ->SetSubject("X")
        ->AddRecipient("X")
        ->AddRecipient("X")
        ->AddRecipient("X")
        ->AddRecipient("X")
        ->AddRecipient("X")
        ->AddRecipient("X")
        ->Send();

Есть ли проблемы с возвратом и повторным использованием объекта снова и снова, такие как скорость или несоблюдение лучших практик

Также, если вы новичок в Fluent-Interface: Martin Fowler по интерфейсам Fluent-интерфейсов

Я полностью понимаю, что не имеет , который можно запрограммировать таким образом, и может обрабатываться так:

$Mail = new MailClass("mail");
$Mail->AddRecipien(
    array(/*.....*/)
);
$Mail->SetFrom("X");
$Mail->SetTo("X");
$Mail->SetSubject("X");
$Mail->Send();

, но давайте скажем, что у меня есть такой объект:

$Order = new Order()
         ->With(22,'TAL')
         ->With(38,'HPK')->Skippable()
         ->With(2,'LGV')
         ->Priority();

Обратите внимание на ->With(38,'HPK')->Skippable(), это прекрасный пример Pro для этого типа программирования

Ответы [ 4 ]

5 голосов
/ 29 сентября 2010

Если вам нужно проверить что-то, я думаю, что имеет смысл проверить это в самом методе AddRecipient , но производительность должна быть примерно такой же.И я не знаю каких-либо общих недостатков использования метода цепочки.

2 голосов
/ 29 сентября 2010

Невозможно выполнить цепочку непосредственно из экземпляра класса:

$Mail = new MailClass("mail") 
            ->SetFrom("X")
            ->SetTo("Y");

сначала необходимо создать экземпляр, а затем создать цепочку для экземпляра объекта:

$Mail = new MailClass("mail") ;
$Mail->SetFrom("X")
     ->SetTo("Y");

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

Неустранимая ошибка: вызовфункция-член SetSubject () для необъекта в C: \ xampp \ htdocs \ oChainTest.php в строке 23

если вы генерируете исключения, вы можете заключить цепочку в try ... catch

$Mail = new MailClass("mail");
try {
    $Mail->SetFrom("X")
        ->SetTo("Y")
        ->SetSubject("Z");
} catch (Exception $e) {
    echo $e->getMessage();
}

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

1 голос
/ 29 сентября 2010

РЕДАКТИРОВАТЬ: Обновлен ответ, чтобы соответствовать вопросу
Вызовы функций выполняются медленнее, чем циклы, то есть, например, создание цепочки, например, метода addRecipient(), значительно снижает производительность по сравнению с вызовом метода addRecipients(), который принимает массив, который затем обрабатывается в цикле.

Кроме того, более сложный метод, соединяющийся в цепочку с текущими API, может потребовать дополнительного учета данных, связанных с последним вызванным методом, чтобы следующий вызов мог продолжить работу с этими данными, поскольку все методы возвращают один и тот же объект, на котором построена цепочка , Давайте посмотрим на ваш пример:

...
->With(22, 'TAL')
->With(38, 'HPK')->Skippable()
->With(2, 'LGV')
...

Это требует, чтобы вы помнили, что Skippable() должен применяться к (38, 'HPK') вместо (22, 'TAL').

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

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

Однако обычно существуют функции, которые дают другие значения, отличные от объекта, которому они принадлежат (например, те, которые возвращают статус объекта и методов доступа). Важно, чтобы пользователь вашего API мог определять, какие функции являются цепочечными, а какие нет, и при этом не нужно обращаться к документации каждый раз, когда он встречает новый метод (например, руководство, которое говорит, что все мутаторы и только мутаторы поддерживают сцепление).


Ответ на оригинальный вопрос:

[...] Проблемы с цепочкой, которые у меня возникают, заключаются в том, что вы не можете выполнить дополнительную проверку [...]

Альтернативно, реализуйте специальный метод проверки, который вы вызываете после установки всех свойств, и он возвращает вам массив ошибок проверки (которые могут быть простыми строками или объектами, например с именем ValidationFailure).

0 голосов
/ 29 сентября 2010

Это обоюдоострый меч.

Хорошая сторона?Это чище, чем повторное обращение к классу, и хотя это в основном просто изменение синтаксиса, оно немного ускорит обработку.Было бы предпочтительнее зацикливать этот вид цепочки, чем зацикливать каждый вызов в длинной форме.

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

  1. Предварительная проверка вашей информации.
  2. Предварительная авторизация пользователей.

Я не вижу проблем с объединением этих методов в цикл, с производительностью.

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