Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Professional Java.JDK.5.Edition (Wrox)

.pdf
Скачиваний:
31
Добавлен:
29.02.2016
Размер:
12.07 Mб
Скачать

Chapter 2

package=”${name}.hibernate” genXDocletTags=”false” genIntergratedCompositeKeys=”false”

javaTypeMapper=”middlegen.plugins.hibernate.HibernateJavaTypeMapper”

/>

</middlegen>

<mkdir dir=”${build.classes.dir}”/> </target>

The hbm2java target determines where the database table mappings reside using the path id element and then creates the hibernate mappings to be used to access the items in the tables of the targeted database:

<path id=”project.class.path”>

<pathelement path=”${build.gen-src.dir}”/>

<pathelement path=”${build.gen-src.dir}/test/hibernate”/> <fileset dir=”${build.gen-src.dir}/test/hibernate”>

<include name=”**/*.hbm.xml”/> </fileset>

<fileset dir=”lib”>

<include name=”**/*.jar”/> </fileset>

</path>

<!-- Hibernate mapping files -->

<fileset id=”hibernate.mapping.files” dir=”${build.gen-src.dir}/test/hibernate”>

<include name=”**/*.hbm.xml” /> </fileset>

<target name=”hbm2java” description=”Generate .java from .hbm files.”>

<pathconvert refid=”hibernate.mapping.files” property=”hibernate.mappings” pathsep=” “/>

<java classname=”net.sf.hibernate.tool.hbm2java.CodeGenerator” fork=”true”> <classpath refid=”project.class.path” />

<arg line=”--config=test.xml”/> <arg line=”${hibernate.mappings}”/>

</java>

</target>

The test.xml file passed as a parameter to the CodeGenerator application specifies the renderer operations that will be performed during code generation. This code snippet tells you what is needed for a basic rendering procedure:

<codegen>

<generate renderer=”net.sf.hibernate.tool.hbm2java.BasicRenderer”/> <generate suffix=”Finder”

renderer=”net.sf.hibernate.tool.hbm2java.FinderRenderer”/>

</codegen>

106

Tools and Techniques for Developing Java Solutions

The next target, compile-hibernate, performs Java compilation of the domain model objects that were created by the mapping and conversion procedures:

<target name=”compile-hibernate” depends=”middlegen” description=”Compile hibernate Business Domain Model”>

<javac srcdir=”${build.gen-src.dir}” destdir=”${build.classes.dir}” classpathref=”lib.class.path”

>

<include name=”**/hibernate/**/*”/> </javac>

</target>

<target name=”all” description=”Build everything” depends=”compile-hibernate”/>

<target name=”clean” description=”Clean all generated stuff”> <delete dir=”${build.dir}”/>

</target>

</project>

JMeter

Software development typically is performed as a solitary endeavor until it is time to integrate with new and existing components on your deployment system. Understanding how your applications will perform under real-life conditions is a legitimate concern for all software developers.

With the JMeter application available at http://jakarta.apache.org/jmeter/, you can generate and manage user simulations for your applications using a robust GUI application console to collect performance measurements. This is performed by adding ThreadGroups to your test plans to simulate users and configuration elements that simulate and stimulate your applications (see Figure 2-10).

With enterprise development efforts, performance discovery cannot be performed early enough in your development activities to determine what kind of loads your applications can handle alone and when packaged with other applications targeted for deployment.

Rather than delving into a broad range of scenarios to demonstrate the load testing abilities of JMeter and the wide range of testing protocols that can be applied, it would probably be more beneficial to describe from a high-level view all of the different capabilities that the tool possesses that can facilitate your development operations.

JMeter is comprised of six different components (Listeners, Config Elements, Assertions, Preand PostProcessors, and Timers) to measure your application’s performance in your development space.

107

Chapter 2

JMeter

I’ve spent all my time developing this component.

 

 

group

I wish I knew how well it will work when it is

 

 

integrated with all of the pieces being assembled?

Component 1

 

 

Will my component perform well when deployed?

group2

group3

 

 

Component 2

 

 

 

Component 3

Emulate multiple users

Database

Developer

Figure 2-10

Listeners are conduits to data that is collected by the JMeter application during testing operations. Data collections can either be saved off to files or shown in graphical representations like graphs and tables.

Config Elements are used by the JMeter application to perform disparate protocol requests to back-end components like Web, database, and Lightweight Directory Access Protocol (LDAP) servers. TCP and FTP requests can also be performed to test your system’s components.

Assertions can be implemented to discover problems with HTML tags and error strings that can be introduced by testing activities.

Preand Post-Processor tests act a lot like servlet filters that can manipulate code prior to being run as well as after. These components allow Web requests to be modified prior to being passed along for interpretation. An example of this would be to translate an XML response to HTML during Web application transactions.

