Мне любопытно, каковы недостатки использования шаблона ActiveRecord для доступа к данным / бизнес-объектам. Единственное, о чем я могу подумать, - это то, что он нарушает Принцип Единой Ответственности, но модель AR достаточно распространена, и сама эта причина не кажется «достаточно хорошей», чтобы оправдать ее неиспользование (конечно, мой представление может быть искажено, поскольку часто ни один код, с которым я работаю, не следует ни одному из принципов SOLID).
Лично я не фанат ActiveRecord (за исключением написания приложения на Ruby on Rails, где AR чувствует себя «естественным»), потому что он чувствует, что класс делает слишком много, а доступ к данным не должен зависеть от самого класса обрабатывать. Я предпочитаю использовать репозитории, которые возвращают бизнес-объекты. Большая часть кода, с которым я работаю, имеет тенденцию использовать вариант ActiveRecord в форме (я не знаю, почему метод является логическим):
public class Foo
{
// properties...
public Foo(int fooID)
{
this.fooID = fooID;
}
public bool Load()
{
// DB stuff here...
// map DataReader to properties...
bool returnCode = false;
if (dr.HasRows)
returnCode = true;
return returnCode;
}
}
или иногда более "традиционный" способ иметь public static Foo FindFooByID(int fooID)
метод для поиска и что-то вроде public void Save()
для сохранения / обновления.
Я понимаю, что ActiveRecord, как правило, намного проще в реализации и использовании, но кажется, что он слишком сложен для сложных приложений, и вы могли бы иметь более надежную архитектуру, инкапсулировав логику доступа к данным в репозитории (не говоря уже о том, что ее проще заменить стратегии доступа к данным, например, возможно, вы используете Stored Procs + DataSets и хотите переключиться на LINQ или что-то еще)
Итак, каковы другие недостатки этого шаблона, которые следует учитывать при принятии решения, является ли ActiveRecord лучшим кандидатом на работу?
источник
Самый большой недостаток активной записи заключается в том, что ваш домен обычно тесно связан с определенным механизмом сохранения. Если для этого механизма требуется глобальное изменение, возможно, от сохранения на основе файлов к сохранению на основе БД или между средами доступа к данным, КАЖДЫЙ класс, реализующий этот шаблон, может измениться. В зависимости от языка, структуры и дизайна, даже чего-то такого простого, как изменение места нахождения БД или того, кто «владеет», может потребоваться пройти через каждый объект для обновления методов доступа к данным (это редко встречается в большинстве языков, которые обеспечивают легкий доступ настроить файлы со строками подключения).
Это также обычно требует от вас повторения. Большинство механизмов персистентности имеют много общего кода для подключения к БД и запуска транзакции. СУХОЙ (не повторяйся сам) скажет вам как программисту централизовать такую логику.
Это также делает атомные операции сложными. Если группа объектов должна быть сохранена в режиме «все или ничего» (например, «Счета-фактуры» и «InvoiceLines» и / или «Customer» и / или «GL»), либо один объект должен знать обо всех этих других объектах и контролировать их постоянство ( который расширяет область действия контролирующего объекта; большие взаимосвязанные записи могут легко стать «объектами бога», которые знают все об их зависимостях), или контроль над всей транзакцией должен осуществляться вне домена (и в этом случае, почему вы используете AR?)
Это также «неправильно» с объектно-ориентированной точки зрения. В реальном мире счет-фактура не знает, как подать файл, так почему объект кода счета-фактуры знает, как сохранить себя в БД? Конечно, чрезмерная религиозная приверженность «объектам следует только моделировать то, что могут делать их реальные партнеры», приведет к анемичной модели предметной области (счет-фактура также не знает, как рассчитать свою общую сумму, но разделяет вычисление этой общей суммы на другой объект вообще считается плохой идеей).
источник
Основной недостаток заключается в том, что он делает вашу модель предметной области сложной, поскольку он содержит не только бизнес-логику, но и информацию о постоянстве.
Поэтому решение состоит в том, чтобы использовать реализацию ORM для Data Mapper . Это отделяет постоянный слой, и теперь мы больше ориентируемся на бизнес-логику сущностей. Доктрина является Data Mapper ORM.
Но этот подход также имеет некоторую сложность: для запросов теперь вы слишком сильно зависите от Data Mapper, создающего ориентированную на запросы среду. Для того, чтобы упростить ее еще один слой вводится между Domain Model и Mapper данных называется хранилище .
Репозиторий абстрагируется от персистентного слоя. Это создает ощущение объектно-ориентированного программирования в том смысле, что оно представляет собой совокупность объектов одного типа (как и всех сущностей, хранящихся в таблице базы данных), и вы можете выполнять над ними операции как операции сбора, добавления , удаления . содержит и т. д.
Например, для User Entity будет UserRepository , представляющий коллекцию пользовательских объектов того же типа (которые хранятся в таблице users), над которыми вы можете выполнить операцию. Для запроса к таблице пользователей он использует User Data Mapper, но он абстрагируется от модели домена User .
Шаблон репозитория - это тип уровня доступа к данным , другой - различия между объектами доступа к данным. Репозиторий имеет функцию агрегированного корня.
источник