Any thoughts about this one?
To prevent codeduplication in my MPV GUI I think of splitting usercontrols in MPV triads. I use passive screens (http://martinfowler.com/eaaDev/PassiveScreen.html). Say for example I have a form with a customlistview object and a customtreeview object communicating like in the windows explorer, for menumaintenance. I could choose to keep it simple and write a TreeView.cls (subclass of UltraTreeView), a ListView.cls (subclass of UltraListView), a MenuView.cls with the former as children and use one MenuPresenter.cls and one MenuModel.cls. But that would mean codeduplicates in the presenterobjects that present different viewers. To solve this I can create MPV triads for the usercontrols. If for example I have the requirement that after editing the the value of the item in the listview the corresponding treenode should be updated too, I could:
- 'Publish' the event 'OnItemExitedEditMode' from viewer ListView.cls. This 'Publish' publishes an object with the
ItemExitedEditModeEventArgs and sender as properties.
- MenuPresenter.cls subscribes to this event. If it catches an 'OnItemExitedEditMode' that is published by the ListView.cls instance,
MenuPresenter.cls publishes the event 'UpdateNode', with e:Item:Key and e:Item:Value as parameters.
- TreeViewPresenter.cls subscibes to 'UpdateNode'. If 'UpdateNode' is catched the viewer's node is found with the first parameter and it's caption set with the second.
Ok, not thought about the model(s) yet. Maybe TreeViewModel.cls and ListViewModel.cls are not needed.
--
Kind regards,
Stefan Houtzager
Houtzager ICT consultancy & development
www.linkedin.com/in/stefanhoutzager
Let me clarify and correct some things after giving this a bit more thought. We have a form, let's call it MenuViewer.cls, which is a container for two usercontrols: ListView.cls and TreeView.cls. I want to maintain menu's. I want to do this in an MVP architecture with the passive view because of all the advantages described on many places on the web. As a thought experiment, to find out pro's and con's of implementing this pattern. Of course the first con is that the pattern is almost unknown in the progressworld, so why would you bother to use your valuable time to learn about all this? Well, I propose you put your valuable time in reading about it on the web then.
Okay, I had the requirement that if a menuitem's caption is edited in the ListView (in the enabled first column) the corresponding treenode in TreeView.cls should be updated too. I proposed the following as the first steps:
- 'Publish' the event 'OnItemExitedEditMode' from viewer ListView.cls. This 'Publish' publishes an object with the
ItemExitedEditModeEventArgs and sender as properties.
- MenuPresenter.cls subscribes to this event. If it catches an 'OnItemExitedEditMode' that is published by the ListView.cls instance,
MenuPresenter.cls publishes the event 'UpdateNode', with e:Item:Key and e:Item:Value as parameters.
This is not according to MVP/Passive view rules! Why didn't you tap my fingers for that? ;-) The presenter should not know about control specifics, therefore it cannot use ItemExitedEditModeEventArgs . Let's change this therefore and replace the EventArgs in the published object by the values of e:Item:Key and e:Item:Value. If MenuPresenter.cls publishes the event 'UpdateNode', Key and Value can be passed by their values. Next step is
- TreeViewPresenter.cls subscibes to 'UpdateNode'. If 'UpdateNode' is catched the viewer's node is found with the first parameter and it's caption set with the second.
Of course TreeViewPresenter.cls may not refer to the treenode. It has to set the nodevalue with the parameters of 'UpdateNode' by a property that is contained in an interface, ITreeView.
Any thoughts now?
I use the MVC pattern. My application is designed so that a user need not touch the mouse to do his/her work (ok, once or twice to get the ball rolling). I have seen users pound the keyboard at lightning speeds, and fear that another object layer could effect responsiveness. I am monitoring keystrokes, so need to be concerned here.
I do subscribe high level CRUD events to methods in the controller (addButtonChoose, saveButtonChoose, etc) and employ the observer pattern where the view, having registered with the model, is notified to refresh it's data/controls. While doing so, I reference model query and dataset handles. Also, when the user wants to save changes, any control not bound to a data source has its Value property assigned to public properties in the model.
I could probably make the MPV pattern work but cannot see an upside that makes a big enough difference, and there may be a downside I can't afford.
Did you make a conscious choice between MVP, MVC and possible other alternatives (whereunder just not splitting these objects) beforehand?
--
Kind regards,
Stefan Houtzager
Houtzager ICT consultancy & development
www.linkedin.com/in/stefanhoutzager
I did. I studied books, scoured the web, and made a choice. I have a POS application in production based on the OERA, with a Progress GUI client. The next version will have a GUI for .NET client (building it now). The version after that will have an OOABL back end. There are some great conversations on this site regarding theory around transforming back end procedural based systems to OO. No concrete examples yet, but much to think about.
And what were your reasons to choose MVC over MVP or no separate UI objects at all? MVP is by the way seen as an improvement after MVC. OERA names MVP too, not MVC. Maybe the progress architects have their reasons.
"And what were your reasons to choose MVC"
See above.
"OERA names MVP"
I would love to see more on this. Have you a link?
Ok then let me be the first to name the advantages of MVP over MVC. Found them on the web where you must have read about them too, and reworded them.
MVP offers a better separation of concerns than MVC. As a result
- You can write unittests that talk to interfaces (IView and maybe others) - no testing by hand (of the presenter via the viewer) needed.
(I have no experience with this way of unittesting in OE, would like to hear from others that do).
- Your presenter is reusable. Say for example you need to use the infragistics treeview instead of the ms one in your custom viewer treeview.cls:
rewrite your viewer and you're ready
- ???
I would be interested to hear what advantages of MVC over MVP you see.
As for your question on the ora papers: just search the psdn on oera and mvp! Ok, here are some links:
a pdf
http://communities.progress.com/pcom/docs/DOC-34978
a ppt
http://communities.progress.com/pcom/docs/DOC-29518
MVP was not thought out by PSC. For discussions you can look further than communities.progress.com. Here are some links:
http://blogs.infragistics.com/blogs/todd_snyder/archive/2007/10/17/mvc-or-mvp-pattern-whats-the-difference.aspx
www.object-arts.com/papers/TwistingTheTriad.PDF
http://martinfowler.com/eaaDev/uiArchs.html (part of http://martinfowler.com/eaaDev/ )
http://blog.vuscode.com/malovicn/archive/2007/11/04/model-view-presenter-mvp-design-pattern-close-look-part-2-passive-view.aspx
--
Kind regards,
Stefan Houtzager
Houtzager ICT consultancy & development
www.linkedin.com/in/stefanhoutzager
Thanks for the links. They were new to me.
Reading the papers and listening to the webcasts persuaded me to call what I am doing the MVP pattern.
In my application the main MDI form reviews/updates a collection of objects and creates/views them on demand. If there is a request for a Customer form then:
A customerModel object is created. A customerControl object is created and passed the model reference. CustomerControl creates the customerView and passes it model and control references.
Separation of concerns is handled.
Martin Fowler (one of your links) summarizes MVP:
I use Observer Synchronization.
In the model:
method void notifyObservers():
for each ttObserver:
cast(ttObserver.Observer, iObserver):refreshData(this-object).
end.
end method.
"Say for example you need to use the infragistics treeview instead of the ms one"
I haven't used ms controls yet but I think it's just a matter of obtaining a bindingSource handle.
bsPhoneNumbers:handle = oContactModel:getPhoneQueryHandle vs oContactControl:getPhoneQueryHandle (which then gets it from the model).
"You can write unit tests"
An interesting possibility.
I will take the few remaining model references out of the view and pass the operations/requests through the controller.
"I would be interested to hear what advantages of MVC over MVP you see."
None.
Daniel,
Just a few remarks.
"A customerModel object is created. A customerControl object is created and passed the model reference. CustomerControl creates the customerView and passes it model and control references. Separation of concerns is handled."
I assume you only use the interfaces of the viewer and model to talk to from within the presenter and "talk" from viewer to presenter by means of raising events?. Passing of a modelreference to the viewer has no use in MVP. And what use is your viewer making of the controlreference?
"I use Observer Synchronization.
In the model:
method void notifyObservers():
for each ttObserver:
cast(ttObserver.Observer, iObserver):refreshData(this-object).
end.
end method."
Doesn't Fowler name this as one of the soundbites of MVC?
""Say for example you need to use the infragistics treeview instead of the ms one"
I haven't used ms controls yet but I think it's just a matter of obtaining a bindingSource handle.
bsPhoneNumbers:handle = oContactModel:getPhoneQueryHandle vs oContactControl:getPhoneQueryHandle (which then gets it from the model)."
I think you misunderstood me? Ms treeview and infragistics treeview are different classes, their differences have to be handled. Moreover a viewer may not communicate with the model in MVP.
""You can write unit tests"
An interesting possibility."
For which you need the Passive view variant of MVP (Fowler again).
--
Kind regards,
Stefan Houtzager
Houtzager ICT consultancy & development
www.linkedin.com/in/stefanhoutzager
Maybe this is an interesting link also. Just found it, maybe Peter Judge can tell what it is all about?
--
Kind regards,
Stefan Houtzager
Houtzager ICT consultancy & development
www.linkedin.com/in/stefanhoutzager
This is currently a work in progress project that we wanted to test with Google Code. We're currently looking at a number of different ways to make the new OpenEdge sample application initiative an open process and this was one of the tests, so don't necessarily expect the Google project to stay around as we're still assessing our options. The code in the project is early test code so feel free to look at it but again don't expect it to work! As soon as we have a permanent home for the project and we have the initial designs & docs in a state to share, we'll make an announcement of where you can find the project and how, if you're interested, you can participate.
But hopefully the project will be exciting. We're planning a multi-tenant designed application & set of reference components that will highlight the OpenEdge 10.2b feature set and incorporating some standard patterns such as MVP and potentially concepts such as Dependency Injection.
So look for the announcement soon.
Mike
Thanks for sharing this code, I'm looking forward to what is going to come!
--
Kind regards,
Stefan Houtzager
Houtzager ICT consultancy & development
www.linkedin.com/in/stefanhoutzager
http://code.google.com/p/vendoredge/wiki/Code?tm=4 :
Code Check back soon for access to the sample code |
Duh, I hope soon will be soon. The code looked so intelligent! You don't have to be so shy. ;-)
--
Kind regards,
Stefan Houtzager
Houtzager ICT consultancy & development
www.linkedin.com/in/stefanhoutzager
Soon will be soon
Stefan, you still have a copy?
No problem, google is my friend. Hehehehe!
--
Kind regards,
Stefan Houtzager
Houtzager ICT consultancy & development
www.linkedin.com/in/stefanhoutzager
Well I guess we should be glad that you're excited. I promise the project will be made fully public real soon, we're just making sure the supporting docs etc are in order. The plan is for the project to be as open as we can be, so you will see fairly frequent code drops as we move through the project. Of course, if people want to also contribute to the effort then that will be most welcome.
mormerod wrote:
Soon will be soon
I hope so - I've got another vendor who'se version of "soon" is more of an attempt to pacify the audience rather than being a measure of time.
Hello Mike,
Do you have a concrete timestamp (format MM/YY) when the code will be available for us?
Kind regards, Stefan.
Do you have a concrete timestamp (format MM/YY) when the code will be available for us?
I appreciate that "soon" has probably come and gone but (unfortunately) I don't have a concrete date. We are in an internal review phase right now, which I'm hoping will be over soon*.
-- peter
* yeah, yeah, I know
mormerod wrote:
Soon will be soon
What is your definition of 'soon'?
any news yet Mike, is the project already made public ?
regards,
Will
Hi,
Thank you for your email. I'm currently out of the office on vacation. I will return on August 27. During my absence I will have no or very limited access to my email. For urgent matters, call me on my mobile and leave a message on my voice mail or call our office.
Best regards,
Wouter.
--
Wouter Dupré
Senior Solution Consultant
Progress Software NV
Stocletlaan 202 B| B-2570 Duffel | Belgium
Direct Line +32 (0) 15 30 77 00 | Mobile +32 (0) 478 50 00 49
wdupre@progress.com