Pregunta

El software que construiré incluirá la aplicación " " " cambiando entre diferentes estados mucho. Se pueden realizar ciertas tareas dependiendo del estado en que se encuentre una aplicación. Estaba pensando en usar enum como el estado

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 usar la tabla de búsqueda en la base de datos, ya que el estado se actualiza / vuelve a ordenar 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, necesito 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 de hacer con enumeración. Sin embargo, cuando se trata de actualizar el orden de clasificación de estado o la descripción, será bastante difícil.

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

¿Qué piensas? Gracias de antemano!

¿Fue útil?

Solución

Me gustaría crear una clase de estado que contenga las diferencias y llamarlas. Entonces (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 de mantener la funcionalidad compartimentada, y con un patrón de herencia razonable entre los estados, puede compartir las funciones que no difieren.

Otros consejos

No debes rociar tu 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 }

En su lugar, usa el patrón de estado. Cambie el estado siempre 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. Así que puedes usar cualquier enfoque que sea elegante.

entiendo que el patrón de estado es bastante bueno para las ejecuciones solo de IU o solo en memoria, donde en mi situación cuando recupero datos de la tabla de la aplicación, todavía debe haber una declaración if else para determinar a qué objeto lanzar.

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. ya que todavía necesito una enumeración o una tabla de búsqueda para guardar el estado de la aplicación en la base de datos

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top