2012-04-23 17 views
6

Estoy escribiendo mi propio framework MVC en PHP, solo para fines de aprendizaje. No fue realmente difícil tener una clase enrutador/despachador para llamar al controlador/acción correcto, etc.Un modelo base en PHP MVC, ¿bueno o malo?

Pero ahora estoy en la parte en la que voy a usar modelos. O en realidad, la capa del modelo. Pero hay algo que me confunde.

Muchos otros frameworks MVC tienen un 'BaseModel'. He leído que esto es una mala práctica, porque el "Modelo" no debe verse como otra clase. Pero como una 'capa' real, que puede contener elementos como el patrón 'asignador' o el patrón 'repositorio', etc.

Pero para ser sincero, no veo ninguna ventaja en eso. Para mí, una clase 'BaseModel' parece ser la forma más rápida de hacerlo, con los mismos resultados.

simplemente puedo hacer algo como:

class User extends BaseModel 
{ 
    // the GetUserBy* could easily be something that's handled by the 
    // BaseModel class, like in the Repo pattern. 

    public function getUserByName ($name) 
    { 
     // no error handling of any kind, just for simplicity 
     return $this->db->exec("SELECT * FROM users WHERE name='".$name."'"); 
    } 

    // $data = array 
    public function saveUser ($data) 
    { 
     // Make sure no extra fields are added to the array 
     $user = array ('name' => $data['name'], 
         'address' => $data['address']); 

     $this->db->autoSave ($user); 
    } 
} 

Pero si yo iría a un patrón repositorio entonces tengo que crear los siguientes: repositorios Entidades DAO

Las entidades tienen agregados a otros repositorios. Básicamente estoy escribiendo manualmente mi esquema de base de datos completo para objetos ...

Al final, ¿cuál es la diferencia? Excepto que probablemente podría haber ahorrado un montón de tiempo simplemente usando una clase de BaseModel ...

¿Pero por qué todavía se considera algo malo? No es que el patrón repo desacople mi aplicación más de lo que estoy haciendo ahora. Porque para mí, esos patrones mencionados anteriormente parecen estar muy sobrevalorados. Probablemente solo funcionaría en una aplicación que tiene un estado compartido; Guarde objetos localmente (en el repositorio) y confírmelos más adelante.

Es por eso que creo que nadie puede responder a esta ...

pero todavía estoy esperando ver una respuesta decente que me hace ir: "ahhhh ... ¿Qué estaba pensando .... ". Pero si no, entonces estoy seguro de mi caso de que el BaseModel no es nada malo y que la mayoría de los bloggers son solo un montón de ovejas :-)

+1

