2010-02-04 2 views
6

У меня есть приложение MVC, написанное с Zend Framework, которое извлекает данные из базы данных Oracle 10g и отображает эти данные в таблицах и списках и визуально обогащает эти данные с помощью цветов и диаграмм. Нет ORM и не задействовано создание, обновление или удаление, просто чистое чтение. Данные вставляются из другого приложения. Данные в БД моделируются после концепций, которые они представляют и получают доступ к представлениям БД, которые объединяют эти данные из разных других таблиц (устаревшие, не могут быть изменены), например.Как бы вы моделировали это приложение?

| Event ID | Start    | End     | Status | Created_By | 
----------------------------------------------------------------------------- 
| 12345678 | 2009-10-01 12:00:00 | 2009-10-01 12:15:00 | booked | John Doe | 
| 12345679 | 2009-11-01 13:00:00 | 2009-12-01 12:00:00 | booked | John Doe | 
| 12345680 | 2009-11-01 13:00:00 | 2009-12-01 12:00:00 | tba | Jane Doe | 

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

Моего текущий подход работает примерно так:

Request --> Controller 
      | <--> sanitizes and returns Request params 
      | ---> Facade (capsules steps to fetch View Data) 
      |  | <--> Table Data Gateway builds Query for requested View 
      |  | <--> Query Decorator¹ applies User/Client settings 
      |  | <--> DB Adapter fetches RecordSet from decorated Query 
      | <----returns Recordset 
      | <--> applies RecordSet to View 
      | <--> Data-Aware ViewHelper render RecordSet (and View) 
Response <--returns rendered View 

¹Запросы Decorator можно прочитать в сохраненных настройках пользователя/клиента и добавить его в основном объект запроса, возвращенный TDG на лета.

Однако в последнее время я сомневаюсь в этом подходе и хочу его улучшить. Я предполагаю, что смогу полностью удалить TDG и полностью создать представление View полностью из пользовательского интерфейса; основанный только на структуре БД. Пользователям это наверняка понравится. Дело в том, что View должен много знать о данных. ViewHelpers должны знать имена столбцов, чтобы обогащать данные, и часто они делают это в отношении нескольких столбцов в наборах записей. Они не могут быть родовыми, и что-то говорит мне, что это все равно. Это похоже на мишмаш. Я просто не могу понять, почему.

Любые рисунки, идеи и мнения - очень ценятся. Я знаю, что вопрос несколько расплывчатый, но, как я уже сказал, я не могу определить, что заставляет меня сомневаться в этом. Поэтому я предполагаю, что я ищу подходящие подходы к созданию пользовательских и клиентских настраиваемых приложений, ориентированных на базу данных. Мне, конечно, не нужно решение, просто некоторые идеи и, возможно, несколько ссылок, чтобы посмотреть, как другие люди подходят к этой проблеме, поэтому я могу принять это во внимание при следующем рефакторинге.

Примечание
Я оставляю этот вопрос открытым на весь период до принятия ответа. Любой вход оценивается.

+1

Пожалуйста, простите мой скептицизм, но: взгляд должен знать много о данных? ViewHelpers должны знать имена столбцов? * Почему? * Это почти похоже на эффект внутренней платформы, переосмысление Microsoft Access или Cognos. Настройка вне определенного порога - зло; это могут быть * требования *, которые нуждаются в рефакторинге. – Aaronaught

+0

@ Скептицизм Аароношен в порядке. Именно это заставило меня задавать этот вопрос :) Отвечать на ваш вопрос: представьте, что есть ViewHelper, который отображает панель временной шкалы на основе * Start *, * End * и * Status * как часть таблицы, отображающей весь набор записей в дополнение к ViewHelper который отображает PieChart на основе * Created_By *. – Gordon

ответ

13

После перечитывания ваш вопрос несколько раз, и размышляя о ней немного, я считаю, что я бы подытожить ситуацию таким образом:

«M» отсутствует на «MVC».

На данный момент вы создали схему реляционной базы данных вручную, так что она имеет сопоставление 1: 1 с вашей моделью домена. И это здорово, это делает отображение очень простым, но набор записей по-прежнему не является классом домена.

Термин модель в контексте MVC относится к модели домена , а не реляционной модели. Если у вас есть реляционная база данных, поддерживающая это приложение, вам нужно какое-то сопоставление. Это не значит, что вам нужна полноценная структура ORM, например Doctrine, хотя я считаю, что эти инструменты облегчают мою жизнь даже для небольших проектов, но вам нужно что-то. На самом деле, Zend Framework даже подробно рассказывает о сопоставлении модели домена в Quick Start.

