Implementing mvc - using observer pattern - beginner to OOP


#1

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 :wink:

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


#2

2008/11/8 Adam A. :

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çois.


#3

Hi,

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

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

This is pretty much what MVC tries to deal with. There are variations
on MVC as well.

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.

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

These two papers are pretty good I think. The second paper talks about
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

Value models seem like a bit of a pain, but worth knowing about.
You won’t likely need them at the start, and MVC + value models can be
a bit complicated, but when your application starts getting complex
they can help.

As Jean-François pointed out, you don’t have to do this yourself. On
the other hand, if you are looking to learn OOP this is a pretty good
way, it might be a hard way, but you’ll certainly have a handle on OOP
by the time you’re done :slight_smile:

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

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

The rest of your questions are better answered by the papers I linked
to.

Cheers,
Bob


#4

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.


#5

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 :wink: )

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.


#6

On Tue, 11 Nov 2008, Adam A. 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.


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

#7

On Tue, 11 Nov 2008, Adam A. wrote:

with, and Read and Update mean you’ll need to search for tasks, so that
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.

Sounds OK to me.

instance of the DB and the UI within it, is that correct?
Yes, and I should have lowercased those, as they should be instance
methods not class methods. Having Upppercase variables makes that
unclear.

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.

I think there are varying schools of thought on this, because it
depends what is easiest to do. For your case, I’d go through the
controller. The controller will ask the DB for info, for updates,
and so on, so it should get the responses. It may need to filter
the information to pick out the pertinent stuff. That way you can
change the DB to SQLite3 or whatever later, and only the DB and
controller will be affected, if you’ve not managed to keep all the
effects inside the DB classes.

IIRC “Head First Design Patterns” (a good book, if you accept the
cognitive psychology that drives the quirky style) I think says that
often the Model (database) can just send stuff to the UI. But you
are mainly concentrating on separation of concerns for this work, so
unless performance becomes a problem, I’d go through the controller.

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

Yes, you can wrap them into a similar object, but they may not be valid
things to create a real Task. When do you want this to end: 30-FEB-2009
for example.

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.

Yes

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.

I’d say that’s entirely in the court of the UI. Why? Because it would
do different stuff if it was a web form, Tk dialogue box, interface
operated by a blink-switch …

    Hugh

#8

Adam A. 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.


#9

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!.


#10

Fogot the

Thank you once again for your and everyone elses help \

part.


#11

I just came across this which may be relevant, even though it uses
ActiveRecord:

http://www.oreillynet.com/pub/a/ruby/2007/06/21/how-to-build-simple-console-apps-with-ruby-and-activerecord.html