Domanda

Il software che costruirò coinvolgerà " applicazione " passare da uno stato diverso molto. Alcune attività possono essere eseguite in base allo stato in cui si trova un'applicazione. Stavo pensando di usare enum come status

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

Ma poi ho pensato che forse è bene usare la tabella di ricerca nel database poiché lo stato viene aggiornato / riordinato abbastanza spesso

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

Nel mio caso devo fare cose come

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

Penso che il caso precedente sia più facile da fare con enum. Tuttavia, quando si tratta di aggiornare l'ordinamento o la descrizione dello stato, sarà piuttosto difficile.

Dovrei usare la riflessione per creare dinamicamente enum in base ai valori della tabella di ricerca? O dovrei usare il modello di stato? Il problema che vedo con enfection refection è l'impatto sulle prestazioni. E il modello di stato può produrre molto codice ridondante.

Cosa ne pensi? Grazie in anticipo!

È stato utile?

Soluzione

Creerei una classe Status che contiene le differenze e le chiamerei. Quindi (in 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])

Veloce, facile da mantenere la funzionalità suddivisa in compartimenti e con un ragionevole modello di ereditarietà tra gli stati è possibile condividere le funzioni che non differiscono.

Altri suggerimenti

Non dovresti cospargere il tuo codice con questo segno di spunta ovunque

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

Invece, usa il modello di stato. Cambia lo stato ogni volta che cambia la modalità dell'applicazione e inoltra tutte le tue chiamate ai metodi dello stato. Avrai un codice molto più pulito e più facile da mantenere.

Per quanto riguarda la modifica dello stato, ciò non ha nulla a che fare con il modello di stato. Quindi puoi usare qualunque approccio sia elegante.

la mia comprensione è che il modello di stato è abbastanza buono per le sole esecuzioni dell'interfaccia utente o solo in memoria, dove nella mia situazione quando si recuperano i dati dalla tabella dell'applicazione, ci deve essere ancora un'istruzione if else per determinare su quale oggetto eseguire il cast.

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;
}

Non la vedo come una soluzione elegante poiché ho ancora bisogno di una tabella enum o di ricerca per salvare lo stato dell'applicazione nel database

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top