Pull to refresh
0
0
miros @miros

User

Send message
Проблему ADM против «наделение сущностей предметной области поведением, не относящимся на прямую к ним» может решить парадигма DCI (http://en.wikipedia.org/wiki/Data,_Context_and_Interaction).
Если кратко, то следует задуматься о том, что кроме самих объектов есть ещё роли, которые они играют и с точки зрения программирования выгодно разделить объект предметной области (не несущий функционала специфичного для юз кейсов программы) и роли (которые уже несут специфичный функционал).Это не единственная и не главная идея DCI, там есть ещё несколько клёвых, например о явном выделении шагов алгоритма (юз кейса), за что часто ругают ооп (вот у нас есть много объектов со многимим методами, а как понять когда и как они используются).
Насчет влияния на архитектуру… Я считаю что влияние на архитектуру — это сверхпереоцененное качество тестов. Это их побочное явление. Главное в тестах это — отловить регрессии, служить эталоном верного поведения кода. Тогда они развяжут вам руки при рефакторинге и дадут возможность экспериментировать с дизайном. TDD же намертно вбивает один дизайн (закрепляя его на уровне тестов интерфейсов и протоколов взаимодействия) еще до написания кода. Это будет не самый плохой на свете дизайн (вот именно это превозносят сторонники TDD). Но этот дизайн будет очень далек от наилучшего (хотя бы потому, что еще не написав никакого кода, вы не понимаете предметную область). TDD будет лучше работать если вы напишете тесты, напишите код, а потом сотрете нафиг большую часть тестов, а другие напишите нормально (то есть не так близко к реализации, в стиле тестирования поведения). Но ведь так никто не делает. Подсознательно сложно заставить себя стереть тест. В TDD не хватает обратной связи код -> тесты…
Тут есть принципиальное отличие, но оно не в коде (конкретной реализации теста), а в области мышления.
С TDD вы думаете «мой код должен вернуть тру при таких-то входных параметрах» и на основе этого пишете тесты.
При BDD вы думаете «мой код должен выполнить такой-то юз кейс» (или даже «мой код должен решить такую-то бизнес задачу пользователя»).
Путаница в этих понятиях, я думаю, связана с тем, что многие говорят о BDD в контексте юнит тестирования. Но бизнес требования — это высокоуровневая вещь и чем тесты ближе к реализации (а ближе, чем юнит тесты и не бывает), тем сильнее разница подходов размывается. А многие считают, что раз используют Rspec и пишут it should значит это BDD, что если их тесты тестируют поведение (а не интерфейсы и реализацию) класса (что, конечно, хорошо) — то это BDD. BDD это когда конечный пользователь читает название теста, и говорит: да — это то, что я хочу от программы.
Опять статья про тестирование в которой перемешаны понятия тестирования в целом, модульного тестирования, интеграционного тестирования и самого TDD. ТDD это test-first методология. Любой разработчик обязан писать тесты. Но делать в TDD стиле это не обязательно. На самом деле TDD имеет недостатки. Классический (mockist-style) подход порождает кучу тестов, которые очень сильно зависят от интерфейсов (и от реализации).
По большому счету многие из этих тестов должны быть просто удалены, поскольку в будущем их хрукость только мешать будет. Фактически единственное преимущество TDD это модульность, которую он пораждает. Но тут тоже не все так гладно, с одной стороны такой подход защитит вас от монолитных классов и совсем плохой архитектуры, но с другой стороны хороший дизайн от TDD сам не появится. TDD поощряет single responsibility principle, но тут легко дойти до крайности и обнаружить, что модель предметной области забита классами-сервисами без состояния. На мой взгляд о TDD лучше отказаться в пользу BDD (причем c широким циклом: пишем приемочный тест, кодим пока он не прошел). Модульные тесты при этом используются прагматически: тестируем ими действительно сложную логику + то что на интеграционном уровне простестировать сложно. В общем покрытие вашего кода должно быть высоким, но обеспечивать оно должно интеграционными тестами, они и регрессионность обеспечат и позволят вам задуматься о фичах с точки зрения требований, да и проект они неплохо документируют. Огромный минус — медленно. Но что уж сделаешь, идеала не бывает.
Вы шутите? У проекта шортики полностью статическая главная страница (для всех). На ней один запрос, который кешируется по времени. Пейдж кэш не всегда можно использовать. Но в конкретном случае и в конкретных условиях это очень хороший вариант…

P.S.
Кстати, о конкретной технологии кеша, и как его хранить (почему сразу файлы?) я ничего не говорил…

То есть вы считаете, что full page cache на прокси — это не самый простой и эффективный способ кеширования? Почему?
Вы зря кешируете на уровне запросов. Если можно закешировать всю страницу целиком, то так и надо делать (А если нельзя — надо постараться, чтобы было можно).
Не пользуйтесь will paginate. Он фактически мертв, плохо поддерживается и так и не был переписан для нормальной поддержки скоупов. Используйте kaminari…
Опять эта тема твиттера и руби… Руби не повезло, что самый большой сайт на нём принадлежит такой странной в техническом отношении компании как твиттер. Несколько примеров… Они написала очередь сообщений на руби (кому вообще могло прийти в голову писать такое на руби во времена черепашьего 1.8?!, причём судя по тестам их реализация была очень далека от оптимальности...) — переписали на скале — по блогам пошли посты на тему; руби дрянь, скала рулит. Переписали поисковую подсистему на JVM с иcпользованием асинхронных запросов к бэкенду через netty — скорость выросла в 10 раз — все снова сделали вывод: руби дрянь, хотя если бы они переписали синхронный код на руби с иcпользованием асинхронности через event_machine, рост производительности был бы таким же огромным.
Плюс странные заявления, что Scala лучше ruby потому, что там статическая типизация, что снижает кол-во ошибок. Надёжность программ со статической типизацией это просто миф, в который верят люди у которых мало опыта с динамическими языками.
Из постов в блогах кажется, что Твиттер компания, где решают все проблемы переходом на новую более модную технологию и написанием своих велосипедов на ней…
Да чепуха всё это про «передний край». Так обычно называют модные и прикольные по мнению разработчиков технологии. И пиарят их больше всех люди, которые на практике не использовали их никогда на реальных проектах, но хотели бы. Node.js и Javascript в этом отношении очень показательны, тут нет ничего нового, джаваскрипт как серверный язык не имеет никаких преимуществ над руби и питоном, фреймворки для асинхронных серверов существовали и до него. Просто новая модная штука. То же самое с эрлангом. В своей нише он очень хорош, для производительного инфраструктурного сервера отличный выбор, но хорошо ли подходит чисто функциональный язык для типичного сайта или веб сервиса со сложной бизнес логикой…
1. Нет, как вы говорите ничего не выйдет. Преобразовать и сохранить картинки это просто, но вы не сможете потом получить от карриервейв правильный урл или имя файла, они будет с расширением базовой версии (поскольку в бд хранится только оно). Никакое переопределение методов для версии вам не поможет преобразовать расширение (это возможно но сламается другой функционал карриервейв). Я разговаривал по этому поводу с разработчиками, мне сказали что они очень хотят эту фичу, но архитектура не позволяет.
2. Это проявляется на апдейтах
github.com/jnicklas/carrierwave/issuesearch?state=closed&q=nested#issue/91
Возможно в хеде уже исправили.
Пожалуйста, расскажите где там конкретно паттерн Chain of Responsobility?
насчёт Кариервейв всё неоднозначно.Carrierwave неидеален. Код у него супер. Но вот некоторые юз кейсы с ним очень сложно реализуемы: например, вы не сможете сделать у картинки две версии с разными расширениями, вы не сможете без самописных костылей использовать его со вложенными формами (он не дружит с accepts_nested_attributes), при удалении модели он файлы удалит но оставит пустые папки, которые вам надо самим тереть и так далее.
Если я прафильно понимаю, то метод в питоне не более чем, аттрибут класса, который оказался объектом типа метод. Так что, вы вполне можете добавить к классу новый метод или скопировать из одного класса метод в другой. Чтобы, в таких ситуациях всё было очевидно, разработчики, видимо, решили не связывать метод с классом, которому он сейчас принадледжит, какими-то неявными механизмами, а передавать указатель в лоб, питом же стремится к ясности, пусть и в ущерб красоте.
А это только так кажется, на самом деле, если писать создание тестовых объектов руками, то будет много дублирования. Сложный объект не просто создать, у него много связей. А что если какие-то аттрибуты у модели уникальны: вручную следить за их уникальностью?
Без factory_girl (или чего то такого) github.com/thoughtbot/factory_girl мне было бы очень трудно. Например, можно создать базовое правило производства объекта, а затем конкретизировать его в новом правиле, наследовав от старого.
Это понял автор статьи. Раз пока нет широкоиспользуемых решений для этого подхода, значит пока не поняло.
Механизм fixtures описанный в этой статье это плохо. Фикстуры ненадёжны и неудобны. Это поняли ещё в 80-х. Rails сообщество поняло пару лет назад. Php ещё нет :-). Надо пользоваться фабриками. Не знаю как с ними обстоит в php, видимо, плохо.
У меня абсолютно другой практический опыт. Как и у многих других в rails сообществе. Сейчас, наоборот, всё больше говорят, что предпочтительно тестировать не стабя вызовы к БД. Выгода от менее хрупких и более надёжгых тестов стоит потерь скорости.
То что тесты работающие с базой данных прям такие медленные, что их нельзя использовать это совсем не правда. Типичная страшилка. Они медленные только по сравнению с тестами, не работабщими с базой. Просто посчитайте: несколько инсертов, апдейтов и селектов средней сложности это десятки миллесекунд не больше (в тестовой БД, обычно данных нет, при каждом тесте она обнуляется, или просто каждый тест идёт в отдельной транзакции). Оверхед на один тестовой пример небольшой, и хотя примеров много, в целом разница не смертельная, это еденицы минут для очень больших тестовых пакет и секунды, десятки секунд для небольших и средних проектов. Я не говорю что все тесты, должны работать с бд. Если в тесте можно обойтись без неё, то нужно обойтись. Но то как проект работает с БД тоже надо тестировать. И в нормальном тестовом пакете всё равно придёться иметь такие тесты, иначе регрессивность пакета будет никуда не годной.

P.S. А если тесты запускать на БД в памяти то оверхед вообще минимальным будет.

Information

Rating
Does not participate
Location
Москва и Московская обл., Россия
Registered
Activity