В Model-Driven Design в вашем приложении есть логические сущности , и эти сущности могут отображаться в несколько таблиц в физической базе данных. Конечно, вам нужно запустить более сложный SQL для извлечения полной сущности, и класс Model - это место, где реализуются эти отношения.
Я думаю, что ActiveRecord и тому подобное можно использовать для простых запросов к одной таблице, но пытаться принудительно использовать эти шаблоны для сложных запросов слишком сложно. К счастью, у нас уже есть краткий, предметно-ориентированный язык, который вы можете использовать для определения сложных запросов: SQL.
Таким образом, в вашем классе Model у вас есть методы для выполнения логических задач уровня приложения, например getCustomersForFeature()
. В коде для этого метода вы должны написать конкретный запрос, либо с помощью методов ActiveRecord, либо с прямым SQL, если это необходимо. Таким образом, конкретный дизайн вашей базы данных инкапсулирован в одном месте, в классе Model.
Это означает, что нам нужно разорвать связь между моделью и таблицей. Отношения ОО между Моделью и классом ActiveRecord не IS-A - это HAS-A (или has-many).
Re ваш комментарий: Так что наша модель? Если вашему приложению в первую очередь необходимо работать с клиентами как единым целым и рассматривать функции как более или менее атрибут клиентов, то да, ваша Модель будет Покупателями, и это будет скрывать тот факт, что функции хранятся в отдельной таблице в базе данных. , Модель Customers будет внутренне использовать ActiveRecord или обычный SQL для сбора необходимых данных, чтобы обеспечить полное представление о сложном объекте, являющемся клиентом, со связанными многозначными атрибутами.
Однако, что если вашему приложению также необходимо напрямую работать с функциями? Например, экран администратора, где вы можете получать отчеты на основе функций или создавать новые функции. Тогда было бы неуклюже получить доступ к функциям через модель Customer. Таким образом, вам все-таки нужна модель Особенности. Только у него будут разные методы для реализации операций, которые вам нужно делать с функциями.
Каждый класс модели должен предоставлять API только того, что нужно сделать с этой моделью . Там нет необходимости даже быть симметричным. То, что ваша модель Customer может выбирать всех клиентов, у которых есть данная функция, не обязательно означает, что вашей модели Feature необходимо получить все функции для данного клиента. Следуйте правилу YAGNI .
Но после того, как вы создали свою модель Customer и свою модель Feature, не приведет ли это к дублированию логики, которая знает об отношениях между таблицами? Да, это возможно. Это одна из многих проблем, подпадающих под область несоответствия объектно-реляционного импеданса .