I need to write a GUI framework, where I have no experience at all, not even using one. I'm a programmer for 25 years now, but not touched GUI in OO.
My questions:
1. I'm using a special kind of programming language, where there is main event-loop that accepts all events and from there it has to dispatch the events. my question is, as a gui framework, to where I need to dispatch the event, for instance if a complex control like a List that has a scrollbar was scrolled, I get the event in my main event loop and I have to forward it to the complex control? or should it be routed to the scrollbar which is internal control in the List control, and then bubble it up to the List?
2. Apart from sending the event to the control that triggered it, for the sake of taking the standart internal response - is there another responsibility that the framework should handle? I mean, does the framework should bubble the event also to the Dialog control that will be inherited later by the framework user in order to impliment the specific response to the events? or is it left to the framework user to dispatch the event to the dialog? I guess what I'm missing is what is the framework responsibility in terms of reacting to internal events.
Related
As I'm learning about Sammy.js I read that you can have several Sammy.js applications in the same page, each bound to a different element (i.e. div). I would like to understand why would this be useful.
I read in another post that only forms inside a bound element will trigger the route change, I'm thinking this could be used to modularize your application. Is there another use case beside this? Could you provide an example of how to modularize your application in this way?
We implemented a component similar to Sammy in our Silverlight application some time ago. The similarity is in that both represent a kind of a simple browser that can be bound to a UI region. The approach gave us several benefits:
We had an extensible way to add new content implementations. I mean that we could add plugins to our app that contained new forms/views which the application core had no knowledge about.
We could easily implement composite views, e.g. dashboard that were able to show any view implemented in any module. Including themselves. (A-ha, we had created recursive dashboards that worked until the app hit the memory limit. Kind of Inception. :))
Sammy can be used to reach these goals as well.
However, you must understand that from all Sammy applications running on a page, only one can be bound to the browser location bar. Others will have their location visible only to javascript, or you'll need to render location bars for them on the page.
I am involved in the development of a WPF Prism application which uses the event aggregator to send global type messages which are then picked up by the shell. For example, a viewmodel might want a toast message displayed but doesn't really care how it is displayed. In this instance the shell would be setup to process those events and act on them application wide.
The question I have is how do you do it if a particular view wants to display the toast messages differently. I like the global approach because it is very simple, but how to customize it for special cases?
I think this really depends upon how your application is setup and what standards/patterns you are using. In MVVM I see two approaches.
View-First
If your View-Model is injected into your view, then send the messages to your view, and let the View decide what to do with it. If it wants to display them itself, it can do that. If it wants to send them to your shell, it can do that through the event aggregator or injecting a Toast service interface. That keeps your View in control of the visual.
View-Model-First
If your View is injected into your View-Model, then your View Model should be asking for a different View, which should be bound to its own View Model. If it wants to send messages to another View-Model, it can do that through the event aggregator or injecting a Toast View-Model/service interface. That keeps your View-Model in control of the navigation between Views.
I prefer the View-First approach because it keeps your View in control of the visualization of your model. But I'm very interested in how other MVVM developers tackle this. This seems very closely aligned with the question of how to present dialogs in the MVVM View-First approach.
Using Eventaggregator for this purpose is not the right way I think, because the events are broadcasted to the entire application.
One possible way to handle the scenario is your viewmodels can get an IMessenger interface injected in the constructor. There is an application implementation of IMessenger(which is injected by default) and you can have customised implementations of IMessenger according to your needs. Your viewmodel just calls an interface function(say DisplayMessage()), but according to the Messenger injected to it, the behaviour is different.
In an WP app which approach is better.
From the .xaml page, call a method of another class (pass the delegate of a .xaml.cs callback Method ) which makes some request to server , receives data and when requests complete calls the .xaml.cs page method. and in call back method we get data and bind the data with a control (ListBox).
Bind the List box with an ObservableCollection object of MainViewModel class. and change the bounded object from the MainViewModel. All the calls to requests to server are made in MainViewModel class.
I vote for the option 2. Event the project templates (Eg. Databound application template for Windows Phone 7) gives you the MainViewModel and binds a Listbox to an ObservableCollection in that class.
The MVVC approach gives you a lot more flexibility, your UI is totally separated from the logic. ALl your UI needs to know is that it is bound to an ObservableCollection and it doesn't need to know how that collection is filled.
I think you should use the second approach which allows you to create loosely-coupled applications. The big advantages of such applications are:
separation of concerns: different subsystems/layers are independent
unit testing is simple
refactoring is easier
increase ability to code reuse
...
Regarding WP7, you can read my article which shows how to code using this approach:
a framework for building of WP7 application
I just started a new GWT project for a client and I'm interested in hearing people's experience with various GWT MVC architectures. On a recent project, I used both GXT MVC, as well as a custom messaging solution (based on Appcelerator's MQ). GXT MVC worked OK, but it seemed like overkill for GWT and was hard to make work with browser history. I've heard of PureMVC and GWTiger, but never used them. Our custom MQ solution worked pretty well, but made it difficult to test components with JUnit.
In addition, I've heard that Google Wave (a GWT application) is written using a Model-View-Presenter pattern. A sample MVP application was recently published, but looking at the code, it doesn't seem that intuitive.
If you were building a new GWT application, which architecture would you use? What are the pros and cons of your choice?
Thanks,
Matt
It's worth noting that google has finally written out a tutorial for designing using the mvp architecture. It clarifies a lot of the elements from the google i/o talk listed above. Take a looK: https://developers.google.com/web-toolkit/articles/mvp-architecture
I am glad this question has been asked, because GWT desperatley needs a rails-like way of structuring an application. A simple approach based on best practices that will work for 90 % of all use-cases and enables super easy testability.
In the past years I have been using my own implementation of MVP with a very passive view that enslaves itself to whatever the Presenter tells him to do.
My solution consisted of the following:
an interface per widget defining the methods to control the visual appearance
an implementing class that can be a Composite or use an external widget library
a central Presenter for a screen that hosts N views that are made up of M widgets
a central model per screen that holds the data associated with the current visual appearance
generic listener classes like "SourcesAddEvents[CustomerDTO]" (the editor does not like the real symbols for java generics here, so I used thoe brackets), because otherwise you will have lots of the same interfaces who just differ by the type
The Views get a reference to the presenter as their constructor parameter, so they can initialize their events with the presenter. The presenter will handles those events and notify other widgets/views and or call gwt-rpc that on success puts its result into the model. The model has a typical "Property[List[String]] names = ...." property change listener mechanism that is registered with the presenter so that the update of a model by an gwt-rpc request goes to all views/widgets that are interested.
With this appraoch I have gotten very easy testability with EasyMock for my AsynInterfaces. I also got the ability to easily exchange the implementation of a view/widget, because all I had to rewrite was the code that notified the presenter of some event - regardless of the underlying widget (Button, Links, etc).
Problems with my approach:
My current implementation makes it hard to synchronize data-values between the central models of different screens. Say you have a screen that displays a set of categories and another screen that lets you add/edit those items. Currently it is very hard to propagate those change events across the boundaries of the screens, because the values are cached in those models and it is hard to find our whether some things are dirty (would have been easy in a traditional web1.0-html-dumb-terminal kind of scenario with serverside declarative caching).
The constructor parameters of the views enable super-easy testing, but without a solid Dependency-Injection framework, one will have some UGLY factory/setup code inside "onModuleLoad()". At the time I started this, I was not aware of Google GIN, so when I refactor my app, I will use that to get rid of this boilerplate. An interesting example here is the "HigherLower" game inside the GIN-Trunk.
I did not get History right the first time, so it is hard to navigate from one part of my app to another. My approach is not aware of History, which is a serious downturn.
My Solutions to those problems:
Use GIN to remove the setup boilerplate that is hard to maintain
While moving from Gwt-Ext to GXT, use its MVC framework as an EventBus to attach/detach modular screens, to avoid the caching/synchronization issues
Think of some kind of "Place"-Abstraction like Ray Ryan described in his talk at I/O 09, which bridges the Event-Gap between GXT-MVC and GWTs-Hitory approach
Use MVP for widgets to isolate data access
Summary:
I dont think one can use a single "MVP" approach for an entire app. One definetly needs history for app-navigation, a eventbus like GXT-MVC to attach/detach screens, and MVP to enable easy testing of data access for widgets.
I therefore propose a layered approach that combines these three elements, since I believe that the "one-event-mvp-system"-solution wont work. Navigation/Screen-Attaching/Data-Access are three separate concerns and I will refactor my app (move to GXT) in the following months to utilize all three event-frameworks for each concerns separately (best tool for the job). All three elements need not be aware of each other. I do know that my solution only applies for GXT-projects.
When writing big GWT apps, I feel like I have to reinvent something like Spring-MVC on the client, which really sucks, because it takes a lot of time and brain-power to spit out something elegant as Spring MVC. GWT needs an app framework much more than those tiny little JS-optimizations that the compiler-guys work so hard on.
Here is a recent Google IO presentation on architecting your GWT application.
Enjoy.
-JP
If you're interested in using the MVP architecture, you might want to take a look at GWTP: http://code.google.com/p/gwt-platform/ . It's an open source MVP framework I'm working on, that supports many nice features of GWT, including code splitting and history management, with a simple annotation-based API. It is quite recent, but is already being used in a number of projects.
You should have a look at GWT Portlets. We developed the GWT Portlets Framework while working on a large HR Portal application and it is now free and open source. From the GWT Portlets website (hosted on Google code):
The programming model is somewhat similar to writing JSR168 portlets for a portal server (Liferay, JBoss Portal etc.). The "portal" is your application built using the GWT Portlets framework as a library. Application functionality is developed as loosely coupled Portlets each with an optional server side DataProvider.
Every Portlet knows how to externalize its state into a serializable PortletFactory subclass (momento / DTO / factory pattern) making important functionality possible:
CRUD operations are handled by a single GWT RPC for all Portlets
The layout of Portlets on a "page" can be represented as a tree of WidgetFactory's (an interface implemented by PortletFactory)
Trees of WidgetFactory's can be serialized and marshalled to/from XML on the server, to store GUI layouts (or "pages") in XML page files
Other important features of the framework are listed below:
Pages can be edited in the browser at runtime (by developers and/or users) using the framework layout editor
Portlets are positioned absolutely so can use scrolling regions
Portlets are configurable, indicate when they are busy loading for automatic "loading spinner" display and can be maximized
Themed widgets including a styled dialog box, a CSS styled button replacement, small toolbuttons and a HTML template driven menu
GWT Portlets is implemented in Java code and does not wrap any external Javascript libraries. It does not impose any server side framework (e.g. Spring or J2EE) but is designed to work well in conjunction with such frameworks.
So I know that unit testing is a must. I get the idea that TDD is the way to go when adding new modules. Even if, in practice, I don't actually do it. A bit like commenting code, really.
The real thing is, I'm struggling to get my head around how to unit-test the UI and more generally objects that generate events: user controls, asynchronous database operations, etc.
So much of my code relates to UI events that I can't quite see how to even start the unit testing.
There must be some primers and starter docs out there? Some hints and tips?
I'm generally working in C# (2.0 and 3.5) but I'm not sure that this is strictly relevant to the question.
the thing to remember is that unit testing is about testing the units of code you write. Your unit tests shouldn't test that clicking a button raises an event, but that the code being executed by that click event does as it's supposed to.
What you're really wanting to do is test the underlying code does what it should so that your UI layers can execute that code with confidence.
Read this if you're struggling with UI Testing
Manually test UI stuff where benefit to cost in automating it is minimal. Test everything under the UI skin ruthlessly. Use Humble Dialog, MVC or variants to keep logic and UI distinct and loosely coupled.
You should separate logic and presentation. Using MVP(Model-View-Presenter)/MVC (Model-View-Controller) patterns you can unit test you logic without relying on UI events.
Also you can use White framework to simulate user input.
I would highly recommend you to visit Microsoft's Patterns&Practices developer center, especially take a look at composite application block and Prism - you can get a lot of information on test driven design.
The parts of your application that talk to the outside world (ie UI, database etc.) are always a problem when unit-testing. The way around this is actually not to test those layers but make them as thin as possible. For the UI you can use a humble dialog or a view that doesn't do anything worth testing and then put all the logic in a controller or presenter class. You can then use a mocking framework or write your own mock objects to make fake versions of the views to test the logic in the presenters or controller. On the database side you can do something similar.
Testing events is not impossible. You can for example subscribe an anonymous method to the event that throws an exception if the event is thrown or counts the number of times the event is thrown.