Дизайн php oop MVC - правильная архитектура приложения для редактирования данных

Теперь, когда я прочитал очень много сообщений, статей, вопросов и ответов об ООП, MVC и шаблонах проектирования, у меня все еще есть вопросы о том, как лучше всего построить то, что я хочу создать.

Моя маленькая структура построена в стиле MVC. Он использует smarty в качестве средства просмотра, и у меня есть класс, настроенный как контроллер, который вызывается из URL-адреса.

Теперь я думаю, что заблудился в части модели. Я мог бы смешивать модели и классы/объекты слишком много (или слишком мало).

Во всяком случае пример. Когда цель состоит в том, чтобы получить список пользователей, которые находятся в моей базе данных:

приложение вызывается, например. «users/list» Затем контроллер запускает список функций, который открывает экземпляр класса «user» и запрашивает этот класс для извлечения списка из таблицы. после возврата контроллеру контроллер отправляет его в средство просмотра, назначая набор результатов (массив) шаблону и устанавливая шаблон. Затем пользователь щелкнет строку в таблице, которая сообщит контроллеру, например, запустить «user/edit», что, в свою очередь, создаст форму и заполнит ее пользовательскими данными для редактирования.

Все идет нормально.

прямо сейчас у меня все это объединено в один пользовательский класс, так что этот класс будет иметь функцию создания, getMeAListOfUsers, обновление и т. д. и такие свойства, как hairType и NoseSize. Но правильный дизайн oop хотел бы, чтобы я отделил «пользователя» (с такими свойствами, как имя пользователя, большой нос, вьющиеся волосы) от «получить список пользователей», что больше похоже на «класс менеджера пользователей».

Если бы я реализовал класс менеджера пользователей, как бы это выглядело? должен ли это быть объект (нельзя сравнивать его с реальным миром) или это должен быть класс только с общедоступными функциями, чтобы он более или менее выглядел как набор функций.

Должен ли он возвращать массив найденных записей (например: array([0]=>array("firstname"=>"dirk", "lastname"=>"diggler")) или он должен возвращать массив объектов.

Все это все еще немного сбивает меня с толку, и мне интересно, может ли кто-нибудь дать мне небольшое представление о том, как лучше всего подойти к этому.


person half-a-nerd    schedule 22.12.2011    source источник
comment
Хм, это действительно зависит от многих вещей. MVC — хороший, но не совсем определенный шаблон дизайна в веб-среде. Он бывает в нескольких вариациях. Лично мне не нравится аспект жирного контроллера, как вы описали. Контроллер следует использовать для маршрутизации запросов и обработки данных GET/POST/SESSION. Представление должно получать все из модели напрямую (если нет какой-то специальной бизнес-логики, заставляющей это извлекаться в контроллере). Что касается разделения моделей, у меня была такая же проблема. В конце концов, для каждого класса сущностей был создан один класс Repository/Manager, который обрабатывает все CRUD.   -  person ZolaKt    schedule 22.12.2011
comment
Ну, у меня есть индексный файл, который решает, какое приложение открыть, обрабатывает сеанс и повторяет шаблон. Так что я думаю, вы можете видеть это как контроллер тоже в своем роде. Но я стараюсь этого не делать, так как мой мозг не справлялся с тем, какими должны быть тогда зритель и модель ;)   -  person half-a-nerd    schedule 22.12.2011


Ответы (3)


Я не эксперт в этом, но недавно сделал почти то же самое. Я настроил так, что у меня есть один класс для нескольких строк (Users) и один класс для одной строки (User). «Класс нескольких строк» ​​— это просто набор (статических) функций, и они используются для извлечения строк из таблицы, например:

$fiveLatestUsers = Users::getByDate(5);

И это возвращает массив объектов User. Затем каждый объект User имеет методы для получения полей в таблице (например, $user->getUsername() или $user->getEmail() и т. д.). Я раньше просто возвращал ассоциативный массив, но затем вы сталкиваетесь со случаями, когда вы хотите изменить данные перед их возвратом, и именно здесь наличие класса с методами для каждого поля имеет большой смысл.

Изменить: объект User также имеет методы для обновления и удаления текущей строки;

$user->setUsername('Gandalf');
$user->save();
$user->delete();
person powerbuoy    schedule 22.12.2011
comment
Я думаю, что это действительно правильный путь. Полученный код прост для понимания и правильно разделяет логику. Спасибо за помощь (всем вам). - person half-a-nerd; 22.12.2011
comment
давно эта тема была горячей. Я решил (тогда) не возвращать массив объектов, а просто массив записей. Хотя это работает нормально, возвращать объекты действительно более аккуратно - хотя бы для того, чтобы иметь разные имена полей и имена членов. Поэтому, просматривая некоторый код, я просто задался вопросом, как вы собираетесь возвращать массив с объектами. Я имею в виду: выберите * из x, выполните цикл по результату, $objLine = new line(); $objLine-›loadFromDb($recordid) вызовет слишком много запросов к базе данных, не так ли? - person half-a-nerd; 28.02.2013

Уровень абстракции, необходимый для обработки и обработки данных (Бизнес-логика), зависит от ваших потребностей. Например, для приложения с скриптами транзакций (что, вероятно, имеет место с вашим дизайном), класс, который вы описываете, который извлекает и обновляет данные из базы данных, кажется мне подходящим.

Вы можете немного обобщить вещи, используя Table Data Gateway, Шлюз данных строк или Активная запись даже.

Если вы чувствуете, что затем дублируете много кода в сценариях транзакций, вы можете создать свой собственный Модель предметной области с сопоставителем данных< /а>. Однако я бы не стал делать это вслепую с самого начала, потому что для начала требуется гораздо больше кода. Также неразумно писать сопоставитель данных самостоятельно, а использовать для этого существующий компонент. Doctrine является таким компонентом в PHP.

Еще одним существующим компонентом ORM (Object Relational Mapper) является Propel, который предоставляет активные записи.

Если вы просто ищете быстрый способ сделать запрос к своей базе данных, вам может подойти NotORM.


Шаблоны, выделенные курсивом, можно найти в

в котором перечислены все шаблоны из книги Шаблоны архитектуры корпоративных приложений.

person hakre    schedule 22.12.2011
comment
Другой альтернативой является Propel. Хотя это ORM, а не DataMapper. (Но это мой любимый ;-) - person nikc.org; 22.12.2011
comment
Просто добавим, что Doctrine1 также является реализацией Active Records. Доктрина 2 — это Data Mapper. А для самых смелых :) вы также можете реализовать Active Records поверх Doctrine2 Data Mapper ;) - person ZolaKt; 22.12.2011

Другой альтернативой Doctrine и Propel является PHP Activerecords.

Doctrine и Propel — действительно могучие звери. Если вы делаете небольшой проект, я думаю, вам лучше использовать что-то более легкое.

Кроме того, если говорить о сторонних решениях, то существует множество фреймворков MVC для PHP, таких как: Kohana, Codeigniter, CakePHP, Zend (конечно)...

Все они имеют свои собственные реализации ORM, обычно более легкие альтернативы.

Для фреймворка Kohana также есть Auto modeler, который предположительно очень легкий.

Лично я использую Doctrine, но это огромный проект. Если бы я делал что-то меньшее, я бы скорее выбрал более легкую альтернативу.

person ZolaKt    schedule 22.12.2011