Я не думаю, что вам нужно удалить TDG. Абстракции хороши. Вытащить его, чтобы сделать ваше приложение немного более компактным, я бы сравнил с тем, чтобы войти в офисное здание и вырвать телефонную систему на том основании, что сотрудники могут просто использовать свои сотовые телефоны. Они могут, но вы не хотите их, так же, как вы не хотите, чтобы ваши представления бросали SQL-запросы непосредственно в базу данных. Это неэффективно и в целом трудно справиться.

Моя версия архитектуры будет выглядеть следующим образом:

Request --> Controller 
      | <--> sanitizes and returns Request params 
      | ---> Facade (encapsulates steps to fetch View Data) 
      |  | <--> Table Data Gateway builds Query for requested View 
      |  | <--> Query Decorator applies User/Client settings 
      |  | <--> DB Adapter fetches RecordSet from decorated Query 
***   |  | <--> Mapping layer converts RecordSet to Domain Model 
***   | <----returns Model 
***   | <--> applies Model to View 
***   | <--> Data-Aware ViewHelper render Model (and View) 
Response <--returns rendered View 

Я пометил линии изменения с ***. Действительно, единственное, что я изменил, это то, что вместо сбора набора записей с фасада он подбирает модель (вероятно, массив классов домена) и применяет к к представлению.

Вместо условий, таких как $row['Status'] в вашем представлении [Помощник], у вас будет $event->status, что безопаснее и проще поддерживать в долгосрочной перспективе. Нет названия столбца, просто свойство.

Теперь вы прямо упомянули в самом верху своего вопроса, что у вас нет ORM, поэтому я думаю, что вы, вероятно, знаете об этом и, возможно, просто нуждаетесь в толчке. Эти подозрительные сомнения в вашем уме, вероятно, следуют следующим образом: Что делать, если это не всегда доступно для чтения? Что делать, если модель данных становится более сложной? Что, если люди начнут просить более сложные отчеты?

Все эти вещи являются причиной, почему у вас есть модель домена, почему это на самом деле фундаментальный строительный блок MVC: В конце концов, умственная модель ваши пользователи будут выпадают из синхронизации с моделью данных, по ряду причин, по которым я не буду здесь. Дело в том, что это почти всегда происходит.

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

Нет, я не знаю. Только вы можете это решить. Что я знаю может сказать, что парадигма MVC как специфическая архитектура не делает вам много хорошего без надлежащей модели домена. Это немного лучше, но не , что намного лучше, чем просто иметь встроенные запросы или фасадные вызовы на каждой странице. Без модели MVC не намного больше, чем причудливая схема перезаписи URL-адресов.

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

Надеюсь, что это тот вид ответа, который вы искали!

+0

Спасибо Аарон. На самом деле, вы довольно точно знаете мои сомнения. Я хотел иметь ORM и модель домена с самого начала по причинам, о которых вы упомянули, но об этом говорил начальник, потому что он был обеспокоен влиянием производительности, которое у него было бы. – Gordon

+0

@ Gordon: Ах, микроменеджмент, теперь все это имеет смысл! Если ваш сайт не имеет дело с миллионами пользователей в день, хорошие абстракции и хороший дизайн должны быть более важными приоритетами, чем производительность (и даже тогда есть другие варианты). Влияние производительности модели домена практически ничтожно; большинство приложений с поддержкой базы данных связаны с I/O и проводят большую часть времени, ожидая результатов запросов. Удачи! – Aaronaught

+0

Еще раз спасибо. Наслаждайся своей заслуженной наградой :) – Gordon

0

Конструкция схемы БД имеет различные требования (производительность запроса/записи, масштабируемость) как хороший пользовательский интерфейс (хороший поток страниц, поддерживающий работу людей или работу процессов). Поэтому часто подход UI и DB трудно сопоставить напрямую.

В качестве плохого примера я помню приложение с использованием «Oracle Forms», которое непосредственно представляло общий вид из структуры базы данных. Для людей, не относящихся к технике, часто было очень непротиворечивым в использовании.

Все еще я думаю, что в вашем случае, если представление может быть непосредственно сопоставлено с схемой DB, обязательно избавитесь от ненужных абстракций-слоев, кода и упростите систему. Решите требования как можно проще.

0

Для динамического получения данных из таблицы на основе пользовательского ввода вы можете использовать сетку данных компонентов Zend_Dojo. Вы можете создать один объект TDG, который будет переназначен в новую таблицу на основе пользовательского ввода.

http://zendguru.wordpress.com/2009/01/08/dojo-grid-in-zend-framework-creating-nice-and-cool-grid-in-php-using-zend-framework-and-dojo/

Смежные вопросы