2009-03-04 12 views
6

Il software che verrà creato comporterà un "passaggio di applicazione" tra diversi stati. Alcune attività possono essere eseguite in base allo stato dell'applicazione. Stavo pensando di utilizzare enum come lo statoEnum vs Tabella di ricerca 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 
} 

Ma poi ho pensato che forse è bene utilizzare tabella di ricerca nel database come lo stato viene aggiornato/riordinata molto spesso

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

Nella mia caso ho bisogno di fare le cose come

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

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

Devo utilizzare la riflessione per creare dinamicamente enum in base ai valori della tabella di ricerca? O dovrei usare lo schema di stato? Il problema che vedo con enume refezione è l'impatto sulle prestazioni. E lo schema di stato può produrre molto codice ridondante.

Cosa ne pensi? Grazie in anticipo!

risposta

3

Vorrei creare una classe Status che contenga le differenze e chiamarle. Così (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à compartimenti stagni, e con un modello di ereditarietà ragionevole tra gli Stati è possibile condividere le funzioni che non differiscono.

+0

come si fa gestire u il recupero dal db e cast di oggetto un po 'se non altro come ho detto nella risposta 3? – Jeff

+0

Credo di avere difficoltà a capire il problema. Ciascuno degli oggetti Status può contenere qualsiasi codice desiderato, inclusi i cast hard-switch, se necessario. L'oggetto Application può rimanere lo stesso; invia le chiamate che differiscono dallo stato interno. –

+0

i miei problemi è come evitare di scrivere a mano se in un'altra istruzione quando si esegue il cast della tabella di dati sull'oggetto nello stato corretto, nell'esempio, come si fa a lanciare la riga di dati su StatusZero o StatusOne senza altre istruzioni? – Jeff

7

Non si dovrebbe cospargere il codice con questo controllo ovunque

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

Al contrario, utilizzare il modello di Stato. Cambia lo stato ogni volta che la modalità dell'applicazione cambia e inoltra tutte le chiamate ai metodi dello stato. Avrai un codice molto più pulito e facile da gestire.

Come per cambiare lo stato, che non ha nulla a che fare con il modello di stato. Quindi puoi usare qualunque approccio sia elegante.

0

La mia comprensione è che lo schema di stato è abbastanza buono solo per l'interfaccia utente o solo per le esecuzioni di memoria, dove nella mia situazione quando si recuperano i dati dalla tabella delle applicazioni, deve essere presente un'altra istruzione per determinare a 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 vedo questo come una soluzione elegante come ho ancora bisogno sia una tabella di enum o di ricerca per salvare lo stato di applicazione nel database