Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enum vs Lookup table vs Enum reflection vs State pattern

The software I will be building will involve "application" switching between different status a lot. Certain tasks can be done depends on the status an application is at. I was thinking about using enum as the status

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

But then I thought maybe it’s good to use lookup table in the database as status does get updated/re-ordered quite often

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

In my case I need to do things like

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

I think the above case is easier to do with enum. However when it comes to updating status sort order or description it'll be quite hard.

Should I used reflection to dynamically create enum based on values from lookup table? Or should I use state pattern? The problem I see with enum relfection is performance impact. And state pattern can produce a lot of redundant code.

What do you think? Thanks in advance!

like image 684
Jeff Avatar asked Mar 04 '09 06:03

Jeff


2 Answers

You should not sprinkle your code with this check everywhere

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

Instead, use the state pattern. Change the state whenever the mode of the application changes and forward all your calls to the state's methods. You'll have a much cleaner and easier to maintain code.

As for changing the status, that has got nothing do with the state pattern. So you can use whichever approach is elegant.

like image 51
Frederick The Fool Avatar answered Sep 22 '22 07:09

Frederick The Fool


I'd create a Status class that contains the differences, and call those. So (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])

Fast, easy to keep the functionality compartmentalized, and with a reasonable inheritance pattern between the states you can share the functions which don't differ.

like image 29
Chris B. Avatar answered Sep 24 '22 07:09

Chris B.