NOTA: Esta pregunta se ha actualizado para proporcionar más detalles y conocimientos que los anteriores.Primeros pasos con el diseño de software utilizando MVC, OO y patrones de diseño
ACTUALIZACIÓN: Solo quiero agradecer a todos los que respondieron. Todavía estoy a oscuras sobre qué patrón de diseño funcionaría mejor para el Widget. Tal vez uno de los patrones de fábrica o constructor?
Estoy empezando un nuevo proyecto y necesito utilizar MVC, OO y patrones de diseño.
Aquí está la idea: Imagine una página que muestra un conjunto de widgets. Estos widgets son (normalmente) gráficos que se basan en datos contenidos en varias tablas separadas en la base de datos. Uso un ejemplo de página en ejecución que informa sobre el rendimiento de un alumno.
requisitos de alto nivel
- una página que muestra un conjunto de widgets (HTML solamente).
- Los datos del widget se basarán en una consulta de base de datos.
- la página se puede usar para ver conjuntos de datos separados que contienen datos distribuidos de manera similar. Por ejemplo, una sola página mostrará widgets que informan sobre diversos aspectos del rendimiento de un solo alumno.
- desea ver el rendimiento de otro alumno, abra otra página. No es necesario mostrar diferentes widgets para diferentes estudiantes (aunque puede ser bueno tenerlo después).
- Puede haber muchos estudiantes, pero los datos contenidos en la base de datos se presentan de manera similar para todos los estudiantes.
- la forma en que se muestra un widget se puede cambiar fácilmente (por ejemplo, cambiar un widget para que no se muestre como un gráfico circular para mostrarlo como un gráfico de barras).
- widgets deben poder crearse rápidamente.
Requisitos nivel bajo
- datos Actualmente no cambia de modo de widgets no tendrán que actualizar automáticamente a sí mismos.
- Los widgets pueden representar una relación de dos cosas (por ejemplo, una proporción de pruebas fallidas a pruebas exitosas como un gráfico circular), una serie de puntos o, a veces, un único valor numérico.
- El desarrollo de nuevos widgets debería ser pan comido, no es necesario modificar el código existente.
- Marco a utilizar: Zend Framework, basado en MVC.
Hay (mínimamente) tres cosas para definir un widget: el conjunto de datos para informar sobre (en el ejemplo anterior, el estudiante ID), la consulta que describe la métrica que se informa, y un modo de render (diagrama de barras, series de tiempo, etc.).
Aquí es un paso en la subdivisión de las responsabilidades de cada capa de la MVC:
Ver: vistas Zend son plantillas HTML con PHP inyectados. Contendrán uno de varios tipos de widgets.Los widgets son de varias formas, incluyendo: las imágenes JPEG estáticos (cargados desde un sitio remoto es decir: <img src="http://widgetssite.com?x=2&y=3"/>
, los widgets javascript basados JSON, o gráficos de diversos tipos (piechart, gráfico de barras, etc.)
controlador: crea los widgets, los asigna a la vista después. El conjunto de widgets que se debe mostrar en una página debe mantenerse en alguna parte. Como no puedo pensar en una buena manera de hacer esto en la vista, agregaré esto a los controladores. responsabilidades por ahora. Si hay un lugar mejor para esto, por favor gritar. El controlador también tendrá que manejar otros parámetros de entrada y pasarlos al widget. Por ejemplo, el id data_set que se puede pasar en la línea url como http:/.../report/?student_id=42
Modelo: El modelo, en Zend Framework, es responsable de extraer los datos y, como tal, muy probablemente contenga una clase para cada widget para acceder a la base de datos.
Algunos puntos:
El modelo aquí, representa los datos de un widget en particular. Entonces, necesariamente, necesitará saber cuál será la consulta, para juntar las tablas necesarias para obtener esos datos.
Hay un paso de procesamiento adicional que probablemente sea necesario antes de que el widget pueda presentar los datos. Esto depende de qué renderizador se utilizará. A veces puede requerir la formación de una url de los datos devueltos. Otras veces, una matriz JSON. Otras veces tal vez creando un margen de beneficio. Esto puede ir en el modelo o el controlador o la vista. A menos que alguien pueda pensar en una buena razón para moverlo al controlador o a la vista, probablemente sea mejor dejar esto en vivo en el modelo y mantener la vista y el controlador delgados.
Del mismo modo, un widget se compone de 3 cosas, sus parámetros, sus datos y su procesador.
Una gran parte de la pregunta es: Qué es una buena manera de representar el widget en un diseño orientado a objetos? Ya le pregunté esto una vez, no pude obtener una respuesta. ¿Existe algún patrón de diseño que pueda aplicarse a los widgets que tenga más sentido para este proyecto?
Aquí está un primer paso en una clase bastante simple para el widget:
class Widget{ //method called by the view render() {//output the markup based on the widget Type and interleaved the processed data} //methods called by the controller: public function __construct() {//recieve arguments for widget type (query and renderer), call create()} public function create() {//tell the widget to build the query, execute it, and filter the data} public function process_data() {//transform into JSON, an html entity etc} //methods called by the model: public function build_query() {...}; public function execute_query() {...}; public function filter_data() {...}; }
En cuanto a él, que ya se puede ver algunos problemas.
Por ejemplo, es fácil pasar el widget que se creó en el controlador a la Vista para representar.
Pero cuando se trata de implementar el modelo, no parece tan sencillo. Table Gateway Pattern es más fácil de implementar que ORM. Pero dado que el patrón de puerta de enlace de tabla tiene una clase para cada modelo/tabla, no parece ajustarse a la factura. Podría crear un modelo para una tabla en particular y luego, crear una instancia de cualquier otro modelo necesario. Pero eso no parece ajustarse al Patrón Table Gateway, sino al patrón ORM. ¿Se puede implementar el patrón de puerta de enlace de tabla con varias tablas? ¿Qué alternativas hay? ¿Tiene sentido que el controlador cree el widget y el widget crea el Modelo?
Otro problema que surge es que este diseño no permite una fácil creación de widgets. es decir. Digamos que quería crear un PiechartWidget, ¿cuánto código se puede reutilizar?¿No tendría más sentido usar algunas ideas OO, como una interfaz o clases/métodos abstractos y herencia?
Digamos que extraigo la clase de Widget, por lo que solo los métodos compartidos se definen concretamente y el resto se declaran como métodos abstractos. La revisión de la clase Widget para que sea abstracta (segundo paso):
abstract class Widget{ private $_type; private $_renderer; //methods called by the controller: //receive arguments for widget type (query and renderer), protected function __construct($type, $renderer) { $this->_type = $type; $this->_render = $renderer; $this->create(); } //tell the widget to build the query, execute it, and filter the data private function create() { $this->build_query(); $this->execute_query(); $this->filter_data(); } //methods called by the model: abstract protected function build_query(); protected function execute_query() { //common method } abstract protected function filter_data(); //method called by controller to tranform data for view //transform into JSON, an html entity etc abstract protected function process_data(); //method called by the view //output the markup based on the widget Type and interleave the processed data abstract protected function render(); }
Es este un buen diseño? ¿Cómo puede ser mejorado?
Supongo que escribir un nuevo widget requerirá al menos un nuevo código para generar la consulta, y tal vez filtrar los datos, pero debería poder usar el código preexistente para casi todo el resto de su funcionalidad, incluyendo los renderizadores que ya existen
Estoy esperando que alguien pudiera proporcionar al menos alguna información sobre este diseño. Validarlo? Arráncalo. Llámame un idiota. Eso está bien también. Podría usar cualquier tracción delantera.
Algunas preguntas específicas:
Q1. ¿Cuál es la mejor manera de implementar los procesadores, como parte de la clase de Widget o como una clase separada? 1a. Si está separado, ¿cómo interactuaría con la (s) clase (s) de widget?
Q2. ¿Cómo podría mejorar este diseño para simplificar la creación de nuevos tipos de widgets?
Q3. Y, por último, siento que me falta algo aquí con respecto a la encapsulación de datos. ¿Cómo se relaciona la encapsulación de datos con los requisitos y se desarrolla en este escenario?
http://en.wikipedia.org/wiki/Presentation-abstraction-control – alex
Esto está usando Zend Framework, por lo que MVC es inherente. – hinghoo
¿Todos los datos estarían en forma de proporciones como el ejemplo que usted da, o algunos widgets mostrarían una proporción mientras que otros mostrarían, por ejemplo, un conjunto de puntos? – mattjames