#php #oop #design-patterns #anti-patterns
#php #ооп #шаблоны проектирования #антишаблоны
Вопрос:
Я много раз видел, как Zend Framework использует return $this;
шаблон стиль — и с моей точки зрения:
-
Pro: кажется, это совсем неплохо
шаблонстиль для объединения множества действий над одним объектом и сокращения вашего кода. -
Con: код выглядит немного странно, когда вы видите, что объект возвращает сам себя в методе, который выполняет что-то другое (например, установщик для некоторого свойства)
Это действительно хорошо шаблон практика или, может быть, анти-шаблонпрактика?
РЕДАКТИРОВАТЬ: ну, с моей стороны было немного чересчур называть это «шаблоном», спасибо всем, что указали мне правильное направление!
Комментарии:
1. Смотрите статью Мартина Фаулера о fluent interfaces . Я никогда не рассматривал это как антишаблон. Это работает очень хорошо для многих вещей. jQuery — еще один выдающийся интерфейс fluent.
2. это просто а стиль кодирования и своего рода синтаксический сахар, а не шаблон.
Ответ №1:
Возврат this
позволяет вам объединять вызовы в цепочку и устанавливать значения. Это очень полезно для настройки некоторого объекта (см. Fluent interface). Вы можете очень легко выразить то, что вы хотите (и вы можете использовать различные типы возвращаемых данных для достижения желаемого).
Ответ №2:
Я обнаружил, что цепочка методов полезна в обстоятельствах, когда это имеет смысл; например, для языка, зависящего от домена:
$query->select('*')->from('users')->where(array('user_id' => 1, 'verified' => 1));
Дело в том, что эти методы в void
любом случае будут возвращать только результаты, поэтому return $this
они просто функционируют как сокращенная версия написания:
$query->select('*'); $query->from('users'); $query->where(...);
Мы по-прежнему собираемся вызывать метод toSQL()
or execute()
, чтобы использовать данные, которыми мы заполнили наш объект.
На мой взгляд, это не антишаблон и может функционировать как законный, разумный метод заполнения объектов в правильных обстоятельствах.
Ответ №3:
Если вы имеете в виду «хорошую практику или плохую практику», вот мое мнение:
С положительной стороны, вы получаете некоторый синтаксический сахар.
С другой стороны, вы отказываетесь от значимых возвращаемых значений в пользу цепочки. Что на самом деле неосуществимо, потому что в конечном итоге вам придется иметь методы, которые возвращают что-то отличное от базового объекта, так что в итоге вы получите некоторые методы, которые можно использовать в цепочке, а некоторые — нет (пользователи ваших классов получают удовольствие, угадывая, какие из них какие.)
Или вы идете полным ходом и делаете все из них цепными, несмотря ни на что, но тогда вы оказываетесь в нелепых ситуациях, таких как возврат поддельного «пустого» объекта ради сохранения цепочки, и этот объект нужно протестировать на наличие какого-то непонятного свойства, чтобы определить, является ли он «настоящим» или просто звеном в цепочке.
Классическим примером является jQuery, который демонстрирует все симптомы: базовый объект пытается быть единственной базовой единицей данных во всем коде (все возвращает объект jQuery); поддельное тестирование объекта ( if (obj.length)
); плюс внутреннее противоречие, когда все еще необходимо нарушать цепочечность для методов, подобных getAttribute()
этому возвращающему string.
ИМХО, это ужасный беспорядок, который нужно создавать только ради этого кусочка синтаксического сахара.
Комментарии:
1. Примечание сбоку: такой подход привел к неестественным, плохим практикам при использовании jQuery. Например. вы ищете в #foo элементы с .bar, но не находите ни одного или даже не находите #foo. В большинстве случаев это означает, что у вас большая проблема, они, скорее всего, должны быть там. Случаи, когда вам все равно, есть они или нет, встречаются намного реже. Тем не менее, jQuery призывает вас игнорировать тот факт, что #foo или .bar отсутствуют, и позволяет вам счастливо объединять методы, которые ничего не добьются, без предупреждения. Это переворачивает все с ног на голову, требует гораздо меньших вариантов использования и делает это нормой.
2. Я думаю, что вы попали в точку. Возможно, вы можете получить лучшее из обоих миров, отделив цепные методы от не цепных с помощью разных классов, как я пытаюсь продемонстрировать здесь: blog.programster.org/fluent-interface
Ответ №4:
Это называется Fluent Interface, я не думаю, что это шаблон, но лучший способ реализовать функцию для уменьшения объема кода и улучшения читаемости.
Я даю вам прочитать страницу Википедии : http://en.wikipedia.org/wiki/Fluent_interface
Ответ №5:
Этим занимается не только PHP / Zend Framework, поскольку существует множество других языков программирования, использующих интерфейс fluent. Я, конечно, думаю, что это удобно и что использование fluent interface — хороший способ кодирования. Хотя иногда коды выглядят странно, это не значит, что это неправильно, и я не думаю, что вы можете отнести это к категории con, если честно.
В итоге программист видит только то, что он получает тот же объект обратно, а не то, как он выглядит внутри кода класса fluent interface. Я думаю, что самый большой плюс интерфейса fluent — это читаемость кода. Если вы хотите услышать опровержение, то отладка беглой цепочки — одно из них.