By establishing test plans using ThreadGroups, users can manually craft simulations through the GUI controls as well as generate capture and replay tests automatically by recording navigation flows using JMeter’s Recording Controller.

The latest JMeter 2.0 release has introduced many new features, as shown in Figure 2-11, to load test the functional behavior of your system and gather performance metrics so that your applications can be deployed with some assurance that they can handle difficult user loads.

108

Tools and Techniques for Developing Java Solutions

 

Mailer

 

Assertion

Visualizer

Aggregate

 

Results

Monitor

Report

 

 

 

Results

View Results

Graph Full

 

 

in Table

Results

Simple Data

 

 

 

 

Writer

 

Graph

 

View Results

Results

Spine

Tree

 

Visualizer

 

Listeners

Constant Gaussian

Throughput Random Timer

Timer

Uniform

Constant Random Timer

Timer

Timer

Regular

 

Save

Responses to

Expression

 

a File

Extractor

 

 

 

 

 

Generate

Result Status

Summary

Action Handler

Results

Post Processors

 

 

 

 

 

HTTP

 

 

 

 

 

 

 

 

Request

HTTP Cookie

 

 

 

User Defined

Defaults

Manager

 

 

 

 

 

 

 

 

 

Variables

 

 

JDBC SQL Query

 

 

 

 

 

 

 

Login Config

 

 

HTTP Header

 

Defaults

 

 

Manager

 

 

 

 

Element

 

 

 

 

JDBC Database

 

 

 

 

 

 

Thread

Single

 

 

 

Java Request

Connection Pool

 

 

HTTP

Defaults

Group

 

 

Defaults

Config

 

 

 

 

 

Authorization

 

 

 

 

Element

 

 

 

TCP

 

 

Manager

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

LDAP

Sampler

 

 

FTP Request

 

 

Config

 

 

 

 

Request

 

 

 

Defaults

 

JDBC Database

Defaults

 

 

 

 

 

 

 

 

 

 

 

 

 

Login Defaults

 

Config

 

 

 

 

 

 

 

 

JMeter

 

 

 

 

 

 

 

Element

 

 

 

 

 

 

 

 

*.xml

 

 

 

 

Duration

 

 

 

 

 

 

 

Assertion

Size

 

 

 

 

Response

 

 

 

 

 

Assertion

HTML

Assertion

 

 

 

 

 

 

 

 

 

 

 

 

 

Assertion

 

XML

 

 

 

 

BeanShell

 

 

 

 

 

 

Assertion

MD5Hex

Assertion

 

 

 

 

 

 

 

 

 

 

 

 

 

Assertion

 

Counter

 

HTTP URL

 

Assertions

 

 

 

 

 

 

 

Re-writing

 

 

 

User

 

HTML

 

Modifiers

 

 

 

 

 

 

 

 

 

 

Parameters

Parameter

 

 

 

 

 

 

 

 

Mask

HTTP User

 

 

 

 

 

 

 

 

 

HTML Link

 

Parameter

 

 

 

Parser

 

 

Modifiers

 

 

 

Pre Processors

Figure 2-11

Summar y

This chapter carried you from the abstract concepts of what it means to write quality software to the concrete details of how software tools are used in Java development environments. Along the way, you were provided information to give you a feel for what it is like to be a Java developer, including the following points:

The principles of software quality by which developers live

The habits that an effective software developer exhibits

109

Chapter 2

A few of the methodologies that software developers use

How and why to use many of the tools found in Java development environments

Chapter 3 continues the brief aside into thinking like a professional Java developer by discussing design patterns, which provide an intellectual repository from which you can learn to avoid common problems that face many Java developers, as well as how the developers of the Java programming language solved many of their issues.

110

Exploiting Patterns in Java

In Chapter 2, you learned about half of “thinking like a Java developer” when I discussed software development methodologies. This chapter handles the other half — the use of patterns to make you an effective Java developer.

This is not a patterns book. This chapter is included because patterns are critical to understanding and communicating the designs of application programming interfaces, tools, and other applications. This is because the vast majority of these technologies are built on top of design patterns.

If I had to pick one aspect of software engineering that I absolutely love, hands down, it would be software design. Designing software well is challenging and it requires a combination of creativity and problem-solving skills. The experience of creating a solution in software can be very rewarding. If you are just becoming familiar with the Java programming language, software design can be a little overwhelming. It’s like a blank canvas with a lot of colors from which to choose. Design decisions are difficult to make because — without experience — it is difficult to understand how the choices you make will affect the application later.

