摘要: J2EE Patterns
The second day was an unseasonably hot day for the month of October. The class itself was all warmed up and ready to grapple with a new set of topics. Today, some of the topics and patterns we would look at were CMP 2.0, Primary Key Generation Strategies (such as UUID and Sequence Blocks), the Read Mostly Pattern, and Data Transfer Objects.
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
The first 45 minutes of class were enthusiastically spent completeing the DAO lab from yesterday after which Owen delved into the next section, on CMP 2.0. The CMP section promised to be interesting, as we would be using some really cool open source tools for the lab such as Middlegen and XDoclet.
The entry point into the discussion on CMP 2.0 was entity beans, but as is common in most such advanced courses, there was a slight digression into a discussion on the Sepukku pattern, in which entity beans can invalidate themselves. As one student had trouble with the name, Owen explained the Japanese phenomenon in which a person kills themself when they have dishonoured their family. Can an entity bean really dishonour it's container?
CMP 2.0 and some Cool Tools
Coarse-grained, heavy weight entity beans should technically be a thing of the past, fallout from the archaic EJB 1.1 spec. With advanced O/R mapping in EJB 2.0, entity beans can now be lightweight and fine grained, encouraging relationships. With CMP 2.0, cardinality and referential integrity are container managed.
Now that you can create a fine-grained domain model without worrying about how to persist it, there's the tedium of actually creating your CMP beans. There are some really cool tools such as Middlegen and Toplink that make the task of creating your object model (from database tables) much easier. Used in concert with XDoclet and Ant, Middlegen examines your existing tables and generates EJB 2.0 compliant entity bean java files which contain XDoclet tags; these XDoclet tags in turn are used to generate EJB deployment descriptors, Home and Remote interfaces.
In the ensuing lab, we were provided with two populated database tables, Team and Player, with a one to many relationship. The objective of the lab was to automate the generation of our Player and Team CMP entity beans using Middlegen and XDoclet. Once the CMP entity beans were created, we used Ant to run an XDoclet script. It was interesting and somewhat baffling to see the tags generated by XDoclet. As this lab built upon the previous one, we had to make some modifications to our DAO interface, now that it would use our newly generated Player and Team entity beans. One of the advanced exercises was to turn on the GUI option for the Middlegen tool and play around with it, changing cardinalities and the directions of relationships between our two tables.
Lunch with Dr. Slimani
During lunch, I spoke with Said Slimani, a Ph.D. in engineering currently working as a software architect who designs, and develops projects that are to be integrated within an intranet used by Barnes and Noble.
"The intranet for Barnes and Noble is a vital tool for corporate communication and is being used throughout our company by a wide user base for various tasks. Currently I am working on several projects. Their objective is to meet the need of our users for better communication and to speed up processing time by automating several of their tasks, and make it available on their intranet site," he explained.
Slimani signed up for the Patterns course as he was interested in implementing some of the patterns learned in class to his system at work. He was very interested in learning "well tested patterns, along with refactoring strategies, for designing, implementing, and maintaining real-world J2EE applications." Slimani was particulary interested in learning more about J2EE frameworks. We would be looking at Struts later on in the week.
UUID and Sequence Blocks
After lunch, we looked at the UUID and Sequence Blocks patterns. Primary Key Generation patterns address the need to generate primary keys in a database and application server neutral fashion. The Universally Unique Identifiers (UUID) strategy creates string based primary keys that are unique across space and time in memory using system information and random number generation. A singleton or stateless bean is created that exposes a getUUID() method which returns a unique string comprised of the current time down to milliseconds, the IP address of the object, the memory address of the object (a hash code), and a 32 bit integer generated by the java.security.SecureRandom class.
The class got involved in a discussion on how there is still a possibility of generating the same UUID. How much precision is really required to guarantee a unique id? One student commented that "You'd need about 50, 000, 000 hits a day to even come close to the problem of two people hitting your system (calling the getUUID() method) in the same millisecond." If anything, the random 32 bit integer would ensure uniqueness in the unlikely circumstance that all the other values (time, IP address, memory address) are not unique.
The Sequence Block strategy addresses the need to create integer-based, sequential primary keys using a method that is once again database and application server independent. In this pattern, an entity bean is used to generate numbers in sequence. A session bean requests blocks of keys from the entity bean, and then issues them to the client as needed, which greatly increases scalability. Each subsequent block of keys is requested within a new transaction each time, ensuring that no two blocks are identical. The entity bean is backed by a transactional store, such as a relational database which keeps track of the most recently created ids.
Let's All Go to The Lobby
Owen made a point of providing us with short breaks between sections or during labs, to go out into the lobby for refreshing, non-alcoholic beverages and an assortment of snacks provided to us by the good people at the training facility. In the mornings, fresh bagels were lain out but these were scarce and often all gone if you didn't come at least half an hour before class. But the warm muffins were a good substitute, cookies and fruits in the afternoon were an enjoyable treat, and all throughout the day, you could hear the sounds of juice and pop cans being cracked open as students sated their thirst or caffeinated themselves to stay alert. The days were long and a lot of information was being fed to us, so these short breaks helped us absorb this information, discuss issues with colleagues over a drink, and of course take care of normal human exigencies.
The Read Mostly Pattern and a Comparative Lab
The principle behind the Read Mostly Pattern is to avoid unnecessary database hits. By caching data, it can be seen that read-only entity beans are high-performing and simple to implement. <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />
In the 'Read-Write vs Read-Only lab' we compared the Read-Write entity beans vs Read-Only entity beans to see if there was any substantial difference in thread running times. We created ReadWrite entity beans of a Team and Player class. Using a ThreadedClient, we simulated a a multiple user environment by instantiating 10 threads of the client all accessing the entity beans. We instantiated the ThreadedClient several times to ensure that the beans have been created and pooled so that repeated calls would be more accurate. The thread running time, on average was between 100 - 200 milliseconds.
With the read-only versions of the same entity beans, the thread running time went down to about 50 milliseconds.
Domain and Custom Data Transfer Objects
We ended off the day with a section on Domain and Custom Data Transfer Objects (DTOs). The context for the Data Transfer Object pattern is the need to shuttle information or data around a distributed J2EE system. It is commonly the client's need for data that prompts the use of this pattern, however it is applicable at any time where remote communication is occurring and there is an imbalance between latency and traffic (i.e. when traffic is too high). In a distributed application, it is always important to balance the number of hits vs. the size of the data being transmitted. Increasing the size of the data being transmitted can increase the latency of an individual request/response pair, but it can also greatly reduce the number of request response pairs necessary to perform a business function.
By encapsulating data details within a wrapper (DTO) class, we can make fewer network calls to transmit the same amount of data, more data can be accessed within a single transaction and security check, small changes to the data model are not made apparent at the interface level, and validation of input parameters can occur locally to the client.
The Domain DTO pattern is a specialization of the DTO pattern in which you create a copy of server side domain objects so that clients can operate locally on the same domain model. So for each entity bean in your domain model, you simply create a corresponding DTO that transmits its attributes. One of the benefits of the Domain DTO approach is fewer network calls in which whole graphs of DTO objects that model entity relationships can be passed back and forth in one call. One of the drawbacks of this approach is the heavy coupling that results between the client and server now that the client is responsible for instantiating and manipulating DTOs; client side code that manages DTOs is now dependant on the domain model so that if the domain model changes, clients have to make corresponding changes. Another drawback of the Domain DTO approach is the fact that if a client needs to access only 4 of 20 attributes, the transmission of a DTO with all 30 attributes is wasteful. This latter drawback facilitates the use of the Custom DTO pattern.
The Custom DTO pattern allows for the creation of DTOs that represent the data required for a particular Use-case. These DTOs potentially encapsulate data from many sources which means that complex hierarchies can be flattened into simple objects. Network overhead is reduced as there is no longer the transfer of unnecessay data.
Day 3 Preview
People stayed in a little later after class to work on some of the earlier labs, discuss the topics of the day, and talk about issues in the industry. There was no eagerness to leave it seemed. However, at , the closing time for the Microtek facility, we had to leave and join the bustling streets of downtown