2010-02-19 9 views
5

Este es un problema de diseño al que me enfrento regularmente y me gustaría encontrar algunas ideas generales sobre el tema. El código provisto aquí es solo un ejemplo.Diseño de OOP: Cómo incorporar el manejo de DB en los objetos de aplicación

En la fase de diseño es fácil decidir que necesita un objeto:

User 
========== 
Unique ID 
Login name 
Password 
Full name 

Y es fácil convertirlo en un objeto de base de datos:

CREATE TABLE user (
    user_id INT NOT NULL PRIMARY KEY, 
    username VARCHAR(15) NOT NULL UNIQUE, 
    password_hash CHAR(32) NOT NULL, 
    full_name VARCHAR(50) 
); 

Mis dudas comienzan a nivel de PHP. La conversión obvia es:

<?php 
class User{ 
    public $user_id, $username, $full_name; 
} 
?> 

Sin embargo, ¿cómo debo completar los valores reales?

puedo mantener el DB-agnóstico clase:

<?php 
class User{ 
    public $user_id, $username, $full_name; 
    public function __construct($user_id, $username, $full_name){ 
     $this->user_id = $user_id; 
     $this->username = $username; 
     $this->full_name = $full_name; 
    } 
} 
?> 

Pero luego tenga que ejecutar la consulta en otro lugar ...

que puede encapsular dentro del constructor de la clase:

<?php 
class User{ 
    public $user_id, $username, $full_name; 
    public function __construct($user_id){ 
     $sql = 'SELECT username, full_name FROM user WHERE user_id=?'; 
     $parameters = array($user_id); 
     $res = get_row_from_db($sql, $parameters); 

     $this->user_id = $user_id; 
     $this->username = $res['username']; 
     $this->full_name = $res['username']; 
    } 
} 
?> 

Esto se ve elegante pero me impide hacer muchas cosas con la clase:

  • Validar un usuario por nombre de usuario y contraseña ($ user_id no se conoce aún)
  • Imprimir información de usuario de mensajes en el foro (no puedo pagar 100 consultas a 100 usuarios mostrar)

Lo más probable es que Necesito definir varias clases, pero no estoy seguro de cómo organizarlo. Una clase base y muchas clases para niños? Clases independientes? Clase individual con métodos específicos? Tal vez es un patrón de diseño bien conocido, pero me enseñaron la programación de procedimientos.

También apreciaría algunas ideas sobre: ​​

  • Manejo de una colección de usuarios
  • información en sesión de Almacenamiento de manera DB no necesita ser consultada en cada petición que

==== PARA LOS REGISTROS ====

He etiquetado la respuesta de Gordon como respuesta, ya que proporciona una lectura interesante. Lo que sea, vale la pena señalar que he encontrado un very illustrative code snippet en uno de los comentarios de los usuarios en la página de serialización de objetos del manual de PHP que se puede resumir de la siguiente manera:

  • Se utiliza una clase.
  • Una instancia representa un usuario específico.
  • El constructor se alimenta con los detalles del usuario.
  • La clase proporciona métodos estáticos para la funcionalidad que se requiere antes de poder tener una instancia, p. obtener un usuario de DB por ID o nombre.
  • Las instancias de usuario se pueden serializar como datos de sesión.

Al no ser un gurú de OOP, lo encontré muy simple pero limpio y útil. Los textos OOP tienden a complicar las tareas simples y mi trabajo diario consiste principalmente en proyectos pequeños.

+0

¿Cómo harías para crear nuevos usuarios con el segundo enfoque? Los nuevos usuarios no existirán en la base de datos. – Rune

+0

El fragmento de código que menciona parece una implementación del patrón ActiveRecord para mí. – Gordon

Respuesta

7

Depende de su arquitectura. Los patrones de arquitectura de cuatro común de origen de datos se pueden encontrar en Martin Fowler 's Patterns of Enterprise Application Architecture:

  • Table Data Gateway

    un objeto que actúa como una puerta de enlace a una tabla de base de datos. Una instancia maneja todas las filas en la tabla.

  • Row Data Gateway

    un objeto que actúa como una puerta de entrada a un registro único en una fuente de datos. Hay una instancia por fila.

  • Active Record

    Un objeto que envuelve una fila de una tabla de base de datos o vista, encapsula el acceso a la base de datos, y añade la lógica de dominio en esos datos.

  • Data Mapper

    Una capa de mapeadores que se mueve datos entre los objetos y una base de datos mientras que los mantiene independiente el uno del otro y el propio asignador.

Otros patrones:

2

Ha considerado el uso de un objeto de biblioteca Relational Mapping como Doctrine o Propel?

+0

No realmente. Estoy buscando mejorar mis habilidades de diseño en lugar de aprender una biblioteca de terceros. –

+0

Me pregunto si mejorar tus habilidades de diseño en un área donde ya existen buenas soluciones es el lugar ** más ** efectivo para mejorar. Si usa una biblioteca decente de terceros, libera tiempo para mejorar sus habilidades de diseño en áreas donde no existen soluciones de terceros. –

+0

Aún así, quiero poder escribir un buen código incluso sin marcos. Una especie de cultura general, ya sabes. –

0

El Zend Framework quickstart tiene una, bastante fácil de entender, visión general de los modelos y mapeadores (términos google'able), junto con algo de código fuente.

Cuestiones relacionadas