Как вы организуете свою инфраструктуру MVC, поддерживая модули / плагины? [закрыто]

17

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

Стандарт MVC

/controller
/model
/view

Проблема: Нет разделения связанных компонентов (форум, блог, пользователь и т. Д.)

Модульный MVC

/blog
    /controller
    /model
    /view
/user
    /controller
    /model
    /view
/forum
    /controller
    /model
    /view

Выбор системы на основе модулей оставляет вас с проблемой.

  • Длинные имена (Forum_Model_Forum = forum / model / forum.php) (как Zend)
  • Файловая система выполняет поиск, is_file()чтобы определить, какая папка имеет модель форума? (Как и Кохана)

Есть ли у них какие-либо другие структуры MVC, которые хорошо работают при попытке разделить разные модули? Есть ли преимущества от этих структур, которые я пропускаю?

Xeoncross
источник
1
Я также хотел бы добавить, что мне нужна структура, совместимая с PSR-0, чтобы при необходимости я мог использовать такие библиотеки, как Zend и Doctrine.
Xeoncross

Ответы:

9

Пытаться:

/blog 
    /controller
    /view
/user
   /controller
    /view 
/forum
    /controller
    /view
/model
    User
    BlogPost
    Comment
    ....

Ваши модели - это сердце вашего приложения. Вы должны разработать и кодировать их как отдельный пакет. Контроллеры - это просто клиенты вашей модели, которые превращают активность пользователя в действия для вашей модели. Представление - это только один конкретный способ отображения данных из вашей модели. Если ваше приложение растет, вы можете пойти еще дальше, отделив клиентов от модели:

WebClient
    /blog 
        /controller
        /view
    /user
       /controller
        /view 
    /forum
        /controller
        /view
CommandLineClient
    delete_spam_posts_script
RestApiClient

/model
    User
    BlogPost
    Comment
    ....

Это должно сделать очевидным, что у вас может быть несколько клиентов, которые так или иначе взаимодействуют с одной моделью.

Матиас Веррэс
источник
+1, потому что я полностью согласен с вашим объяснением компонентов MVC и того, как они должны работать. Однако смысл модуля в том, что вы можете импортировать модули, созданные другими пользователями, поэтому наличие моделей вне пути к модулю делает его менее «перетаскиваемым». Тем не менее, ваш метод имеет смысл для приложений, которые не используют внешние плагины или модули.
Xeoncross
@ Xeoncross это правда, я действительно не учел возможность повторного использования здесь. Если это требование, вы действительно можете пойти еще дальше и иметь, например, модуль «Пользователь», который группирует модель User с его контроллером, и модуль Blog, который группирует модель BlogPost и Comment с его контроллерами. Как всегда: это зависит от контекста :-)
Матиас Веррэс
2

;)

Я нашел лучшую структуру для MVC / HMVC Framework вместе взятых. Для основного вам нужно использовать базовые контроллеры / модели / представления ... но для отдельных компонентов модулей курса ...

Так что в моей структуре MVC / HMVC структура выглядит так:

/application
  controllers/
  models/
  views/
  modules/
    blog/
      controllers/
      models/
      views/ 
    user/
      controllers/
      models/
      views/
    forum/
      controllers/
      models/
      views/

Также, если мне нужно, я добавляю в модули библиотеки, i18n или помощники.

Соглашение об именах легко, для контроллеров и моделей я добавляю суффиксы _Controller и _Model. Для контроллеров и моделей из модулей я также добавляю префикс с именем модуля, например. Профиль контроллера в модуле Пользователь будет назван User_Profile_Controller.

Так что очень легко и быстро найти то, что вам нужно.

Shogun
источник
1

Проблема: длинные имена (Forum_Model_Forum)

Систематическое именование классов помогает избежать конфликтов имен между компонентами. Длинное именование классов вряд ли приведет к серьезным потерям производительности. Я считаю эту схему именования довольно полезной при кодировании, потому что легко увидеть, что происходит откуда.

поиск в файловой системе (какая папка имеет модель форума?).

