![]() |
implementing mvc - using observer pattern - beginner to OOP
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/. |
Re: implementing mvc - using observer pattern - beginner to OOP
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_ |
Re: implementing mvc - using observer pattern - beginner to OOP
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/. > |
Re: implementing mvc - using observer pattern - beginner to OOP
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/. |
Re: implementing mvc - using observer pattern - beginner to OOP
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 |
Re: implementing mvc - using observer pattern - beginner to OOP
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/. |
Re: implementing mvc - using observer pattern - beginner to OOP
Fogot the
Thank you once again for your and everyone elses help \ part. -- Posted via http://www.ruby-forum.com/. |
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/. |
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/. |
| All times are GMT. The time now is 09:13 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.