parece bonito [Propel] (http://www.propelorm.org/) -ish – Alp

+2

¿Puede darnos un enlace a una de estas publicaciones de blog? – webbiedave

+1

@Alp el ejemplo del código? Propel es solo un ORM, no voy en esa dirección, porque me gusta escribir consultas yo mismo. No realicé ORMs. Pero prefiero no usarlos tampoco. Algo de 'magia' está bien, pero no demasiado. Pero esa es toda una historia diferente. – Vivendi

Respuesta

1

No es que el patrón de recompra desacopla mi solicitud más de lo que estoy haciendo ahora

Su aplicación está estrechamente unida a los componentes de base de datos SQL (que son, en efecto, actuando como su mapeador) . Sin embargo, a pesar de esto, su diseño se parece mucho más a un Repository que a un enfoque Active Record (que es probable que la mayoría de estos bloggers a los que hace referencia estén molestos).

registros activos encapsulan no sólo los datos, sino también el acceso a la base de datos:

$user = new User(); 
$user->setUsername('jane'); 
$user->setEmail('[email protected]'); 
$user->save(); 

Es mejor tener los objetos de registro sean conscientes de la capa de persistencia (separación de intereses). Su "base" hace precisamente eso al devolver matrices de datos de usuario y cuando esas matrices se modifican, deben pasarse a la "base" del usuario para su guardado. Puede cambiar su nomenclatura a:

class UserRepo extends BaseRepo 
{ 
    // user-specific repo code... 
} 

$userRepo = $this->getRepo('User'); 
$user = $userRepo->getUserByName('jane'); 
$user['email'] = '[email protected]'; 
$userRepo->save($user); 

No hay nada de malo en tener un repositorio base.

+0

Supongo que tienes razón. Parece un patrón Repo de alguna manera. Pero no estoy usando ninguna clase Entity u Value Objects.Como también dije en mi publicación, eso se parece mucho a la reescritura del esquema de la base de datos a 'objetos'. --- Mi 'UserRepo' simplemente devuelve matrices tomadas directamente de consultas SQL. No veo el uso de Entities/VO. Porque si usara Entidades que básicamente digo, denme mis resultados como una matriz de mi consulta, asócielos en mi objeto Entity y utilícenlo para obtener/establecer datos. No veo por qué debería perder el tiempo en eso (Entidades). ¿Alguna idea sobre eso ...? – Vivendi

+0

El mapeo de sus registros en objetos les permite todas las opciones de OOP si lo desea (una estructura definida, interfaces, sugerencias tipográficas, etc.). La matriz basada es más rápida, utiliza menos recursos y puede pasarlos a las funciones de matriz nativas de PHP. Es un compromiso y es totalmente tu llamado. – webbiedave

0

La clase Model debe ser abstracta, solo definiendo métodos sin implementarlos. En cuanto a su modelo User, puede escribir fácilmente una interfaz GettingUsers que tendría todas esas funciones, e implementarla en el modelo User.

+2

esta es una respuesta muy libre y ninguna declaración es seguida con una explicación decente por qué es así. Además, si la clase de modelo solo define los métodos sin ninguna lógica de implementación, entonces debería ser una interfaz, no abstracta. como dije, sé que podría "fácilmente" separarlo en modelos, clases abstractas, interfaces. pero * qué * es el beneficio opuesto solo a un modelo base. Parece que ni siquiera trataste de responder eso. – Vivendi

+1

@Vivendi - pregunta interesante, pero por favor sea civil. La verdad ha existido por algún tiempo, como lo demuestra el representante, y eres nuevo aquí. – halfer

+1

@halfer Lo siento, espero que nadie haya ofendido mi respuesta. No quería ser grosero de todos modos. Debería haber puesto ciertas cosas en mi comentario de una manera diferente. – Vivendi

0

No utilizaría ningún modelo base, ya que la mayoría de sus modelos no tendrán una interfaz uniforme con la que se ajusten. Podrías crear una clase base para varios tipos diferentes de modelos (que es solo programación básica orientada a objetos) si así lo deseas.

En general, creo que se supone que los modelos son los componentes "sueltos" que se conectan con un controlador y se muestran con una o más vistas. Realmente no pueden tener una interfaz uniforme porque todos harían cosas diferentes: algunos ni siquiera pueden hablar con un almacén de persistencia, algunos pueden no ser persistentes y/o algunos pueden estar compuestos por otros modelos.

1

Si está intentando aprender buenas prácticas de MVC a partir de frameworks PHP, entonces lo está haciendo mal. Incluso los mejores marcos en PHP están plagados de fallas y errores de diseño.

Los marcos que tienen "BaseModel" generalmente están implementando algún tipo de ORM. Y el patrón más popular aquí es ActiveRecord. Es bueno para las tablas simples, sin relaciones con los demás (básicamente - getters/setters glorificados). Pero comienza a descomponerse, cuando se trata de estructuras y consultas más complejas. Por lo general, causa extenso technical debt.

La otra razón por la cual este enfoque causa problemas es que su "modelo" en este caso también tiene responsabilidades. Su lógica de negocio está estrechamente ligada al almacenamiento y el almacenamiento está soldado a la lógica. A medida que la aplicación crezca, tales "modelos" acumularán ataques.

Y no, el "grupo de bloggers" no son ovejas. Acaban de leer libros sobre arquitectura de aplicaciones y programación orientada a objetos. ¿Cuándo fue la última vez que leíste un libro sobre este tema?

+0

Estoy leyendo muchas cosas contradictorias :). Pero, ¿cómo lo harías para no acumular tanto en el modelo? Parece que tienes modelos de grasa, controladores de grasa, una biblioteca en alguna parte, procedimientos almacenados, etc. ¿Qué haces? Tengo que evitar las ideas de ActiveRecord debido a muchas consultas complejas. AR se siente como un truco y se vuelve enorme. También me gusta SQL, que luego me acopla fuertemente. Gracias. – johnny

+0

@ johnny Creo que tus principales problemas provienen de tener mala información sobre lo que realmente es el "modelo". Tal vez [esta publicación] (http://stackoverflow.com/a/5864000/727208) ayuda un poco. –

Cuestiones relacionadas