Это очень сильно зависит от того, как система была реализована, но структура файловой системы обычно следует соглашению, которое обеспечивает немедленный доступ к нужному компоненту без обширных поисков в файловой системе.

Вот пример, предположим, что должен использоваться компонент форума:

Информация:

  • Название компонента: форум
  • Имя контроллера: индекс

    $ controller_path = BASEDIR. 'модуль /'. $ component_name. '/ controller /'. $ controller_name. '.Php';

Также важно отметить, что при загрузке типичного веб-сайта возникают буквально сотни запросов к файловой системе, поэтому добавление некоторых не повредит.

Леа Хейс
источник
Действительно, серверные части не похожи на клиентские приложения, которые должны запускаться быстро, они могут занять время, необходимое для правильной настройки времени выполнения. Хорошая точка зрения.
Патрик Хьюз
0

У меня есть работа с сайтами, которые начали с первого «Стандартного MVC», но в итоге стали «Модульным MVC».

Если вы работаете на небольшом веб-сайте и не имеете большого опыта, вы можете начать со «Стандартного MVC». Если вы уже знаете, что веб-сайт будет очень сложным и большим, то вам придется привыкнуть к «Модульному MVC», это будет немного сложно в начале, но, в конце концов, вы привыкнете Это.

umlcat
источник
0

Я на самом деле работаю над фреймворком и использую комбинацию структуры каталогов на основе модулей и в свободной форме. Моя структура по умолчанию для кода сайта с использованием фреймворка:

/Configuration (stored a bunch ini files for security related information like passwords)
/Functions (stores file(s) with standard procedural functions)
/Libraries (general use classes)
/Models (all models go here)
/Modules (each module refers to one controller
/Modules/Site (controller class store in this folder if there is a controller)
/Modules/Site/Views (views for the controller)

У вас также может быть папка модуля, которая не относится к контроллеру, и есть один по умолчанию вызов Core, который используется для хранения общих шаблонов сайта, таких как верхний и нижний колонтитулы. Это дает мне лучшее из обоих миров. Вы можете легко узнать, где находится контроллер, поскольку в каждой папке один контроллер, но для классов, таких как модели, вам не нужно искать, где находятся файлы, так как они находятся в одном каталоге (что также обеспечивает чистоту имен моделей). ,

То, как я загружаю файлы, немного отличается, так как я позволяю пользователю настраивать различные каталоги, в которых могут находиться классы, поэтому я сначала анализирую каталоги и сохраняю все расположения файлов классов в файле json, а затем использую это для быстрого поиска все остальные запросы (хотя я ищу способы улучшить это).

ryanzec
источник
0

Ответ на это был продиктован предложением PSR-0 которое все крупные системы начинают адаптировать или уже приняли.

Структура является:

\Doctrine\Common\IsolatedClassLoader => /Doctrine/Common/IsolatedClassLoader.php
\Symfony\Core\Request => /Symfony/Core/Request.php
\Zend\Acl => /Zend/Acl.php
\Zend\Mail\Message => /Zend/Mail/Message.php

Это означает, что вы ничего не можете сделать, чтобы исправить длинные имена файлов:

$controller = new \Blog\Controller\Archive => /Blog/Controller/Archive.php

/Blog
    /Controller
        Archive.php
    /Model
    /View
/User
    /Controller
    /Model
    /View
/Forum
    /Controller
    /Model
    /View

Это также означает, что вы должны использовать тупые смешанные файлы вместо строчных (если вы не используете сторонние библиотеки, они не будут работать).

Xeoncross
источник
0

Решение Mathiases имеет большой смысл. И использование его структуры папок не мешает иметь подключаемый контент, например, добавление независимой / gallery / может выглядеть так

WebClient
    /blog 
        /controller
        /view
    /user (uses /model/User/)
       /controller
        /view 
    /forum
        /controller
        /view
    /gallery
        /controller
        /view
        /model
CommandLineClient
    delete_spam_posts_script
RestApiClient

/model
    User
    BlogPost
    Comment

Теперь у нас есть общая «модель» и независимые при необходимости

Тимо Хуовинен
источник