Кирилл Мокевнин @toxicmt
Программист & Предприниматель
Information
- Rating
- 1,402-nd
- Location
- Miami Beach, Florida, США
- Date of birth
- Registered
- Activity
Specialization
Fullstack Developer, Chief Technology Officer (CTO)
Lead
Программист & Предприниматель
Мало того что угнал идею (http://2009.russianinternetweek.ru/news/210) так еще и прикидываешься овечкой невинной. Лови минусы большие и маленькие.
p.s. Проект билетерра жив и скоро будет запущен.
2. Да я видел все их ассерты и пользуюсь ими.
Вообще это все частности. Топик не является туториалом на тему как вообще писать тесты, об этом и так много статей в том числе и та что Вы указали. Центральная тема топика создание фикстур и взаимодействие с базой.
framework.zend.com/issues/browse/ZF-1156
А переписать пришлось findParentRow и еще некоторые связанные с ним методы. Все сводится к простому наследованию от нужных классов My_Table extends Ext_Db_Table_Abstract, My_Row extends Ext_Db_Table_Row_Abstract
Предположим что мы используем ZF table, кастомизируем его row и определяем там бизнес логику. Когда мы в какой то row делаем выборку этой сущности и джойном тянем другую сущность, то мы фактически в один класс row загоняем данные которые ей не принадлежат. В zf не реализовано расфасовывание объектов по своим row, отсюда возникает куча проблем.
Например мы достали статьи и к ним приосединили юзверей. При выводе статей нам нужно выводить создателей этих статей и рядом показывать значек статуса пользователя (онлайн/офлайн).
В row_user у нас был метод isOnline() который содержал какую то простую логику. А в row_article этого метода нет. Что нам остается делать? Либо писать эту проверку прямо в шаблоне (зло), либо дублиовать этот метод в row_article (зло), либо реализовывать разделение объектов (не очень просто) и самый простой и доступный способ это тянуть данные без использования джойнов через findParentRow().
Можно конечно возразить что findParentRow(), тянет данные для каждого объекта и это запросы в цикле, но ничто не мешает его переопределить так чтобы подтягивались данные сразу для всего rowset, только при первом обращении к findParentRow.
Так вот, потом во вьюхе делается следующее.
foreach…
<?= $article->findParentRow('User')->name ?> //Тут планируется шоткат.
Причем юзеры будут загружены только один раз и только те которые нужны для этих статей. Для этого переопределено много логики, в том числе каждая row хранит в себе rowset.
Это очень сильно упрощает код и его становится гораздо меньше. Плюс не нужно писать кучу лишних методов и тестировать их, т.к. этот функционал уже протестирован.
AR = Row Gateway + бизнес логика.
Фаулер:
«Иногда шлюз записи данных трудно отличить от активной записи(Active Record). В этом случае следует обратить внимание на наличие какой-либо логики домена; если она есть, значит, это активная запись. Реализация шлюза записи данных должна включать в себя только логику доступа к базе данных и никакой логики домена.»
Кастомизацией роу в зенде можно добиться любого результата.
По поводу выборок зависимых объектов, мы поступили следующим образом (кстати, в трекере зенда есть тикет на эту фичу).
Делается выборка, например, статей: $articles = $table->findLastArticles();
0_o
Фреймворк != полная автоматизация.
Все Ваши примеры решаются тем инструментом который для этого предназначен — это условные операторы.
Выдержка из книги «Совершенный код»:
8 ) Кодирование путём исключения
Этот антипаттерн представляет собой реализацию нормальной логики работы программы с помощью механизма исключений. Например, рекурсивный поиск по дереву может в качестве результата поиска кидать исключение. Такая реализация на первый взгляд может выглядеть заманчиво и удобно, но не более чем на первый взгляд.
Исключения должны использоваться с одной единственной целью — проинформировать систему об ошибке. Использование исключений как инструмента для управления логикой программы вносит неоднозначность. Глядя на конструкцию try-throw-catch / try-raise-except, программисту совершенно не очевидно, для чего именно эта конструкция используется. Кроме того, управление логикой через исключения и система оповещения об ошибках, построенная на исключениях, могут попросту мешать друг другу, поскольку они построены на одном механизме.
Для обработки ошибок используйте только исключения, а исключения — только для обработки ошибок.
Методы поиска занимаются только поиском, и если они что то не вернули то значит вы им не то передали. Если ошибка в том что метод не рабочий — правьте тесты.
Если мы говорим про вставку данных, то целостность базы должна поддерживаться на уровне базы и единственный способ сделать это, использовать внешние ключи. Без них любая база превратиться в помойку, даже при самых страшных проверках.
А уже в контроллере можно делать так if ($row)
В выборках наличие непустого id контролируется, например, через роутинг -> news_id => '\d+'