2010-03-09 24 views
5

Actualmente estoy reescribiendo una tienda en línea, pero solo el lado del cliente, es decir, el CMS, sigue siendo en su mayoría intacto. No estoy usando un marco preconstruido, ya que el sistema tiene que mantener la compatibilidad con el CMS y tengo que tener plena libertad de la estructura del código.¿Está bien terminar utilizando clases principalmente estáticas?

El nuevo sistema está basado exclusivamente en MVC y tengo un Bootstrapper que carga controladores basados ​​en el uri actual y los últimos modelos de uso para el trabajo real, tanto con sesiones como con la base de datos.

tl; dr Es mi primer proyecto sin un marco preconstruido.

No tengo mucha experiencia en cuanto a patrones de diseño. Sé cómo funcionan la mayoría de los populares pero nunca los han utilizado.

Ahora sospecho que el código huele porque todos mis modelos son clases que consisten puramente en métodos estáticos. No puedo encontrar ninguna ventaja de hacerlas de otra manera. De manera rutinaria necesito algunos de los métodos en varios lugares a través del código. Es decir. Necesito buscar al usuario conectado en el diseño principal, verificar los derechos de los usuarios para ver la página actual en bootstraper, mostrar el panel de usuario por el controlador. Necesitaría volver a crear una instancia de un objeto cada vez o mantener uno global si no estuviera usando estática. Tampoco habrá necesidad de más de una clase a la vez.

Me falta algo, porque aunque utilizo OOP, algunas de mis clases son contenedores sin sentido para sus métodos (y algunas veces algunas variables privadas). Podría haber estado usando PHP4 y funciones simples.

Cualquier comentario o consejo sería muy apreciado.

EDIT: a pesar de todas estas respuestas educadas, sigo sin estar convencido. Aunque probablemente sea por mi falta de experiencia, todavía no preveo que algo vaya mal con la configuración actual. Quiero decir que ni siquiera comprendo una situación en la que tenga inconvenientes debido a la arquitectura del código como lo es ahora. Espero no obtener una dura lección cuando ya es demasiado tarde para cambiar algo ...

Respuesta

5

Tienes razón, es un olor a código y todo el mundo te dirá que es baaaad.

Así que aquí sugieren en vez de hacer una autoevaluación de la gravedad del problema:

  • ¿Tiene clases con muchos getter y setter?

  • ¿Son sus funciones estáticas como la siguiente?

    En caso afirmativo, intente mover la lógica en la clase MyClass que ya será mucho más OO. Ese es un error clásico del mundo de los procedimientos/scripting.


static void myMethod(MyClass anObject) 
{ 
    // get value from anObject 
    // do some business logic 
    // set value of anObject 
} 

  • ¿Tiene una gran cantidad de estado global, tales como datos de hacer salir de la sesión actual?

    En caso afirmativo, evalúe si desea modificarlo. La forma OO sería pasar la sesión por la cadena de llamadas. Pero en la práctica, es conveniente acceder a la sesión como un objeto global. Pero impide la capacidad de prueba.Intente eliminar algún estado global y conviértalo en un objeto común que pase y manipule en los métodos.

hacer esta evaluación, y tratar de identificar utilidad clases, servicios clases y objetos del negocio . La clase de utilidad son clases de ayuda con métodos de utilidad (por ejemplo, formateo, conversión, etc.) que pueden ser estáticos. La clase de servicio hace algo de lógica de negocios, pero deberían ser apátridas y una instancia suficiente. Los objetos comerciales son user, products, article, etc. es donde debe concentrar su esfuerzo. Intenta convertir datos simples en objetos con incrustar algún comportamiento.

Eche un vistazo a should entity be dumb. Incluso si es para Java, los conceptos son generales.

EDITAR

Aquí está mi análisis basado en su comentario:

  • Usted no tienen un modelo de dominio con las entidades. Usted manipula la base de datos directamente.
  • Lo que usted llama su modelo, es a lo que llamo servicios y es donde realiza la lógica de negocios que manipula los datos. Las clases de servicio son stateless, que es correcto. Como señaló en la pregunta, entonces necesita volver a crearlos constantemente, crear una instancia global o usar métodos estáticos.

El paradigma de OO diría que debe tratar de tener un modelo de dominio donde correlacione su base de datos con entidades. Al menos tener un anemic domain model donde las entidades son contenedores de datos aburridos que se cargan/persisten en la base de datos. Entonces, el paradigma OO también diría que ponga un poco de lógica en las entidades si es posible.

También diría que los servicios se convierten en objetos para facilitar la composición y la reutilización. Si fuera el caso, podría, por ejemplo, ajustar todos los servicios con un interceptor para iniciar/detener las transacciones o realizar alguna comprobación de seguridad, lo que no podrá hacer con los métodos estáticos.

Lo que usted describe (no entidades + servicios de procedimientos sin estado) no se considera un gran diseño de OO. Sugeriría que introduzcas un modelo de dominio anémico al menos y DAO. Con respecto a los servicios de procedimientos sin puerto, esta es en realidad la realidad de muchas aplicaciones web: si no necesita más, puede cumplirlas.

Mis 2 centavos

+0

Ninguna de las tres afirmaciones se aplica a mí. Y solo uso los datos de la sesión si es necesario usarlos de todos modos, como durante el procesamiento del usuario y del carrito de compras, e incluso entonces, los datos cruciales residen en db. No necesito entidades como 'products' o' user' tampoco. No tendrían ningún método. Lo único que tengo que hacer con un producto, por ejemplo, es obtener datos sobre él desde db. Bootstraper llama una acción de un controlador y llama a algunos métodos de los modelos para establecer y obtener los datos requeridos. No tengo más tipos de clases, excepto cosas como el contenedor de db. – raveren

