Enum vs tabla de búsqueda vs Enum reflexión vs patrón de estado
-
03-07-2019 - |
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!
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