2011-12-02 7 views
5

Me he dado cuenta de que todos mis modelos se ven muy similares. La mayoría de ellos tienden a seguir un patrón en el que se trata de colecciones de métodos que contienen código de registro activo que son apenas variaciones leves entre sí. Aquí hay un ejemplo:Mis modelos tienden a tener el mismo aspecto

class Site extends CI_Model { 

    public function get_site_by_id($id) 
    { 
     // Active record code to get site by id 
    } 

    public function get_sites_by_user_id($user_id) 
    { 
     // ... 
    } 

    // ... 

    public function get_site_by_user_id_and_url_string($user_id, $url_string) 
    { 
     // ... 
    } 

    // Non active record methods and business logic 
    // ... 

} 

Este enfoque ha funcionado bien para mí, pero me pregunto si hay una solución más elegante. Simplemente no me parece correcto que deba crear un nuevo método cada vez que necesite buscar datos de una nueva manera. ¿Es esta práctica común o me falta una forma de refactorizar esto?

+1

Esto sería principalmente un efecto secundario de utilizar un grupo de [registro activo] (http://martinfowler.com/eaaCatalog/activeRecord.html) como sustituto de la capa de modo implementado completo. Puede encontrar [this] (http://stackoverflow.com/a/11943107/727208) relevante para las opciones de refactorización. –

Respuesta

2

Estrictamente siguiente a su solicitud, puede agregar una clase intermedia entre la principal clase de modelo (CI_Model) y su clase (Sitio), algo así como

class MyCommonMethodsClass extends CI_Model { 
} 

y que se extendería en sus clases (Sitio) , mientras le pone el código común. Eso funcionaría y podría ser de alguna manera 'elegante'. De hecho, al final terminaría agregando su crud básico, acciones adaptadas al sitio.

Ahora, si eso es 'limpio', eso es otra cosa. De nuevo, estrictamente hablando, el modelo lo hace. Se ocupa de getters comunes y 'avanzados'. Y sí, casi siempre tienen la tendencia a tener el mismo código en todo su sitio web. El problema es que, aunque eso se ve bien en tu código (menos código), estás técnicamente sacrificando la abstracción entre tu lógica empresarial y la base de datos. ¿Eres un modelo purista o práctico?

+0

+1 para "purista" frente a "práctico": muchas veces, las personas hacen más trabajo por sí mismas tratando de hacer las cosas de la manera "correcta". – swatkins

+0

Sí, eso es correcto, pongamos una aplicación en blanco y esperemos a que los problemas lleguen. –

1

Creo que esto es cuestión de opinión, pero creo que la mejor práctica es crear algún tipo de modelo Create, Retrieve, Update, Delete (CRUD) que realice muchas funciones SQL básicas como GetID, UpdateByID, GetById, etc.

Los modelos CRUD solo pueden ayudarlo con más consultas modulares. Pero tiene sentido llamar a una función llamada GetId y pasarle algunos parámetros que tener diferentes funciones para cada tabla.

Como digo, los CRUD solo pueden llegar tan lejos. Por ejemplo, tendría sentido tener una función que consulte una tabla de usuarios de la base de datos para verificar si un usuario ha verificado y el nombre de usuario & coincide con la contraseña. Como esta es una función única y no abstracta, debe tener su propia función definida.

También como una práctica recomendada, el acceso a la lógica y la base de datos nunca debe mezclarse en el mismo archivo.

0

Es una práctica común tener diferentes métodos para manejar la obtención de sus datos de esa manera. El Single Responsibility Principal establece que cada objeto solo debe hacer una cosa, al hacer múltiples métodos que obtienen datos muy específicos, está creando código fácil de depurar y fácil de depurar.

+0

Quizás para funciones que tienden a hacer cosas específicas pero no para funciones muy abstractas que pueden aplicarse a muchas situaciones diferentes. –

+0

También creo que malinterpretas lo que quieren decir con 'Responsabilidad única', esto significa que la función tiene una acción, como un singleton que activa una conexión de base de datos, pero que aún puede reutilizarse. La 'responsabilidad única' es una parte de la encapsulación en OOP, siendo la encapsulación el principio del código reutilizable. –

+0

Se supone que los modelos son muy específicos, ese es el punto de un modelo, la "responsabilidad única" del modelo es una verificación específica del dominio, con el modelo tiene métodos que hacen una tarea específica. Si tiene varios modelos que hacen lo mismo, probablemente tenga olor a código, luego mueva el código común a una nueva clase y luego amplíe su modelo con la clase común. –

0

Si tiene varias clases que proporcionan esencialmente la misma funcionalidad, esto sugiere que puede haber algo mal con su jerarquía de clases (el llamado "olor a código"). Si tienen interacciones similares, eso sugiere que están relacionadas de alguna manera. Si ese es el caso, entonces existe la posibilidad de que todos hereden de una superclase común que implementa la funcionalidad común a todas sus subclases, con cada subclase simplemente especializando la funcionalidad generalizada de la superclase.

Las ventajas de este enfoque son:

  • No estás repitiendo el trabajo (SPOT, SECO)
  • Código que interactúa con las clases pueden ser escritas de una manera más general y puede manejar cualquier objeto que hereda de la superclase (sustitución)
0

No creo que haya nada de malo en crear una clase de modelo 'base' para extenderle otros modelos. Si es sólido y está bien probado, puede hacerte la vida más fácil. ¿Cuál es el sentido de crear las mismas funciones CRUD una y otra vez?

Otra ventaja de hacerlo es que puede tener un repositorio de desarrollo base que clona para iniciar todos los proyectos nuevos.

Si necesita un ejemplo de cómo hacerlo, mire un question que le pregunté anteriormente.

También puede hacer lo mismo con su controllers.

Cuestiones relacionadas