Learning design patterns is the single best way to increase your abilities as a software engineer. Technology changes very quickly. To give things a little perspective, learning a new technology is like reading a good book; learning patterns is like learning to read.

The focus of this chapter is to communicate why design patterns are important and highlight commonly occurring patterns. Hopefully, if you haven’t been turned on to patterns already, this chapter will give you some reasons to pursue them.

There are plenty of patterns books. I feel these three represent some of the best work written on the subject: Refactoring: Improving the design of Existing Code by Martin Fowler; Design Patterns: Elements of Reusable Objected-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides; and Applying UML and Patterns: An Introduction to ObjectedOriented Analysis and Design and the Unified Process by Craig Larman.

Chapter 3

This chapter will provide you with a strong definition of a pattern, an understanding of why patterns are important, tricks to understanding a pattern, and an explanation of important Java patterns. This chapter is divided into three main sections. The first section will discuss the rationale behind learning patterns and some examples of where they are used in software design. The second section, building patterns from design principles, will walk you through a series of exercises that show how to form patterns from basic design principles. Finally, the important patterns section will walk you through code examples of a subset of well-known design patterns.

Why Patterns Are Impor tant

One of my father’s favorite quotes was, “Experience is a good teacher, but a fool will learn from no other.” In software, experience is a good teacher, but lessons learned from experienced designers can help accelerate your design skills. A pattern is a documented lesson learned.

A pattern is a proven solution to a software problem enabling reuse of software at the design level. The purpose of a pattern is to conceptually pair a problem with its design solution and then apply the solution to similar problems. Code level reuse of software is desirable, but design level reuse is far more flexible.

With each application you work on, none of them will be the same. There will be similarities. Being able to recognize these similarities, combined with your knowledge of design patterns, will help bring confidence to the design decisions you make.

Patterns are one of the greatest resources you will have in the design of object-oriented software. They will definitely help you to master the Java programming language, be more productive, and develop effective Java solutions.

Keys to Understanding the Java Programming Language

Patterns help you understand the Java programming language. Compared to other programming languages, Java has a steep learning curve. It’s not that Java is harder to learn than other languages. Just the opposite, it has a very clean syntax and its structure is similar to other OO languages.

The language becomes difficult once you confront the vast number of APIs available to the Java programmer. The number of APIs available is a very good thing. Each API should be viewed as a tool in the toolbox for solving problems.

Leveraging existing software is a core practice in thinking like a professional Java developer. This allows you to save time and be more productive. The collection of APIs provided in the 1.5 JDK, as well as countless open source projects, represent what you don’t have to build from scratch.

This book examines several APIs such as Collections, Java2D, JMX, XML, EJB, JMS, JDBC, RMI, and Web Service. The list is pretty long, but it only scratches the surface on the number of APIs available. The truth is you cannot sit down and learn them all. Thankfully, there is no reason to learn them all. This is why design patterns are so important to learning Java.

Design patterns allow you to learn a new API quickly. If you understand the patterns used in an API, then you will be able to quickly understand, evaluate, and potentially integrate that code into your solution. It is much easier to learn and build on top of existing API’s than it is to reinvent the wheel and start from nothing.

112

Exploiting Patterns in Java

This is especially true when working with the J2EE framework. If you are working on a project and hear that a decision has been made to ignore the distributed transaction processing capabilities of a J2EE application server in favor of a homegrown solution, run and don’t look back. As a Java developer, you learn as much as you can and only build what you need.

J2EE is a standards-based solution. One misconception about the J2EE framework is that it is considered a product. J2EE is not a product. It is a specification that Sun published as a set of documents describing how a Web and EJB containers must behave. Then software vendors implement the specs and sell their products as part of a standards-based solution. This is important because the folks at Sun are pattern savvy. The APIs are all based on patterns. This is very good news for you and an excellent reason to gain a strong understanding of design patterns. If you do, you will be able to understand and leverage anything Sun throws your way.

Keys to Understanding Tools Used in Java Development

In addition to the wealth of APIs available to Java developers, there is also a large number of development tools for improving the software development process. A few tools are ANT, JUnit, and XDoclet. These tools offer extension points for integration as well as good working examples of the power of design patterns.

ANT

ANT is an XML-based build tool with several uses. One of the uses is to automate the building of a software project. It can also do the work of most scripting languages without being OS dependent. It’s built using a combination of several design patterns.

JUnit

JUnit is a unit-testing framework. Establishing automated unit tests is an excellent way to prove code changes so as to prevent introducing new bugs into your software. To use JUnit, you must extend the framework. By understanding the patterns JUnit is built on, you will be able to take advantage of automated unit testing.

XDoclet

