Вообще можно долго писать к чему приводит использование ActiveRecord, об этом много написано. Но действительно понять, что лучше его не использовать можно лишь попробовав его не использовать:)
Паттерн ActiveRecord плохо подходит для приложений с развитой бизнес логикой, коих на самом деле большинство. А плох он, потому что смешивает две ответственности воедино:
работу с базой данных(получение, обновление данных)
отображение записи из таблицы на объект
Что ведет к таким последствиям:
Бизнес логика смешивается с работой с базой, что усложняет поддержу кода
Доступ к полям объекта может приводить к запросам к бд и вы можете долго этого не замечать.
Невозможно полностью абстрагироваться от БД. Это, например, ведет к тому что нельзя писать быстрые тесты. К примеру в паттерне Data Mapper эти две ответственности отделены на сущности(отображение данных из бд на объект) и репозитории(доступ к бд). Используя data mapper я могу написать альтернативную реализацию репозиториев, которые будут работать без доступа к БД(in memory repositories). Не обращаясь к БД тесты будут проходить мгновенно. А чтобы быть уверенным, что приложение работает и с реальными репозиториями, я покрою репозитории отдельными тестами, которые будут поочередно прогонять тесты для двух реализаций(реальной и той что работают без доступа к бд).
Бардака там конечно тоже хватает. Но в руби сообществе проблема в том, что Rails — это стандарт де факто. Люди просто не знают, что можно писать под другому. Этому почти никто не учит в руби. Если же сравнивать с той же явой, то здесь есть именитые разработчики(Martin Fowler, Robert Martin, ...) которые пропагандируют как писать действительно правильно
Согласен с автором. Но есть еще большая проблема. Использование monkey patch и ActiveRecord, ведут к тому, что разрабатывая на рельсах решаешь задачи не как «написать правильно», а как «написать на рельсах правильно”.
Такой разработчик, придя в другой язык, вынужден начинать все с нуля, потому что то, что он применял в рельсах уже совсем не подходит под новый язык/платформу.
В новом языке нет AсtiveRecord, а приложение разрабатывают не на фреймворке, а строят архитектуру для приложения используя фреймворк. Годы опыта потраченные на изучение рельс будут потрачены зря.
Проблема то не в руби, а в рельсах, которые популяризировали плохие способы решения задач(monkey patch, ActiveRecord). Писать не rails way не значит писать медленно.
Использую очень похожую архитекуру. Добавлю свои пять копеек
//Проверяем входные данные
CheckingData(op);
...
_chargeOpsStorage.CreateChargeOp(op);
Я бы добавил класс ChargeOperation, в который перенес бы валидацию на то, что сумма больше нуля. И соответственно в _chargeOpsStorage передавал бы объект ChargeOperation.
//обновить отчет за месяц
public void UpdateMonthReport(Guid userId, ECategory category, int year, int month, double sum)
Тут перебор с аргументами, в данном случае имеет смысл создать объект MonthReport, в котором инкапсулировать эти аргументы
Мы все очень любим (или не любим) поговорить о шаблонах проектирования. Лично я их сильно недолюбливаю, т.к. большинство из них достаточно очевидны для более или менее опытного разработчика, а шаблонность мышления еще никому в жизни не помогала.
Шаблоны это не только примеры удачных архитектурных решений, не менее важно то, что шаблоны дают единый словарь терминов, которые можно использовать в дискуссиях и пояснениях к коду. Т.о. вместо того, чтобы каждый раз объяснять что вы спроектировали вы просто говорите это Фабрика, Медиатор,…
Роберт Мартин приводит в качестве аргумента то, что геттеры и сеттеры тестируются косвенно через другие тесты, но, несмотря на то, что это может быть верно на этапе объявления члена, не факт, что это будет верно сколь угодно долгое время. Спустя месяцы, эти тесты могут быть удалены, оставляя введённый тривиальный член непокрытым тестами.
Точто так же могут быть удалены и модульные тесты. Не забывайте что весь функционал в идеале должен быть покрыт приемочными тестами, которые косвенно протестируют тривиальный код.
Google/Yandex склеивают домен с www и без если по обоим адресам одинаковый контент. Это происходит не сразу, а по прошествии некоторого времени после попадания сайт в базу поисковика.
Что ведет к таким последствиям:
Такой разработчик, придя в другой язык, вынужден начинать все с нуля, потому что то, что он применял в рельсах уже совсем не подходит под новый язык/платформу.
В новом языке нет AсtiveRecord, а приложение разрабатывают не на фреймворке, а строят архитектуру для приложения используя фреймворк. Годы опыта потраченные на изучение рельс будут потрачены зря.
Я бы добавил класс ChargeOperation, в который перенес бы валидацию на то, что сумма больше нуля. И соответственно в _chargeOpsStorage передавал бы объект ChargeOperation.
Тут перебор с аргументами, в данном случае имеет смысл создать объект MonthReport, в котором инкапсулировать эти аргументы
Там подробнее о том что описал автор топика
Шаблоны это не только примеры удачных архитектурных решений, не менее важно то, что шаблоны дают единый словарь терминов, которые можно использовать в дискуссиях и пояснениях к коду. Т.о. вместо того, чтобы каждый раз объяснять что вы спроектировали вы просто говорите это Фабрика, Медиатор,…
Точто так же могут быть удалены и модульные тесты. Не забывайте что весь функционал в идеале должен быть покрыт приемочными тестами, которые косвенно протестируют тривиальный код.