J2EE模式一瞥(5)
2002.10
www.theserverside.com,网站,我想做J2EE的人都知道,是一个很棒的地方。如果您还不知道这个地方,还不赶快去?
最近,该网站推出A Look Inside J2EE Patterns,系列文章,个人认为蛮不错的,而且很成体系,所以萌生了翻译、整理成中文的念头。
第五天:
On the final day of J2EE Patterns, we tied everything together and applied all that we learned in the past week. Some of the topics we covered were the WebWork open source framework and Antipatterns. To wrap things up, we engaged in a 'Pattern Hatching' exercise and later split up into groups to apply the patterns we learned in the final lab.
Owen started off the morning by asking the class, "What is a framework?"
A response came from the front of the room, "It's something that helps you accomplish what you want." There was an unsually long silence as we tried to grapple with this answer. "Could I have been more vague?" came the humorous follow up which prompted Owen to rephrase his question.
"What comprises a GOOD framework?" Owen asked the class again.
"A good framework makes use of patterns," came the more enlightened answer.
Frameworks allow you to write code that is more focused on the problem you are trying to solve, without having to take care of all the low level plumbing. Frameworks use design patterns, encouraging you to code to known architectures such as the Model View Controller (MVC) design paradigm.
WebWork
WebWork, an open source framework, provides a methodology and a framework that enables you to rapidly develop Java Web applications. It utilizes the Service to Worker ('pull' hierarchical MVC), the Front Controller, and the View Helper Web patterns, which we studied on the fourth day of class.
The Controller in WebWork is embodied by a ServletDispatcher, which bundles and routes Java requests to specific Action classes and JSPs as mandated by the configuration file. It filters the request and response behaviour according to the mapping present and the results of related operations. WebWork action classes, used as Dispatchers and ViewHelpers, delegate business logic to isolated classes such as POJOs (plain old Java objects) or SessionBeans.
Java Beans and WebWork-specific Action classes (implementing webwork.action.Action) comprise the Model. WebWork encourages the idea of code reuse, which we emphasized in our study of the Struts framework, by enabling all Action classes to be empty of any servlet API calls; this enables them to be used in a Swing application if the need should ever arise.
In WebWork, Actions are created by ActionFactories, which gather their information from factory-generated ActionContext instances that are associated with their Thread of execution. Requests are wrapped in a webwork.action.ActionContext and are not web-specific, always available by calling the ActionContext.getContext() method. Return types from the ActionContext methods are generic Objects such as Map types. When a method is executed within a servlet container, the map includes servlet-specific information such as HttpServletRequest attributes. When the same request is made outside of the servlet container, the map contains generic application-specific information.
The View in WebWork is embodied by JSP pages and Servlets, XML and HTML pages, and non-Web based technologies such as Swing Java classes. A rich set of taglibs is associated with the WebWork framework and can aid in building complex views and solving logical problems. We then looked two additional features provided by WebWork: A Value Stack, and a rich expression language, which collaboratively help to limit and simplify the code in your view. This was followed by an interesting comparison of the WebWork and JSTL expression languages.
Antipatterns
"Knowing about antipatterns helps us learn from the experience of those who have gone before," Owen said with a gleam of wisdom in his eyes.
An antipattern is a literary form consisting of words and diagrams that is used to communicate a commonly occurring problem. It is past experience 'encapsulated' in the form of good advice. An antipattern addresses a system of errors with the same root cause.
Design patterns provide a blueprint for common solutions. They establish good ways to solve a problem and provide an abstract communication vehicle; however, Design patterns do not identify problems in existing code, warn against problematic implementations, or analyze the root causes of a problem.
It is important to study antipatterns as they train us to better identify and solve existing problems as we refactor our code. Antipatterns and refactoring are intimately related. Refactoring is the work required to get from an antipattern to a design pattern. Antipatterns help you decide what to refactor, identify 'broken areas' in your code, and elminate traps while you refactor.
One antipattern we talked about was the Y2K. We discussed the motivations for why Y2K came about, one of the reasons being that memory and storage were more precious in the past and it was thought that the software that was being created back then wouldn't be around for another 30 years.
Owen said that the moment you press Control-S to save your code, it becomes legacy code, emphasizing the point that it is always important to think about the future consequences of the way you design your applications today.
We looked at several categories of antipatterns and studied an example of each. Some of the categories were coding and idiom antipatterns (such as Java memory leaks), architectural antipatterns (such as round tripping), and process antipatterns (such as performance thrashing). One of the development tier antipatterns we looked at was 'The Magic Servlet', which places the model, view and controller logic into a single servlet.
Pattern Hatching Exercise and a Group Lab
It was Day 5, the home stretch, and the class was visibly exhausted from an intense week of eating, sleeping, and breathing J2EE Patterns. Owen did a great job in the afternoon of keeping things lively. Apart from the usual energy he showed through his emphatic gestures, flailing hands, and lightning wit, Owen tactfully used varying accents to explain certain slides in the voices of a J2EE-savy mobster from
Brooklyn and a Texan cowboy. As a treat, he sang us his famous 'EJB' song, sung to the tune of '99 bottles of beer on the wall'.
The Pattern Hatching Exercise proved to be just the thing we needed to start communicating our knowledge of J2EE patterns. Learning about patterns is different from using them to solve problems and to communicate. Patterns are things that take time and practice to utilize effectively. We would spend the next couple of hours applying patterns, and thinking about how to use them in a real system.
As an example application, we looked at the 'Hungry Hippo Hamburger Hotel', which was a J2EE app that enables wireless access protocol ordering of custom hamburgers. The application remembers customers and their previous orders, and uses that information to possibly display customized messages or menus to returning customers. It also notifies the delivery system when a hamburger is ready.
The class actively brainstormed ideas on how this application would be designed. We asked ourselves questions like 'What reference architectures can we use?', 'What J2EE frameworks can we use?', etc. As we spewed out ideas, Owen wrote them on the board. It was decided that we should use WebWork as our framework. One student said that we would need a WAP interface, and for beeper clients, JMS queues for asynchronous communication. Laughhter erupted as somebody retorted that "if we queue up our orders, our hamburgers could get cold." It was said that our wireless client would first talk to a gateway, which would communicate with a Web server. The WAP client would basically pass in lightweight Strings comprising order information. We'd need our typical entity EJBs such as an OrderBean and a CustomerBean.
A brief debate between Owen and one of the students followed on whether we should use stateful session beans to hold our state or HTTPSessions. The class was generally opposed to using stateful session beans, so we decided to store state in the session. To decouple our layers, we wanted to use the Business Delegate and the Data Access Objects (DAOs). To increase the performance of our system, we decided to use the Read Mostly Pattern or JDBC for Reading (for the bulk loading of data).
For the final lab, the class was separated into 4 groups and provided with a series of pattern-related topics in which we would combine patterns we had learned about or even 'hatch' new patterns to solve a particular problem.
One group looked at the Visitor pattern and discussed how it could be used to refactor a sample gambling application we had worked with in a previous lab. Another group drew up a preliminary design for enabling our completed gambling application to fully integrate with another game system. They discussed particular patterns and groups of patterns that would be used to accomplish this, backing up their decisions by addressing the guiding principles and motivations behind them. A third group's task was to search the Web for a pattern not covered in the course; they selected the Observer Pattern, which defines a one-to many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. They covered it extensively, using PML and Sequence diagrams.
Patterns: A Language and a State of Mind
The use of patterns is prevalent in many fields such as Art and Architecture, the Sciences, Manufacturing, and Software development. Patterns are a convenient and effective way of transmitting expert knowledge. In the J2EE community, we strive to formalize the presentation of patterns and ensure the free distribution and promotion of them. During the course of the week, we learned more than just the names of and motivations behind different patterns. We learned how and when to use them, and started thinking about design problems in an entirely new way.
Patterns usage offers the benefit of better communication in projects, quicker decision making, and the ability to analyze existing and future solutions with improved mental tools. Armed with a knowledge of patterns, many felt that they could now quickly begin to tackle problems and save themselves a great deal of confusion. Students who were already using existing patterns felt more passionate about them and were very interested in implementing related patterns in their systems.
There were many different motivations behind the attendees' decisions to attend J2EE Patterns; however, the common benefits they reaped from the course were starting to become clear. They were heading back to their projects with a renewed sense of confidence. No longer would they have to work hard to solve a problem for which there was already a documented solution. Empowered with the techniques and mindset to look at a problem from a higher-level and with the knowledge of 'pattern-speak' (the necessary vocabulary to communicate and understand patterns), many were ready to go back and apply the patterns they had learned, to imbue their new or existing projects with greater robustness and integrity.