+0

@Raveren - si ese es el caso, esta es la base que debe tomar - que este sistema no sea OOP. Sé que mencionaste Los usuarios no necesitan ser una clase, pero podría ser si quisieras. Su clase de usuario un objeto de usuario => vuelve a un registro de usuario en su base de datos. – JonH

+0

Wow eso es mucho para entender. Ojalá tuviera una relación profesional con alguien con esa experiencia, es muy difícil para mí aprender de los libros de texto, no ejemplos o prácticas del mundo real ... Opté por dejar de hacer modelos 1: 1 * para las tablas de bases de datos * porque nuestro DB fue diseñado por un imbécil y quería que la estupidez se manejara centralmente, así que sí, tengo clases de servicio para la mayoría de las entidades, como 'obsequios '. Estos manejan todas las operaciones asociadas. Francamente, no puedo ver ninguna ganancia en las clases * wrapper * para cada tabla db, incluso si la estructura es lógica ... – raveren

4

Si principalmente solo está utilizando clases estáticas, realmente ha sacado el objeto de la programación orientada a objetos. No digo que estés haciendo las cosas incorrectamente, estoy diciendo que tal vez tu sistema no debería prestarse a OOP. Tal vez es una aplicación simple que requiere algunas funciones básicas de utilidad (envía correos electrónicos, etc.). En este caso, la mayor parte de su código se vuelve muy procesal.

Si se trata de bases de datos que podrían tener una clase estática dB, y una capa de negocio simple, y su aplicación PHP interactúa con su capa de negocio que a su vez interactúa con la capa de base de datos. Esto se convierte en la arquitectura típica de 3 niveles (a algunas personas les gusta referirse a esto como 4 t-iers y separar la base de datos real de la capa de datos, lo mismo).

Si realmente no está llamando a métodos que requieren un objeto de lo que es el objetivo de todas estas clases estáticas, solo una pregunta para hacerse.

1

Sería cauteloso al usar variables estáticas y clases en aplicaciones web. Si realmente debe compartir una instancia entre usuarios, entonces debería estar bien tener una única instancia (patrón de diseño de búsqueda "Singleton").

Sin embargo, si intenta mantener el estado en todas las páginas, debe hacerlo mediante el uso de ViewState o mediante el uso del objeto Session.

Si tuviera una variable estática global, podría tener una situación en la que los usuarios concurrentes luchan por actualizar el mismo valor.

+0

No estoy usando ASP.NET. Tu último párrafo también se perdió en mí. – raveren

+0

En el último párrafo, dice que si tiene más de 1 usuario activo en el sitio a la vez, y ambos están en el sitio, esa variable que es estática se compartirá, ambos tienen la misma variable y causarán problemas de concurrencia . Si no sabe qué simultaneidad DEBE conocer al respecto o tendrá graves problemas de seguridad en un portal de pagos. –

+0

Eso es lo que pensé que quería decir, pero las variables de PHP, estáticas o no, no se comparten entre sesiones de usuario. – raveren

-1

Existen ventajas al usar métodos estáticos. Una de ellas es que, dado que no puedes heredarlas, funcionan mejor. Pero usarlos todo el tiempo te limita. El paradigma OOP completo se basa en la reutilización de clases base a través del uso de la herencia.

+0

Bueno, yo uso herencias en las clases de controlador, pero cada modelo es demasiado único para compartir propiedades entre ellos. +1 para la sugerencia de rendimiento. – raveren

4

Una cosa que puede notar es que si planea realizar algún tipo de prueba de unidad con burla/punteado, es probable que tenga dificultades ya que las clases y los métodos estáticos no son fáciles de simular, probar o probar.

+0

No, no haré pruebas unitarias, pero gracias por la nota. – raveren

1

Respuesta corta: Está bien pero está renunciando a los beneficios de OOP.

Un razonamiento detrás del uso de objetos es que la mayoría de las veces hay más de un tipo de objeto que desempeña un rol. Por ejemplo, puede intercambiar su objeto de acceso a datos DBVendor1 con un objeto de acceso a datos DBVendor2 que tenga la misma interfaz. Esto es especialmente útil si está usando pruebas unitarias y necesita intercambiar objetos que realmente funcionan con objetos ficticios (burlas y trozos). Piensa en tus objetos con la misma interfaz que los ladrillos Lego con diferentes colores que se unen y son fácilmente intercambiables. Y simplemente no puedes hacer eso con objetos estáticos.

Por supuesto, la mayor flexibilidad de los objetos tiene un precio: la inicialización de los objetos y su unión es más trabajo (como usted escribió) y conduce a más códigos y objetos que juntan otros objetos. Aquí es donde entran en juego los patrones de diseño creativo como builder y factory.

Si desea seguir esa ruta, le aconsejo que lea dependency injection y utilice DI framework.

1

Técnicamente no hay nada malo en hacerlo. Pero prácticamente estás perdiendo muchos de los beneficios de la programación orientada a objetos. También escriba el código/funcionalidad en los que pertenecen al .. por ejemplo:

user.doSomeTask() 

en el objeto de usuario tiene más sentido que

UserUtils.doSomeTask(User user) 

Utilizando conceptos de POO que abstraer la funcionalidad que le corresponde a, y en futuro te ayuda a cambiar tu código, extender la funcionalidad más fácilmente que usar los métodos estáticos.

Cuestiones relacionadas