implementing mvc - using observer pattern - beginner to OOP

Discussion in 'Ruby' started by Adam Akhtar, Nov 8, 2008.

  1. Adam Akhtar

    Adam Akhtar Guest

    Hi I started making a simple command line todo list application as a way
    to get better at OOP. I decided to use a flat file db gem called
    kirbybase.

    Anyway the more I started programming it, the more it started to
    resemble spaghetti code with ui getting mixed in with logic so I started
    using google to find some patterns that might help.

    One that came up was MVC which ive heard about from my very very limited
    rails experience.

    I tried implementing it (more like fudging it) but I dont think im giong
    abotu it the right way. Ive looked on google for ruby specific stuff but
    keep getting rails results that only provide an overview of it.

    Can anyone provide any light on how to go about implementing it.

    Will Kirby Base essentially be my model? Or will the model interact with
    kirbybase?

    If i use the observer pattern I guess the model should be the observable
    with the views being registerd observers. Right?

    What about the controller? What is it obesvign and who is observing it?

    All menues etc will live in the views i think with user choices e..g
    "add task" being registered in the controller along with the program
    logic... is that right?

    Regards to their interaction, do all talk to each other or is there a
    chain of command. I.e. the models seem to speak to the views by updating
    them, the controllers seem to talk to about the views and models? is
    that right?

    Finally does the singleton pattern come into play here? If i wrap the
    database into a class should only one instance be made?

    Apologies for my inexperience ;-)

    I know this may sound like overkill for a simply todo command line app
    but i think it will make great practice and setme up for rails in the
    future.

    any help will be of great assistance
    --
    Posted via http://www.ruby-forum.com/.
    Adam Akhtar, Nov 8, 2008
    #1
    1. Advertising

  2. 2008/11/8 Adam Akhtar :
    > Hi I started making a simple command line todo list application as a way
    > to get better at OOP. I decided to use a flat file db gem called
    > kirbybase.
    >
    > Anyway the more I started programming it, the more it started to
    > resemble spaghetti code with ui getting mixed in with logic so I started
    > using google to find some patterns that might help.
    >
    > One that came up was MVC which ive heard about from my very very limited
    > rails experience.


    You should try SimpleConsole,

    http://simpleconsole.rubyforge.org

    sudo gem install simpleconsole

    -- Jean-Fran=E7ois.

    --=20
    http://twitter.com/underflow_
    Jean-François Trân, Nov 8, 2008
    #2
    1. Advertising

  3. Hi,

    On 8-Nov-08, at 12:57 AM, Adam Akhtar wrote:

    > Hi I started making a simple command line todo list application as a =20=


    > way
    > to get better at OOP. I decided to use a flat file db gem called
    > kirbybase.
    >
    > Anyway the more I started programming it, the more it started to
    > resemble spaghetti code with ui getting mixed in with logic so I =20
    > started
    > using google to find some patterns that might help.
    >
    > One that came up was MVC which ive heard about from my very very =20
    > limited
    > rails experience.


    This is pretty much what MVC tries to deal with. There are variations =20=

    on MVC as well.

    >
    >
    > I tried implementing it (more like fudging it) but I dont think im =20
    > giong
    > abotu it the right way. Ive looked on google for ruby specific stuff =20=


    > but
    > keep getting rails results that only provide an overview of it.
    >
    > Can anyone provide any light on how to go about implementing it.


    You would have had better luck looking into the smalltalk world for =20
    MVC than the ruby world.

    These two papers are pretty good I think. The second paper talks about =20=

    two kinds of model: application and domain -- this is important.

    <http://www.create.ucsb.edu/~stp/PostScript/mvc.pdf>
    <http://www.jdl.co.uk/briefings/MVC.pdf>

    Then read about value objects/models here: =
    <http://c2.com/ppr/vmodels.html=20
    > Value models seem like a bit of a pain, but worth knowing about. =20

    You won't likely need them at the start, and MVC + value models can be =20=

    a bit complicated, but when your application starts getting complex =20
    they can help.

    As Jean-Fran=C3=A7ois pointed out, you don't have to do this yourself. =
    On =20
    the other hand, if you are looking to learn OOP this is a pretty good =20=

    way, it might be a hard way, but you'll certainly have a handle on OOP =20=

    by the time you're done :)

    >
    >
    > Will Kirby Base essentially be my model? Or will the model interact =20=


    > with
    > kirbybase?


    MVC is an *object oriented* thing. So your model will interact with =20
    kirbybase.

    The rest of your questions are better answered by the papers I linked =20=

    to.

    Cheers,
    Bob

    >
    >
    > If i use the observer pattern I guess the model should be the =20
    > observable
    > with the views being registerd observers. Right?
    >
    > What about the controller? What is it obesvign and who is observing =20=


    > it?
    >
    > All menues etc will live in the views i think with user choices e..g
    > "add task" being registered in the controller along with the program
    > logic... is that right?
    >
    > Regards to their interaction, do all talk to each other or is there a
    > chain of command. I.e. the models seem to speak to the views by =20
    > updating
    > them, the controllers seem to talk to about the views and models? is
    > that right?
    >
    > Finally does the singleton pattern come into play here? If i wrap the
    > database into a class should only one instance be made?
    >
    > Apologies for my inexperience ;-)
    >
    > I know this may sound like overkill for a simply todo command line app
    > but i think it will make great practice and setme up for rails in the
    > future.
    >
    > any help will be of great assistance
    > --=20
    > Posted via http://www.ruby-forum.com/.
    >
    Bob Hutchison, Nov 8, 2008
    #3
  4. Adam Akhtar

    Adam Akhtar Guest

    Hi thanks for the replies. I looked into MVC and i think its proably
    overkill for what im doing and probably stretching my abilities too far
    at this stage though does look like a good pattern. One think I dont
    understand is what the controller would actually do in my case where im
    just using the command line. I feel like i only need a model and then a
    view/controller wrapped into one.

    Well ive decided to just scrap mvc and just get the thing working. I
    created two classes. One is a database class which wraps up kirbybase (a
    flat file db plugin for ruby) and the second is basically the U.I i.e.
    menu logic, getting input and presenting menus and stuff.

    Im just not sure how to code their communication to each other.

    class DB
    ..
    ..

    def insert (task)
    ...
    #some kirybbase calls here.
    ..
    end

    end


    class UI

    blahblahblah

    def menu
    puts "|A| to add a task"
    ...
    ...
    end

    def navigation
    menu
    input = gets.chomp
    case input
    when "A"
    add task
    etc
    etc
    etc
    end




    def add_task
    new_task = new_task_form
    add_task_to_db(new_task)
    end

    def add_task_to_db(new_task)
    **what goes here?
    end

    def new_task_form
    puts "Enter title for task"
    new_task = Task.new
    new_task.title = gets.chomp
    return new_task
    end

    in add_task_to_db Im wondering the best way to pass the new_task
    completed in the UI object over to my db object. Is there someway to let
    the db class see the value of new_task? Should i be using an observer
    pattern here? Should they be observing one another (if possible?)?

    Im probably overlooking somthing dead simple here but im way confused.

    any help most appreciated.



    --
    Posted via http://www.ruby-forum.com/.
    Adam Akhtar, Nov 11, 2008
    #4
  5. Adam Akhtar

    Hugh Sasse Guest

    On Tue, 11 Nov 2008, Adam Akhtar wrote:

    > Hi thanks for the replies. I looked into MVC and i think its proably
    > overkill for what im doing and probably stretching my abilities too far


    It only needs to be a really simple controller.

    > at this stage though does look like a good pattern. One think I dont
    > understand is what the controller would actually do in my case where im
    > just using the command line. I feel like i only need a model and then a


    It would take requests from the UI and only access the database when it
    needs to. It will handle the business logic of what gets added and
    removed. The UI would concentrate on how stuff looks to the user.
    The idea, as you said that you want to get the hang of OO, is that each
    class has a well-defined role. If two classes are in each other's pockets
    then that is not good, because a change in one means a change in the other.
    If two becomes 8, then this gets truly horrible.

    The code that handles the money in your bank shouldn't care what cheques
    look like when they are printed. But you want some logic in there that
    handles what goes to a cheque when it's printed. If the bank decides
    that cheques should have a blue background this year, rather than yellow,
    then you don't want to change the code that sends the amounts to the
    cheque printer.

    > view/controller wrapped into one.
    >
    > Well ive decided to just scrap mvc and just get the thing working. I
    > created two classes. One is a database class which wraps up kirbybase (a
    > flat file db plugin for ruby) and the second is basically the U.I i.e.
    > menu logic, getting input and presenting menus and stuff.
    >
    > Im just not sure how to code their communication to each other.


    That communication is the role of the controller.
    >
    > class DB
    > ..
    > ..
    >
    > def insert (task)
    > ...
    > #some kirybbase calls here.
    > ..
    > end
    >
    > end
    >
    >
    > class UI
    >
    > blahblahblah
    >
    > def menu
    > puts "|A| to add a task"
    > ...
    > ...
    > end
    >


    This bit below goes in your controller. It's a DB, so you will want to handle
    Create, Read, Update, Delete for the tasks. That's probably enough to start
    with, and Read and Update mean you'll need to search for tasks, so that
    means you'll need to Tell the UI to display them.
    > def navigation
    > menu
    > input = gets.chomp
    > case input
    > when "A"
    > add task
    > etc
    > etc
    > etc
    > end
    >
    >
    >
    >
    > def add_task

    new_task = UI.new_task_form
    DB. add_task(new_task)
    > end
    >
    > def add_task_to_db(new_task)
    > **what goes here?

    # Nothing, it's already in the DB code. Isn't it?
    > end
    >

    This bit belongs in the UI
    > def new_task_form
    > puts "Enter title for task"

    # don't put this here: new_task = Task.new
    > # new_task.title = gets.chomp
    > # return new_task


    # You just want the UI to return a bunch of fields. the controller
    # can validate them, and tell the UI: UI.bzzzt("Try again!").
    > end
    >
    > in add_task_to_db Im wondering the best way to pass the new_task
    > completed in the UI object over to my db object. Is there someway to let


    You don't, you just pass the possibly dodgy data back from the UI to
    the controller. The controller checks before it stuffs a load of spam
    into the DB.

    > the db class see the value of new_task? Should i be using an observer
    > pattern here? Should they be observing one another (if possible?)?


    I don't think you need obsverver if the controller controls what is happening.
    It will sequence which bits of UI show up. It might get errors from the
    DB when you ask about all those tasks you didn't get round to adding. Then
    it will have to tell the UI to display error messages, rather than task
    lists.

    >
    > Im probably overlooking somthing dead simple here but im way confused.
    >
    > any help most appreciated.
    >


    HTH
    Hugh
    Hugh Sasse, Nov 11, 2008
    #5
  6. Adam Akhtar

    Adam Akhtar Guest

    Thank you so much for your help clearing that up. Im much closer to
    understanding how things fit together. Id just like to confirm
    somethings (please dont think im asking you to the write the code for
    me, im not, i just like to be a bit more certain before writing out
    lines of code ;-) )

    > This bit below goes in your controller. It's a DB, so you will want to
    > handle
    > Create, Read, Update, Delete for the tasks. That's probably enough to
    > start
    > with, and Read and Update mean you'll need to search for tasks, so that
    > means you'll need to Tell the UI to display them.



    Ok so I have three classes now.
    DB which encapsulates the DB and all the tables (at the moment there is
    only one for tasks, in the future Id have anohter for categories,
    projects etc)

    Task_Controller which handles the menu navigation logic and any logic
    such as what to do with a task when a user marks it as complete etc. It
    will have DB related tasks such as Create, Read, Update, Delete.

    Task_UI which will have basically all the output to the screen such as
    menu text, prompts etc.

    From this

    >> def add_task

    > new_task = UI.new_task_form
    > DB. add_task(new_task)
    >> end


    Question 1
    it seems your implying my class Task_Controller should define an
    instance of the DB and the UI within it, is that correct?

    Question 2
    Presuming Im correct about that, what is the relationship of the db to
    the view? When the DB is updated is it the DBs job to inform the view
    for it to update or does it inform the controller or .... C. do nothing
    at all and just let the controller tell the view to update when it
    thinks its best.


    > This bit belongs in the UI
    >> def new_task_form
    >> puts "Enter title for task"

    > # don't put this here: new_task = Task.new
    >> # new_task.title = gets.chomp
    >> # return new_task

    > # You just want the UI to return a bunch of fields. the controller
    > # can validate them, and tell the UI: UI.bzzzt("Try again!").
    >> end


    ok so i shouldnt create an instance of task in the UI. Rahter just
    return a bunch of fields (a hash \ array? )which contain the input from
    the user and let the controller figure out what each field represents
    and whether its valid input. The controller will create a Task instance
    and then pass it to the DB.

    Question 3
    When the UI presents say a form for a task to the user to fill is it
    good practice to have things like

    userinput = gets.chomp

    in the UI or should that be handled by the controller. Im wondering to
    what degree logic and presentation are seperated.

    --
    Posted via http://www.ruby-forum.com/.
    Adam Akhtar, Nov 11, 2008
    #6
  7. Adam Akhtar

    Adam Akhtar Guest

    Adam Akhtar, Nov 11, 2008
    #7
  8. Re: implementing mvc - using observer pattern - beginner to

    Adam Akhtar wrote:
    > class DB
    > ..
    > ..
    >
    > def insert (task)
    > ...
    > #some kirybbase calls here.
    > ..
    > end
    >
    > end


    In a typical MVC, the model would be a class which represents the task,
    rather than a class which represents the database connection (the latter
    would be hidden away behind it). Hence something like:

    t = Task.new
    t.name = "Paint shed"
    t.save!

    ...

    t = Task.find_by_name("Paint shed")
    t.completed_at = Time.now
    t.save!

    If you only have a DB class, then the controller can talk to it
    directly, but you've lost the "M" from MVC.

    This may be no loss - simple models are often dumb and just map directly
    to SQL rows. But sometimes it's useful to put logic in the model layer,
    e.g.

    def full_name
    "#{first_name} #{last_name}"
    end

    def full_name=(name)
    f, l = name.split(" ", 2)
    self.first_name = f
    self.last_name = l
    end

    Here we have a virtual accessor that makes it look like the model has a
    full_name column, even though the database actually has two separate
    columns, first_name and last_name.

    > class UI
    >
    > blahblahblah
    >
    > def menu
    > puts "|A| to add a task"
    > ...
    > ...
    > end
    >
    > def navigation
    > menu
    > input = gets.chomp
    > case input
    > when "A"
    > add task
    > etc
    > etc
    > etc
    > end


    If you merge the view into the controller then you might get:

    class TasksController
    def list
    tasks = Task.find:)all)
    puts "You have #{tasks.size} tasks"
    tasks.each { |t| puts t.name }
    end

    def show(n)
    task = Task.find(n)
    puts "Showing task #{n}"
    puts t.name
    end

    def create
    print "Enter task name:"
    name = gets.chomp
    print "Enter completion date:"
    date = gets.chomp

    t = Task.new
    t.name = name
    t.date = date
    t.save!
    show(t.id)
    end
    end

    But what's missing is the sequencing: after showing task n there may be
    associated actions (e.g. edit task n, delete task n, return to listing)

    Maybe a good way to approach this is to start as a simple Rails app with
    a sqlite3 backend. Then you can consider how best to build the UI part
    which will (a) show the current view, and (b) prompt for next action.
    --
    Posted via http://www.ruby-forum.com/.
    Brian Candler, Nov 11, 2008
    #8
  9. Adam Akhtar

    Adam Akhtar Guest

    Re: implementing mvc - using observer pattern - beginner to

    Thank you Brian and Hugh for your help. Ive got a much clearer picture
    of where i should be heading with this now. I have a good enough
    foundation to actually start coding something and then when mistakes and
    spaghetti come flying my way I can look at things a little more in
    detail and refactor.

    Thank you once again. You have been a great help!.
    --
    Posted via http://www.ruby-forum.com/.
    Adam Akhtar, Nov 11, 2008
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Beatrice Rutger
    Replies:
    0
    Views:
    703
    Beatrice Rutger
    Jun 5, 2005
  2. Replies:
    6
    Views:
    728
    Chris Uppal
    Feb 13, 2006
  3. mem

    Observer pattern

    mem, May 18, 2004, in forum: C++
    Replies:
    2
    Views:
    524
    adiian
    Jun 4, 2007
  4. jacob navia

    Implementing an observer

    jacob navia, Nov 18, 2010, in forum: C Programming
    Replies:
    24
    Views:
    710
    Malcolm McLean
    Nov 25, 2010
  5. jacob navia

    Implementing the observer pattern in C

    jacob navia, Mar 27, 2011, in forum: C Programming
    Replies:
    3
    Views:
    1,099
    jacob navia
    Mar 29, 2011
Loading...

Share This Page