2009-03-04 25 views
6

El software que construiré implicará un cambio de "aplicación" entre diferentes estados. Ciertas tareas pueden hacerse dependiendo del estado en que se encuentre una aplicación. Estaba pensando acerca del uso de enumeración como el estadoEnum vs Lookup table vs Enum reflection vs State pattern

public class Application 
{ 
    public int Id {get;set;} 
    public Status {get;set;} 
} 
public enum Status 
{ 
    [Description("New")]New = 1, [Description("Closed")]Closed = 2 
} 

Pero luego pensé que tal vez es bueno utilizar la tabla de consulta en la base de datos de estado no se actualiza/re-ordenado con bastante frecuencia

table status (id int pk, desc string, sort_order int) 
table application (id int pk, status_id int fk) 

En mi caso de que necesite hacer cosas como

if (application.Status == Status.New) 
{ //do something } 
else if (application.Status == Status.Closed) 
{ //do other things } 

creo que el caso anterior es más fácil que ver con la enumeración. Sin embargo, cuando se trata de actualizar el orden de clasificación del estado o la descripción, será bastante difícil.

¿Debo usar la reflexión para crear dinámicamente enumeración basada en los valores de la tabla de búsqueda? ¿O debería usar el patrón de estado? El problema que veo con la rectificación de enum es el impacto en el rendimiento. Y el patrón de estado puede producir una gran cantidad de código redundante.

¿Qué opinas? ¡Gracias por adelantado!

Respuesta

3

Creé una clase de Estado que contiene las diferencias, y las llamo. Por lo tanto (en Python):

class StatusZero(object): 
    def call_me(self, app): 
     print 'Hello, from ' + app.name 
     return db.prepare_specific_status_zero_request() 


class StatusOne(object): 
    def call_me(self, app): 
     print 'Hi, from ' + app.name 
     return db.prepare_specific_status_one_request() 

states = { 'status_zero' : StatusZero(), 'status_one' : StatusOne() } 

class Application(object): 
    name = 'My App' 
    status = states['status_zero'] 

    def change_state(self, state): 
     status = state 

    def call_me(self): 
     state_key = self.status.call_me(self) 
     self.change_state(states[state_key]) 

rápido, fácil mantener la funcionalidad compartimentada, y con un patrón de herencia razonable entre los estados que puede compartir las funciones que no difieren.

+0

u ¿cómo manejar la recuperación de db y el reparto de objetos poco sin declaración if else como mencioné en la respuesta 3? – Jeff

+0

Supongo que me cuesta entender el problema. Cada uno de los objetos de estado puede contener cualquier código que desee, incluidos moldes cableados si es necesario. El objeto Aplicación puede permanecer igual; distribuye las llamadas que difieren en el Estado interno. –

+0

mis problemas es cómo evitar la declaración escrita a mano si al volver la tabla de datos al objeto en el estado correcto, en su ejemplo, ¿cómo se transfiere la fila de datos a StatusZero o StatusOne sin if else statment? – Jeff

7

No se debe rociar el código con esta comprobación en todas partes

if (application.Status == Status.New) 
{ //do something } 
else if (application.Status == Status.Closed) 
{ //do other things } 

su lugar, utilice el patrón de estado. Cambie el estado cada vez que cambie el modo de la aplicación y reenvíe todas sus llamadas a los métodos del estado. Tendrás un código mucho más limpio y fácil de mantener.

En cuanto a cambiar el estado, eso no tiene nada que ver con el patrón de estado. Entonces puedes usar cualquier enfoque que sea elegante.

0

Según entiendo, el patrón de estado es bastante bueno solo para UI o en ejecuciones de solo memoria, cuando en mi situación al recuperar datos de la tabla de aplicaciones, todavía falta ser enunciado else para determinar a qué objeto convertir.

public AbstractApplication convert_db_application_to_object(obj db_application) 
{ 
    AbstractApplication app; 
    if (db_application.Status == (int)Status.New) 
     app = application_factory.create(application_state_new); 
    else if(db_application.Status == (int)Status.Closed) 
     app = application_factory.create(application_state_closed); 

    return app; 
} 

no veo esto como una solución elegante como yo todavía necesito ya sea una mesa o enumeración de búsqueda para guardar el estado de la aplicación en base de datos