OOD, TDD и Anti-patterns. Восприятие и логика. Правильное ООП.

maxru

МИФИст
OOD, TDD и Anti-patterns. Восприятие и логика. Правильное ООП.

Заинтересовался технологиями разработки приложений на PHP.
Интересуют не какие-то конкретные методы, а впечатления людей, работавших с этими методами при разработке реальных приложений.
Также хотелось бы услышать о плюсах и минусах OOD.
1) В каких случаях лучше применять Object Oriented Development? (размер и сложность приложений)
2) Какие проблемы я могу получить при не очень грамотном проектировании приложения?
3) Стоит ли создавать God Classes или лучше разбивать на множество небольших? (второй способ мне больше по душе).
4) Также хотелось бы услышать о грамотном комментировании кода. (Сам использую PHPDocumentor). Что нужно комментировать и в каком объеме?
5) TDD. С чем едят и с чего лучше начать, и как не облажаться. (phpclub.ru/faq, Google читал ;) )
6) Anti-patterns. Вот тут будет много мыслей. И мне хотелось бы опровержения моих догадок, если я не прав.

6.1) Anemic Domain Model.
Совсем не понял, что это такое. Хотелось бы ссылочку на примеры кода или внятное описание (ru\en).
6.2) BaseBean
Как я понял - эта ошибка связана с наследованием от одного Bean-класса только потому, что в нем содержатся необходимые методы.
6.3) Call super
Насколько я понял - эта ошибка связана с перегрузкой метода в классе-наследнике, причем реализация этого метода у наследника
как правило сильно отличается от реализации метода у суперкласса. Плохо здесь то, что приходится вызывать метод родительского класса, при этом
до вызова отформатировать данные таким образом, чтобы метод родительского класса их корректно обработал.
Хотя очевидное решение - сделать метод родительского класса final и добавить вызов абстрактного метода, а в потомках реализовать этот
метод.
6.4) Empty subclass failure
Ну тут все просто. Если мы заменяем класс на наследника (который просто наследует суперкласс без изменений) и тесты все равно работают, то это
бессмысленная трата ресурсов.
6.5) God Class
Тут тоже понятно. Не надо создавать класс, который кроме решения своей основной задачи еще и занавески гладит. Для этого отлично подойдет класс
"ГладильщикЗанавесок"
6.6) Object cesspool
Тут более-менее понятно. Нет смысла оставлять в живых обьект, который мы не сможем использовать еще раз. (Кстати, насколько это актуально для PHP?)
6.7) Poltergeist
Тут есть вопросы. Полтергейст - это класс, который необходим для инициализации "полноценного" класса или для реализации какого-то функционала.
Полтергейст создается и достаточно быстро удаляется. Поэтому такие классы являются "растратчиками" ресурсов.

Вопрос:
Создал я, например, класс DatabaseConnection, который открывает, закрывает соединение с БД, хранит идентификатор соединения, блокирует и разблокирует соединение, исполняет запрос и возвращает результат в виде класса-итератора.
Класс-итератор создается на момент выполнения запроса и уничтожается после извлечения всех данных.
По сути своей он и является Полтергейстом. Но получается, что это необходимое зло, т.к. БД может быть много, результаты возвращаются тоже в различной форме, а итератором мы можем сделать доступ к данным прозрачным.

6.8) Sequential Coupling
Это случай, когда методы класса надо вызывать в определенной последовательности. То есть если вызвать, например метод End(), не вызвав до этого
метод Start() будет нарушена работа класса, что приведет к неожиданным результатам.
6.9) Singletonitis
Чрезмерное увлечение паттерном Синглтон.
Вопрос: как определить, что использование Синглтона не нужно в данном конкретном случае?
6.10) YAFL (Yet Another Layer)
Добавление не необходимых слоев в программу, библиотеку или фреймворк.
Опять же вопрос - как определить когда остановиться?
6.11) Yo-yo problem
Эта проблема возникает при очень большом или запутанном графе наследования. Восприятие логики сторонним программистом становится проблематичным.

Сам уже заказал в озоне книги:
Приемы объектно-ориентированного проектирования. Паттерны проектирования Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес (Питер: 2007)
Профессиональное программирование на PHP Джордж Шлосснейгл (Вильямс: 2006)
В книге рассматривается разработка высокопроизводительных, стабильных и расширяемых PHP-приложений, а также подробно освещаются методики
блочного тестирования, обеспечения безопасности, методик кэширования и повышения производительности Web-приложений. Кроме того, в книге достаточно полно описано создание РНР- и Zend-расширений, увеличивающих возможности языка.