XDoclet is a code-generating framework. It allows you to imbed meta data in the comments of your code. The meta data is used to generate supporting code as well as XML descriptor files. XDoclet makes it easy to sync derived software artifacts common when developing EJBs, Servlets, and persistent data objects such as hibernate and JDO.

There are numerous other tools available to the Java developer. Understanding the patterns these tools are built on takes some of the magic out of how they work. By understanding design patterns you will be able to use and extend these tools to build better software.

Keys to Developing Effective Java Solutions

Patterns help you build effective solutions using Java. Patterns help you communicate design concepts as well as gain an appreciative knowledge of underlying design principles.

113

Chapter 3

Develop Common Design Vocabulary

There is a lot of value in the pattern name. The name provides a common vocabulary for software engineers to use to communicate. The patterns in this book are taken from the widely accepted GoF.

For example, say you need two to parts of a system to communicate even though they expect different interfaces. Use the Adapter pattern. If you have a situation where several algorithms will solve the same problem, use the Strategy pattern. This chapter goes into those two patterns, as well as several others, in detail. The point of mentioning them now is to show the value in understanding patterns.

Understand the Fundamentals of Design

This reason for learning patterns is near and dear to me. Initially, after being introduced to the concepts of object-oriented programming, I failed to see the relevance of the object-oriented concepts. It seems like more work with limited benefits. It wasn’t until I was exposed to design patterns that I started to gain a real appreciation for the power of the OO concepts.

Patterns will help you fully understand fundamental design principles. Understanding the fundamentals of software design is critical to becoming a confident software designer. Patterns provide a concrete example of how to apply various design principles. Essentially, design is about making decisions.

Knowing which decisions lead to good software design, and which lead to problems in the future, makes all the difference in building effective solutions.

Design decisions center on identifying the pieces of your software system and how they will work together to accomplish your objective. Good design is the result of the lessons learned often from living through a bad design nightmare.

Abstraction, polymorphism, and inheritance are the three principal concepts of object-oriented design, Abstraction is the practice of modeling the relevant aspects of real-world concepts. Polymorphism is type substitution allowing one class to take the place of another. Inheritance is the practice of creating specialization and generalization relationships between classes.

Some design criteria to consider when building a Java solution include:

Protected Variations. This means that you need to isolate volatility in your application. If you feel an application component could change, then take steps to segregate that component using interfaces. Interfaces will allow you to change the implementing class without affecting existing application dependencies.

Low Coupling. The purpose of this design concept is to ensure that changes made in one section of code don’t adversely affect another unrelated section. For example, does a user interface change require a change to the database? If so, the application could be brittle where any small change propagates throughout the software system.

High Cohesion. The practice of tying closely related things together tightly.

This is important to understanding design patterns because each pattern is the application of one or more design principles. Once you understand abstraction, polymorphism, and inheritance, it is easier to understand how patterns can reduce the complexity of software design.

Software design goals are important, but there is a large gap between goals and real implementations. Patterns bridge this gap and realize these goals; nothing teaches like a good example. The next section discusses some foundation on how to get started with patterns.

114

Exploiting Patterns in Java

Building Patterns with Design Principles

At the core of any pattern is a collection of design principles. This section looks at a simple and unconventional approach to building patterns from the ground up. The approach is to start with a simple design and gradually make changes so that the design is more flexible. Each design change becomes a step in building more complex design patterns. By following the exercises in this section, it will be clear how applying design principles makes software more flexible. This allows the reader to understand the mechanics behind patterns a small piece at a time.

This section starts off with the design of a single class. From this single class design an association is added, followed by an interface. These two steps add flexibility to the single class design. Understanding this flexibility has important ramifications for understanding design patterns. The final section shows an example of merging the concepts of association and inheritance, which is common in a number of design patterns.

Designing a Single Class

A single class doesn’t constitute a design pattern, but it is a design. And there is nothing wrong with simplicity. Part of the design process is assigning responsibility to an object, as in Figure 3-1.

Teacher

-name

+getName()

+getSSN()

+teachClass()

+takeAttendance()

+proctorTest()

+gradePaper()

+reportGrades()

Figure 3-1

It is very common for a class to become bloated with several methods not related to the abstraction the class represents. This can cause dependency problems down the line and does not fit with the high cohesion design principle. In this example, the Teacher class contains several methods related to teacher responsibilities. The solution is to push to the right or delegate the methods that do not belong with the abstraction. The phrase “do not belong” is subjective. Any design decision could be wrong. As long as you justify it with sound OO principles, don’t worry — you can always change it later when the problem is clearer.

Creating an Association between Classes

All the teacher responsibilities have been delegated to a class called TeacherResponsibilities. Again visualize the methods being pushed to the right. Figure 3-2 shows how responsibility has been delegated through an association.

115

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]