2009-03-04 16 views
6

Oprogramowanie, które będę budował, będzie wymagało "przełączania" aplikacji pomiędzy różnymi statusami. Niektóre zadania można wykonać zależnie od statusu, w jakim znajduje się aplikacja. Myślałem o użyciu enum jako statusStół Enum vs Lookup vs Enum Reflection vs State State

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

Ale potem pomyślałem, że może dobrze jest używać tabeli odnośników w bazie danych jako stan jest aktualizowany/re-uporządkowane dość często

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

w moim sprawa Muszę zrobić rzeczy takie jak

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

Myślę, że powyższy przypadek jest łatwiejszy do zrobienia z enum. Jednak jeśli chodzi o aktualizację porządku sortowania statusu lub opisu, będzie to dość trudne.

Czy należy używać odbicia, aby dynamicznie tworzyć wyliczenia na podstawie wartości z tabeli odnośników? Czy powinienem użyć wzoru stanu? Problem, który widzę z relacją enum to wpływ na wydajność. Wzorzec stanu może generować dużo zbędnego kodu.

Co myślisz? Z góry dziękuję!

Odpowiedz

3

Utworzę klasę statusu zawierającą różnice i zadzwonię do nich. Tak (w Pythonie):

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]) 

Szybka, łatwa do utrzymania funkcjonalności przedziały, a wraz z rozsądnym spadkowego wzór między państwami można udostępnić funkcje, które nie różnią.

+0

jak u obsłużyć pobieraniu z db i oddanych do obiektu bit bez instrukcji else, o czym wspomniałem w odpowiedzi 3? – Jeff

+0

Myślę, że trudno mi zrozumieć problem. Każdy z obiektów Status może zawierać dowolny kod, w tym trudne do obsadzenia rzutki, jeśli jest to konieczne. Obiekt aplikacji może pozostać taki sam; rozsyła połączenia różniące się od statusu wewnętrznego. –

+0

moimi problemami jest to, jak uniknąć ręcznego pisania instrukcji else, gdy tabela danych odsyłających z powrotem do obiektu w poprawnym stanie, w twoim przykładzie, w jaki sposób przesyłasz wiersz danych z powrotem do StatusZero lub StatusOne bez tego, czy w innych statystykach? – Jeff

7

Nie należy posypać kodu z tej kontroli wszędzie

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

Zamiast tego należy użyć wzorca państwowego. Zmień stan za każdym razem, gdy zmienia się tryb aplikacji i przekierowuj wszystkie wywołania na metody stanu. Będziesz mieć znacznie czystszy i łatwiejszy w utrzymaniu kod.

Jeśli chodzi o zmianę statusu, nie ma to nic wspólnego ze wzorem stanu. Możesz więc użyć dowolnego podejścia, które jest eleganckie.

0

Zrozumiałem, że wzorzec stanu jest całkiem dobry tylko dla UI lub tylko w pamięciach, gdzie w mojej sytuacji podczas pobierania danych z tabeli aplikacji nadal musi być instrukcja else, aby określić, do którego obiektu należy przesyłać.

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

nie widzę tego jako eleganckie rozwiązanie jak nadal muszę albo tablicę enum lub odnośnika do zapisania stanu aplikacji do bazy danych