Let’s imagine that we have requested the Home page while working with the already created part of our GuessTheWord application. Tapestry took an instance of the Home page class from the pool and used it to produce an appropriate HTML to be sent to our browser. In this process, the page class has checked whether there is some initial value to display in the secretWord text box (implemented as a TextField component). For this, the getTheWord() method of the page class was invoked. We have trusted Tapestry to create and maintain theWord property by writing an abstract getter method like this: public abstract String getTheWord(); Because of this, theWord property will be initially always set to null, so the empty text box will be displayed, or exactly what the creators of the Web application wanted. But let’s imagine that we have created the same property in the traditional Java way, by writing a private class member and accessor methods for it ourselves: private String theWord;
public String getTheWord() { return theWord; }
public void setTheWord(String theWord) { this.theWord = theWord; } Say we have played with the application and tried to guess the secret word. Every time we submitted the form with a version of the secret word entered into the secretWord component, an instance of the Home page class on the server side was used to serve our submission. The setTheWord() method of that page class was invoked to store our word in its private property. Then some code (yet to be written) was used to define whether the word is correct or not and to act accordingly. After a few hundred attempts we have finally managed to guess the secret word and left the application, to do something else equally exciting. The Home page instance we dealt with the last time still stores the word we have guessed in its private theWord member. It goes to its pool to rest and wait until another user comes try and guess the secret word. Say Tapestry chooses to serve the new user that same Home page instance we just left, with the secret word stored in it. As usual, when producing HTML to be sent to the user, the page class will check whether components have any initial values. For the secretWord component, it will invoke the getTheWord() method, and the method will happily return that same secret word we have spent so much effort to guess. So the next user will see the Home page with the secret word already entered in the text box. It will be masked, yes, because we have set the hidden binding for the secretWord component to true, but for the new user it will be enough to press the Submit button to see the sacred wisdom of the Secret page. Is that fair? I don’t think so. What we actually need to do is to set theWord property to its default value, null, every time an instance of the Home page is sent to the pool. This is exactly the additional functionality Tapestry takes care of when we trust it to create a property for us (by providing only an abstract getter method). When Tapestry sees the abstract getter, it automatically creates an appropriate private member of the page class, the default concrete getter and setter methods for it and some other code needed to set the property back to its default value every time the page class instance is sent to its pool. So you can see that it makes a lot of sense to trust Tapestry with creating page properties for us. There can be, however, cases when we have to do all the work ourselves.
blog comments powered by Disqus |
|
|
|
|
|
|
|