Топик создал для того, чтобы подготовиться к восприятию этих книг (на подготовку - время до понедельника *) ).
Очень желательно будет, чтобы собеседники подтверждали свои слова фрагментами кода или ссылками на источники данных.
Я надеюсь, что разговор будет интересным и я (а может быть и другие форумчане) узнаю много интересного.
 

zerkms

TDD infected
Команда форума
отвечу только на 5
остальное - уж больно холиварно-флеймовое ;)

Test driven development by example, K. Beck
такую книжку ищи

ps: на пхпфаке про тдд ничего не было и, думаю, не нужно оно там совсем
 

maxru

МИФИст
Ошибся, не на phpfaq, а на phpclub.ru/faq/

Я бы сказал, не "холиварное".
Возможно эти паттерны и применимы в ряде случаев (а в очень узком ряде случаев применимы только они), но если сильно увлекаться подобными художествами есть шанс засрать всю архитектуру приложения ИМХО.
 

zerkms

TDD infected
Команда форума
maxru
тогда уж актуальнее - читать agiledev.ru
 

whirlwind

TDD infected, paranoid
> 1) В каких случаях лучше применять Object Oriented Development? (размер и сложность приложений)

Применять нужно вообще ИМХО везде, а особенно там, где планируется длительное время сопровождения.

> 2) Какие проблемы я могу получить при не очень грамотном проектировании приложения?

Трудности будущих модификаций. Если вы делаете однодневку или вам наплевать на тех, кто будет работать c кодом после вас - вам не нужны никакие методики, технологии и архитектуры.

> 3) Стоит ли создавать God Classes или лучше разбивать на множество небольших?

Если есть хоть малейшие сомнения - всегда выбирайте композицию.

> 4) Также хотелось бы услышать о грамотном комментировании кода. (Сам использую PHPDocumentor). Что нужно комментировать и в каком объеме?

Документировать следует интерфейсы, а не код.

> 5) TDD. С чем едят и с чего лучше начать,
начать лучше с тестов

>и как не облажаться
Практика, практика и ни в коем случае не бросать. Упрощать, писать тейсты по-своему, но не бросать. У вас уйдет гораздо больше времени на поиск какой нибудь неправильно написанной переменной или забытого ретурна, чем вы потратите на написание $this->assertEqual($myobj->getFoo(),'bar')

> 6) Anti-patterns

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

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

1. Предпочитайте композицию наследованию. Если у вас наследование более чем в 3 уровня, подумайте - все ли вы делаете правильно.
2. Не используйте статические вызовы.
3. Стремитесь к атомарности и автономности. Одни элементы архитектуры должны выглядить "черными ящиками" для других. При проектировании, опирайтесь не на реализацию, а на интерфейс.
4. Думайте о завтрашнем дне вашего кода. Возможно человек, который вернется к написанному вами сегодня - это вы сами.
5. Плохой тест лучше чем его отсутствие.
6. Железо стоит дешевле времени хорошего программиста. Не заморачивайтесь вопросами быстродействия, пока в этом не будет реальной необходимости.
 

maxru

МИФИст
Автор оригинала: whirlwind
> 3) Стоит ли создавать God Classes или лучше разбивать на множество небольших?
Если есть хоть малейшие сомнения - всегда выбирайте композицию.
Обычно так и делаю.
> 4) Также хотелось бы услышать о грамотном комментировании кода. (Сам использую PHPDocumentor). Что нужно комментировать и в каком объеме?
Документировать следует интерфейсы, а не код.
Я это и имел в виду.
Условные операторы я не комментирую. -)
Входные переменные, выходные переменные, кратенькое описание для функции. Package, автор для класса.
PHP:
 if(true == false) // на всякий случай
> 5) TDD. С чем едят и с чего лучше начать,
>и как не облажаться
Практика, практика и ни в коем случае не бросать. Упрощать, писать тейсты по-своему, но не бросать. У вас уйдет гораздо больше времени на поиск какой нибудь неправильно написанной переменной или забытого ретурна, чем вы потратите на написание $this->assertEqual($myobj->getFoo(),'bar')
Так оно и есть. Полчаса пишем, час ищем ошибку (без тестов). Надоело уже.


Спасибо огромное за развернутый ответ.
 

Макс

Старожил PHPClub
> Условные операторы я не комментирую. -)
Комментарии могут быть написаны как для пользователей класса (им нужен интерфейс), так и для программеров, которые будут поддерживать этот код (улучшать, расширять, фиксить в нем баги - в том числе и для самого себя). Вот для последних можно и if прокомментировать, если в нем зашита нетривиальная логика, которую знает лишь автор.

А что касается интерфейсов, то при правильном выборе названий для функций и входящих параметров в комментария можно оставить только, что возвращает функция (если там что-то неочевидное) и какие она может кинуть исключения.
 
Сверху