tags:

views:

169

answers:

3

Hi all,

I am designing a class for log entries of my mail server. I have parsed the log entries and created the class hierarchy. Now I need to save the in memory representation to the disk. I need to save it to multiple destinations like mysql and disk files. I am at a loss to find out the proper way to design the persistence mechanism. The challenges are:

  1. How to pass persistence initialization information like filename, db connection parameters passed to them. The options I can think of are all ugly for eg:

    1.1 Constructor: it becomes ugly as I add more persistence.

    1.2 Method: Object.mysql_params(" "), again butt ugly

  2. "Correct" method name to call each persistance mechanism: eg: Object.save_mysql, Object.save_file, or Object.save (mysql) and Object.save(file)

I am sure there is some pattern to solve this particular problem. I am using ruby as my language, with out any rails, ie pure ruby code. Any clue is much welcome.

raj

+2  A: 

Personally I'd break things out a bit - the object representing a log entry really shouldn't be worrying about how it should save it, so I'd probably create a MySQLObjectStore, and FileObjectStore, which you can configure separately, and gets passed the object to save. You could give your Object class a class variable which contains the store type, to be called on save.

class Object
  cattr_accessor :store

  def save
    @@store.save(self)
  end
end

class MySQLObjectStore
  def initialize(connection_string)
    # Connect to DB etc...
  end

  def save(obj)
    # Write to database
  end
end

store = MySQLObjectStore.new("user:password@localhost/database")
Object.store = store

obj = Object.new(foo)
obj.save
Jon Wood
Thanks a lot for the answer. All 3 answers received suggested the same approach.
Rajkumar S
+1  A: 

Unless I completely misunstood your question, I would recommend using the Strategy pattern. Instead of having this one class try to write to all of those different sources, delegate that responsibility to another class. Have a bunch of LogWriter classes, each one with the responsibility of persiting the object to a particular data store. So you might have a MySqlLogWriter, FileLogWriter, etc.

Each one of these objects can be instantiated on their own and then the persitence object can be passed to it:

lw = FileLogWriter.new "log_file.txt"
lw.Write(log)
Turp
Thanks for the answer. All three answers suggested the same thing. I am accepting the first answer.
Rajkumar S
+1  A: 

You really should separate your concerns here. The message and the way the message is saved are two separate things. In fact, in many cases, it would also be more efficient not to open a new mysql connection or new file pointer for every message.

I would create a Saver class, extended by FileSaver and MysqlSaver, each of which have a save method, which is passed your message. The saver is responsible for pulling out the parts of the message that apply and saving them to the medium it's responsible for.

Lucas Oman
Thanks for the answer. All three answers suggested the same thing. I am accepting the first answer.
Rajkumar S