I have a session variable that is needed to filter my JPA query as follows:
activities = JPAContainerFactory.make(ActivityEntity.class, DCSAdminUI.PERSISTENCE_UNIT);
activities.addContainerFilter(new Compare.Equal("organisation.rowid", OrgID));
My view is able to receive the session variable in the enter() method as follows:
#Override
public void enter(ViewChangeEvent event) {
OrgID = (String) VaadinService.getCurrentRequest().getWrappedSession().getAttribute("org");
buildLayout();
}
The problem is that I don't know how to take the variable from the enter() method and use it in constructing the UI. As you can see from the enter() method code above, I am manually calling buildLayout() which does the UI construction. This works but I end up getting the view re-constructed within itself every time I navigate to another view and back to this one. I know that enter() is called before the constructor but what I don't understand is why the constructor doesn't seem to be called unless I explicitly call it in the enter() method
Any help or pointers will be much appreciated
The constructor of your view class is actually called either by you when you add your views to the navigator or by the framework when you are navigating to the view. This depends on which overloaded variant of Navigator#addView() you use.
Judging by your question, I assume you want to avoid that each time you visit the view either a JPA query is executed or some form of recursive UI construction (whatever you mean by 'constructed within itself') is performed.
A way better approach for your problem, however, would be if you separated your UI code from its data logic. That is, keep the data (JPAContainer) out of the view altogether. Then, you could construct the UI in your View's default constructor (use Navigator#addView(String, Class<? extends View>) in that case). You should have a look at the Model-View-Presenter design pattern to get an idea of how to achieve this separation of concerns. Reading the session variable OrgID would then happen in the presenter.
It is better to rebuild the UI upon navigating to a particular view anyway. Rebuilding a Vaadin UI is fast, whereas keeping UI components not currently visible in the browser in the session will waste precious server-side memory. You should keep your session size as small as possible to allow more simultaneous users on the server. That is, only keep components in the session that are actually visible to the user.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
In the MVP pattern, there is no dependency between the view and the model. Everything is done by the presenter.
In our GWT-project, we implement all our MVP classes like shown on the GWT .page. To access the view, our presenter uses an interface like this:
public interface Display {
HasClickHandlers getAddButton();
HasClickHandlers getDeleteButton();
...
}
So, the presenter gets a button from the view, and applies its click handlers to it.
But this feels so wrong to me. This violates the single responsibility principle, as well as the information hiding principle. the presenter should not know anything of the internals of the view (even when we get an abstract HasClickHandlers).
In my opinion, we should better use this kind of pattern:
public interface Display {
void setPresenter(Presenter p);
}
public interface Presenter {
void onAdd();
void onDelete();
}
So, the view tells the presenter actively, that some interaction occured. But not on which view-element.
My team partners argue, that with the first solution, we avoid circular dependencies. That´s right. But anyway, I would prefer the second way because the modules are better separated and can be maintained independently.
What are the advantages / disadvantages?
Strongly agree - and the article you link describes both sides, if you continue to the second section.
I don't build my Views exposing widgets or their HasSomethingHandlers - I find it generally better to build the Presenter API to expose those possible interactions for several reasons:
Unit tests - It is simpler to make a mock view which invokes methods rather than firing events. This is not to say that it isn't possible (especially if your Presenter can run on the JVM and you can create a Proxy type for each one.
Cleaning up unused handlers - Presenters are generally cheap and get re-created each time, but sometimes Views are heavy and are saved, reused. Any time you reuse a view, you have to be sure that all of those externally added handlers were removed. This can be done correctly with some "lifecycle" methods like onStop() or something on the presenter, so that whatever code replaces presenters can shut it down, but would need to be factored in.
Multiple view implementations - like unit tests, different view implementations (mobile vs desktop, readonly vs readwrite, etc) might have different ways of causing the same change. Now, you could have multiple methods exposing HasClickHandlers onAddClicked() and HasTouchHandlers onAddTapped(), or, take the approach you describe. (You also can end up leaking some UX details into the presenter, like hitting the Enter key while in the last field, as opposed to clicking the button - that arguably belongs in the view, and not in the presenter).
One downside of this approach: the view needs more brains, and part of the goal of MVP is to keep the view as skinny as possible.
Finally, while this alternative approach isn't actually compared and contrasted on the page you linked, page two of the same article you linked does show your approach instead http://www.gwtproject.org/articles/mvp-architecture-2.html:
Now that we have the UI constructed, we need to hook up the associated UI events, namely Add/Delete button clicks, and interaction with the contact list FlexTable. This is where we’ll start to notice significant changes in the overall layout of our application design. Mainly due to the fact that we want to link methods within the view to UI interactions via the UiHandler annotation. The first major change is that we want our ContactsPresenter to implement a Presenter interface that allows our ContactsView to callback into the presenter when it receives a click, select or other event. The Presenter interface defines the following:
public interface Presenter<T> {
void onAddButtonClicked();
void onDeleteButtonClicked();
void onItemClicked(T clickedItem);
void onItemSelected(T selectedItem);
}
This is done in the context of describing the UiBinder way of building views, but it applies equally well without UiBinder.
So when discussing the article in relation to organizing how your team is building their application, be sure to consider the entire set of articles - those articles are both referenced from http://www.gwtproject.org/doc/latest/DevGuideMvpActivitiesAndPlaces.html, which also assumes this non-eventhandler approach. And in that article there are other "wrong" ways of doing things, like manual dependency injection, instead of an automated reliable tool like Gin or Dagger2.
The articles aren't meant to describe the One True Way, but to understand the ideas and patterns that can be used. Don't cargo cult this, applying patterns blindly, but make sure to understand the pros and cons - and work as a team, a pattern used inconsistently is arguably worse than no pattern at all!
EDIT: I realized I didn't mention the circular dependency issue!
This is as much or as little of an issue as you want it to be. If you create them at the same time, and pass references to the other in the constructors, obviously you have an issue - GWT can't proxy them (and arguably that's a bad idea anyway). But, down the road, you might get into a situation where views are expensive to build and could be pooled/cached and not re-created every time, in which case the view needs to be informed of the new presenter it now works with anyway.
That then requires that the View interface supports a void setPresenter(P) method anyway, so our circle is broken. Keep in mind also that this approach will require either the presenter being sure to clear out data in the view, or the view knowing when a new presenter is set to clear its own data.
My personal approach for this leads to the presenter owning a view field, injected (probably via constructor) when it is created, and have a start method in the presenter. When called, the presenter takes control of the view, and when ready, appends it where it belongs in the dom hierarchy.
Yes, this requires one extra method in the view, but if you have any base class for your views, this will be trivial, and if you end up doing any view reuse, you need that method anyway.
Suppose I have a TabManager class which holds tabs array. There is also a controller that needs to track this tabs property and draw tabs in the array. I have two approaches to sharing this data:
First approach is reference sharing:
controller.tabs = tabManager.tabs
There are also many variations of the statement above, for example, this one:
// getTabs() returns reference to private _tabs property
controller.tabs = tabManager.getTabs();
Second approach is to notify controller when tabs array changes:
tabManager.on("tabSetChange", function(tabs) {
// tabs here are clone of tabManager.tabs, not the same reference
// so modifying controller.tabs won't affect tabManager.tabs
controller.tabs = tabs;
});
Is there are a some rule of a thumb to decide which approach to choose? Lately, I'm inclined to use second approach to prevent accidental data change and with this approach debugging seems easier. But the second approach is also much more elaborate.
From your description it sounds like TabManager "owns" the tabs array and is responsible for making changes to it. The controller just needs a read-only view of the information in order to draw the tabs.
Presumably the controller needs to know when the tabs array changes such that the view needs to be refreshed. Simply sharing the reference doesn't give controller the ability to know when the array has changed, the TabManager would have to notify it. This leads to the event driven model you suggest being the better fit.
The event driven model allows the TabManager to emit events when there are relevant changes to the array, and for anyone who cares to be notified. This decoupling of components is a good thing. You may find another component wants to track the tabs array as well, so rather than hardcode a relationship to TabManager, it just registers an event listener.
This event based model is very much the JavaScript way.
Just a note, I'm new to MVC.
I'm trying to make my code as much decoupled and testable as possible.
I have a view with a text box and button.
I want to enable the button when a new text is entered and respects a certain criteria.
Ideally, I'd like this logic that decides if the button is enabled or not outside the view so it can be unit tested.
My understanding of MVC goes like that:
In my View I have a reference to my Controller.
In my Controller I have a reference to my Model.
In my Model I have a reference to my View.
Can you tell me if the following is a good design.
I added a boolean to the model buttonEnabled.
the sequence of event is like that:
Text is input in the text box, the text box has a listener. The listener calls a textChanged method on the Controller, the controller does the checks on whether to enable the button or not, and then sets the buttonEnabled of the Model through a setButtonEnabled accessor.
The accessor changes the value of buttonEnabled, and calls a buttonEnabledChanged() on the view (which exposes that method)
the idea is that the view is specific observer of the model, and the model is an observable which could theoretically have multiple views, and can call buttonEnabledChanged() on all of them.
Please let me know what you think.
This is a philosophical answer to a philosophical question :)
What you suggest could be correct. But the real question is if buttonEnabled is really a good candidate for your model. It's a purely gui thing and makes no sense being there. Thing that are really specific to the interface belong in the view, and nowhere else.
Now there might be a reason that the button is disabled (like, entry is not valid). Then you could just give it another name in the model (isValid). The translation from !isValid to !buttonEnabled would then become part of the controller, or even the view itself.
But I'm guessing that, in your case, the only reason to block the button when there is no content is to make it less likely for the user to send in a blank form. In that case, I would do the check in view completely (javascript if it's web), just for user convenience. In the model, just throw an exception (IllegalArgumentException seems likely) if the empty string gets there anyway.
If you're unit-testing your model, it makes a lot more sense to test if it will complain about an empty string, then to check if your model is setting buttonEnabled to false. If you really want to test gui functionality, there are solutions for that (for web, selenium comes to mind).
What you suggest is overcomplicated and, in my opinion, wrong from the standpoint of MVC.
The controller should not check whether or not to enable button, it is the task of model.
The model should not call any methods on view.
You have too specific methods. This desire to update only specific stuff, like buttonEnabledChanged() will make things overcomplicated in future, where components depend on each other through some business logic.
What you need is to bind this text box's value to model value, perhaps through the controller. So, changing text boxes value will change model's value. It should then call the update on the view. The view knows, that in the model there is some property that determines if the button should be enabled. It shouldn't be called isButtonEnabled() because it is agnostic of the view. It should be called isTextMatchingCriteria or something. Based on the value of that property, the view decides whether to enable the button or not.
This way:
Controller only controlls. It is catches and delegates, updates, but doesn't decide anything on business logic.
The model is independent of view.
View doesn't have any specific methods that can be called separately. The only thing it can is to render a correct presentation based on the current state of the model. It also specifies, what one or another state of the model mean on the screen - a disabled button or error message. The model shouldn't do that.
So, I see this question asked but I will a little bit more code:
Where is the best place to put code to initialize the model before a
page renders. I know of five options, but where do you normally put
this type of initialization?
Before a page renders, I want to set the data in my bean/model with
certain attributes that may only be specific to that page.
I think there are five options.
Add initialization logic in the constructor. This may work, but I
don't know if the constructor is called for every page call (E.g. when
the page is deserialized).
Add init logic in onBeforeRender. This works and it called for every
request? But is it the best place? Or onconfigure? onInitialize.
And then, do you call setDefaultModel/setDefaultObject with the updated values?
Add init logic in a "load" or "getmodel" method in
LoadableDetachableModel class?
Add init in previous page on onSubmit method or onEvent. (onSubmit()
{ initBeanInSession(); setResponsePage(); }
Pass a model to a panel or page constructor (using pageparameters?)
Are any of these best practices or preferred over the other.
(a) Page Constructor code with Loadable detachable model:
MyPage.java:
...
final Form form = new Form(FORM, new
CompoundPropertyModel(new LoadableDetachableModel() {
private static final long serialVersionUID = 1L;
#Override
protected MyBean load() {
final MyBean app = (MyBean) Session.get().getApp();
?????????????
?????????????
initialize here???????
?????????????
return app;
}
};
});
???
onBeforeRender() {
?? Add initiailize here
final MyBean app = (MyBean) Session.get().getApp();
app.setData(doSomeBusinessLogicHere)
}
or initModel?
/**
* Called once per request on components before they are about to be rendered.
* This method should be used to configure such things as visibility and enabled flags.
*/
#Override
protected void onConfigure() {
super.onConfigure();
// Call business logic and properly set email address.
}
1 Add initialization logic in the constructor. This may work, but I don't know if the constructor is called for every page call (E.g. when the page is deserialized).
A constructor is only called when invoking new. Deserialization bypasses normal construction of objects (it only allocates enough memory and then loads the data directly—provided you haven't created any special code for serialization/deserialization). Such assumptions are easily checked with a debugger.
So if you want to do things for each request with your model object, the constructor is the wrong place.
2 Add init logic in onBeforeRender. This works and it called for every request? But is it the best place? Or onconfigure? onInitialize.
onBeforeRender is only called for visible components (for every request). The new onConfigure event is called for all components (regardless of visibility) with every request. onInitialize is only called after a component is added to its parent (i.e. just once).
The answer to your question is difficult to give, because it is not clear if you intent to overwrite the values your users have already provided in their input fields. If so, then you could do it in the load method of the LoadableDetachableModel. If not, then you should do it in onInitialize, or possibly set those defaults in the constructor of your App object.
There are no golden hammers for such design problems—it always depends.
I usually put it in the load() method of a LoadableDetachableModel. This method is specifically meant to contain initialisation logic.
But the question really is why you need to init it for every single page rendering. I admit that in some cases there's no other option, but usually there is.
i've started on some basic java coding with gwt, and im getting a bit concerned about the heft of my main class.
For instance - how does one compartmentalize the keyhandlers, since they trigger a number of changes to the UI, how could i move this into a separate .class file and still be able to access all the various widgets in the main class, without having to pass everything to the handler (ie. all the widgets i manipulate after the click event).
i've googled but didnt come across any particularly good examples - know of any readily legible code-bases i could read to see how it should be done? (gwt's own tuts are pretty basic, and just kitchen-sink every thing into a single file)
thanks!
I hate to say something so unimaginative, but MVC works--it's not the ultimate, but it can start getting you organized.
EDIT: While searching on a semi-related topic, I came across this which has similar ideas to mine but goes into more detail.
What that means in terms of GWT is that you should think of just laying out your GUI components in one class, put all your event handling in a second and put your object model objects separate from the other two.
One way to accomplish this is to make most or all the controls on your GUI public members. This sounds kind of lame, but their usage is encapsulated inside the controller so it's not like you have uncontrollable access--in fact your access is clearer/better defined than if all your members were private but your view code was combined with the controller.
Specific tricks:
Have listeners be their own class. You can often reuse them-- in other words, avoid anonymous inner classes. I sometimes create a listener class and instantiate a new instance for each button/control that needs to have a similar effect when pressed. If I need it to act slightly differently for a given button, I'll pass something into the constructor of the "special" handlers so that they know to act a little differently. You can also create different handler sub-classes if necessary--I'm just saying don't forget that event handlers are classes, you can use inheritance and everything if need be.
One Very Old GUI Trick I learned a long time ago, try not to have various mini-handlers modifying the GUI in different ways, instead have all the "active" buttons and controls set a state within your GUI and then call a single method that applies that state to ALL the controls on your GUI. When you get beyond a trivial GUI this can be a life-saver. If I'm not being clear, leave a comment and I'll leave an example for you.
Property sheets:
There is a special case for GUIs--the property sheet style GUI. I've done a LOT of these and they are irritating as HELL. They tend to have dozens or hundreds of controls on them, each GUI control tends to be tied to a specific field in your model and there are just hundreds of lines of copy and paste boilerplate code connecting them, each group copied and pasted with a few items changed--at minimum it's like 3 lines of code per control (Create control, copy value in and copy value out).
I always write these with a "Smart" controller--one that can intelligently bind the control to some data without any unique code. This can get tricky and if this is your problem let me know in the comments and I can give you some general advice as to some tricks you might try. I've gone from a minimal reflective solution to a full-on XML based solution. Were I to do it again, I might consider annotation-based.
Example of MVC:
Note, this is just an example, there are a MILLION ways to do MVC.
In your MAIN:
Instantiate MyView
Instantiate MyModel
Instantiate MyController(myView, myModel)
myView.setVisible(true)
in MyView
probably extends Frame
Most components are public final (public final Button b=new Button())
If public members make you nervous, use getters--same EXACT effect as public final members with a little extra syntax.
Remember that you can set final members in your constructor.
May have general methods such as reset(), but MyController may be a better place for this.
in MyController
saves references to myView and myModel
adds listeners to myView where necessary (see advice on listeners above)
configures myView based on state of myModel
when "done" button pressed, copies state from myView to myModel
notifies myModel that it's data has been updated and destroys itself.
in MyModel:
This would be a typical model class, it would contain your business logic (mostly not used as part of the GUI, that's more like GUI logic in MyController. The controller would tend to set values in your business logic then call some method like updated() to cause some business logic to take control. It should know nothing of a GUI--this is your "pure" business class.
Sometimes the GUI might call an update() or some other method to trigger some data change and then reload the GUI controls from the Model--this is a fairly good way to integrate your business logic with your GUI without your model knowing about the GUI...
Also, as I said above, I would put more work into MyController if I was working with property sheets just due to the sheer number of lines of boilerplate that you end up with if you aren't smart about it.
Note that View and Controller are nearly always paired. You can't just replace a Swing view with a web view and expect the controller to remain unmolested--but the model should not ever change for the view or controller.
You should take a look at the best practices for GWT applications first:
http://code.google.com/events/io/2009/sessions/GoogleWebToolkitBestPractices.html
One of the concepts they talk about is that of MVP (not MVC) to structure your application. There's a sample project on Google Code that you can look at to understand how to structure a GWT application in this way:
http://code.google.com/p/gwt-mvp/