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

Professional Java.JDK.5.Edition (Wrox)

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

Chapter 1

Method

Description

boolean getBoolean(String key,

Returns the boolean associated with a

boolean def)

specified key. If the key does not exist, it is

 

created with the default value def and this

 

default value is then returned.

byte[] getByteArray(String key,

Returns the byte array associated with a

byte[] def)

specified key. If the key does not exist, it is

 

created with the default value def and this

 

default value is then returned.

double getDouble(String key,

Returns the double associated with a

double def)

specified key. If the key does not exist, it is

 

created with the default value def and this

 

default value is then returned.

float getFloat(String key, float def)

Returns the float associated with a specified key. If the key does not exist, it is created with the default value def and this default value is then returned.

int getInt(String key, int def)

Returns the integer associated with a specified key. If the key does not exist, it is created with the default value def and this default value is then returned.

long getLong(String key, long def)

Returns the long associated with a specified key. If the key does not exist, it is created with the default value def and this default value is then returned.

Setting Preference Values on the Node

Along with each get method is a put version intended for setting the information associated with a given configuration parameter’s key name.

Method

Description

void put(String key, String value)

void putBoolean(String key, boolean value)

void putByteArray(String key, byte[] value)

void putDouble(String key, double value)

void putFloat(String key, float value)

void putInt(String key, int value)

void putLong(String key, long value)

These methods set a configuration parameter (the name of which is passed in as key) to a specific type. If key or value is null, an exception is thrown. The key can be at most 80 characters long (defined in

MAX_KEY_LENGTH) and the value can be at most 8,192 characters (defined in MAX_VALUE_LENGTH).

66

Key Java Language Features and Libraries

Events

Two events are defined for the Preference class — one fires when a node is changed in the preference tree, and the second fires when a preference is changed. The methods for these events are listed in the next table.

Method

Description

 

 

void addNodeChangeListener

Adds a listener for notification of when a

(NodeChangeListener ncl)

child node is added or removed from the

 

current preference node.

void addPreferenceChangeListener

Adds a listener for preference change

 

events — anytime a preference is added to,

(PreferenceChangeListener pcl)

removed from, or the value is changed,

 

listeners will be notified.

void removeNodeChangeListener

Removes a specified node change listener.

(NodeChangeListener ncl)

 

void removePreferenceChangeListener

Removes a specified preference change

(PreferenceChangeListener pcl)

listener.

 

 

Other Operations

The following table lists the other methods in the Preference class, such as writing any pending changes to the backing store, resetting the preference hierarchy to empty, saving the hierarchy to disk, and other operations.

Method

Description

 

 

void clear()

Removes all preferences on this node.

void exportNode(OutputStream os)

Writes the entire contents of the node (and

 

only the current node) to the output stream

 

as an XML file (following the preferences.

 

dtd listed below).

void exportSubtree(OutputStream os)

Writes the entire contents of this node and all

 

nodes located below this node in the prefer-

 

ences tree to the output stream as an XML

 

file (following the preferences.dtd listed

 

below).

void flush()

Writes any changes to the preference node to

 

the backing store, including data on all chil-

 

dren nodes.

void remove(String key)

Removes the value associated with the

 

specified key.

 

 

 

Table continued on following page

67

Chapter 1

Method

Description

 

 

void sync()

Ensures that the current version of the pref-

 

erence node in memory matches that of the

 

stored version. If data in the preference node

 

needs to be written to the backing store, it

 

will be.

String toString()

Returns a string containing User or System,

 

depending on which hierarchy the node is in,

 

and the absolute path to the current node.

 

 

Exporting to XML

The Preferences system defines a standard operation to export the entire tree of keys/values to an XML file. This XML file’s DTD is available at http://java.sun.com/dtd/preferences.dtd. This DTD is also included here:

<?xml version=”1.0” encoding=”UTF-8”?>

<!-- DTD for a Preferences tree. -->

<!-- The preferences element is at the root of an XML document representing a Preferences tree. -->

<!ELEMENT preferences (root)>

<!-- The preferences element contains an optional version attribute, which specifies version of DTD. -->

<!ATTLIST preferences EXTERNAL_XML_VERSION CDATA “0.0” >

<!-- The root element has a map representing the root’s preferences (if any), and one node for each child of the root (if any). -->

<!ELEMENT root (map, node*) >

<!-- Additionally, the root contains a type attribute, which specifies whether it’s the system or user root. -->

<!ATTLIST root

type (system|user) #REQUIRED >

<!-- Each node has a map representing its preferences (if any), and one node for each child (if any). -->

<!ELEMENT node (map, node*) >

<!-- Additionally, each node has a name attribute --> <!ATTLIST node

name CDATA #REQUIRED >

<!-- A map represents the preferences stored at a node (if any). --> <!ELEMENT map (entry*) >

<!-- An entry represents a single preference, which is simply a key-value pair. -->

<!ELEMENT entry EMPTY >

68

Key Java Language Features and Libraries

<!ATTLIST entry

key CDATA #REQUIRED value CDATA #REQUIRED >

Using Preferences

The following example sets a few properties in a node in the user tree, prints out information about the node, and then exports the information to an XML file:

import java.util.*; import java.util.prefs.*; import java.io.*;

public class PreferenceExample {

public void printInformation(Preferences p) throws BackingStoreException

{

System.out.println(“Node’s absolute path: “ + p.absolutePath());

System.out.print(“Node’s children: “); for(String s : p.childrenNames()) {

System.out.print(s + “ “);

}

System.out.println(“”);

System.out.print(“Node’s keys: “); for(String s : p.keys()) {

System.out.print(s + “ “);

}

System.out.println(“”);

System.out.println(“Node’s name: “ + p.name()); System.out.println(“Node’s parent: “ + p.parent()); System.out.println(“NODE: “ + p); System.out.println(“userNodeForPackage: “ +

Preferences.userNodeForPackage(PreferenceExample.class)); System.out.println(“All information in node”);

for(String s : p.keys()) {

System.out.println(“ “ + s + “ = “ + p.get(s, “”));

}

}

public void setSomeProperties(Preferences p) throws BackingStoreException

{

p.put(“fruit”, “apple”); p.put(“cost”, “1.01”); p.put(“store”, “safeway”);

}

public void exportToFile(Preferences p, String fileName) throws BackingStoreException

{

try {

69

Chapter 1

FileOutputStream fos = new FileOutputStream(fileName);

p.exportSubtree(fos);

fos.close();

} catch(IOException ioe) {

System.out.println(“IOException in exportToFile\n” + ioe); ioe.printStackTrace();

}

}

public static void main(String args[])

{

PreferenceExample pe = new PreferenceExample();

Preferences prefsRoot = Preferences.userRoot();

Preferences myPrefs = prefsRoot.node(“PreferenceExample”);

try { pe.setSomeProperties(myPrefs); pe.printInformation(myPrefs);

pe.exportToFile(myPrefs, “prefs.xml”); } catch(BackingStoreException bse) {

System.out.println(“Problem with accessing the backing store\n” + bse); bse.printStackTrace();

}

}

}

The output to the screen is shown here:

Node’s absolute path: /PreferenceExample Node’s children:

Node’s keys: fruit cost store Node’s name: PreferenceExample

Node’s parent: User Preference Node: /

NODE: User Preference Node: /PreferenceExample userNodeForPackage: User Preference Node: /<unnamed> All information in node

fruit = apple cost = 1.01 store = safeway

The exported information in the XML file is listed here:

<?xml version=”1.0” encoding=”UTF-8”?>

<!DOCTYPE preferences SYSTEM “http://java.sun.com/dtd/preferences.dtd”> <preferences EXTERNAL_XML_VERSION=”1.0”>

<root type=”user”> <map/>

<node name=”PreferenceExample”> <map>

<entry key=”fruit” value=”apple”/> <entry key=”cost” value=”1.01”/> <entry key=”store” value=”safeway”/>

70

Key Java Language Features and Libraries

</map>

</node>

</root>

</preferences>

Summar y

This chapter introduced the new language features that Sun built into the JDK 5 release of the Java programming language. You should have all you need to know to understand and utilize these new features. You may find that a number of programming tasks you’ve accomplished in the past are now made simpler and clearer, and perhaps even some problems that never had a good solution now do.

Also covered in this chapter are several of the most important utility libraries in Java. The preferences library allows you to store and retrieve configuration information for your application. The logging library provides a sophisticated package of routines to track what your program is doing and offer output to a variety of people that need it. The regular expression library provides routines for advanced processing of textual data.

You should now be well-equipped to solve a variety of real-world problems and get the most out of the JDK 5 release of Java.

Now that you have learned about the advanced language features in Java, the next two chapters will take you inside a modern Java development shop. In Chapter 2, the habits, tools, and methodologies that make an effective Java developer will be discussed.

71

Tools and Techniques for Developing Java Solutions

Many beginning Java developers master the concepts of the Java programming language fairly well and still have a difficult time reaching the next level as a professional Java developer.

This is because most Java books simply focus on teaching just the Java language, a Java tool (like Ant or JUnit), or a language-neutral software methodology. This leaves you to learn techniques and practices from other software developers or at the proverbial “school of hard knocks.”

In Chapter 1, I discussed the advanced features of the Java language — a continuation on the theme of most beginning Java books. But now, you are starting the transition to a new kind of Java book, one more experience-centric, starting with this chapter. In this chapter, you will get a feel for the tools and techniques of modern Java development. It will introduce you to “thinking like a professional Java developer,” which continues in the next chapter — a discussion of Java design patterns.

By the end of this chapter, you should have acquired the following skills:

Familiarity with the principles of quality software development

Familiarity with the habits of an effective software developer

Awareness of a number of the prominent software development methodologies

Acquaintance with many of the tools commonly found in Java development environments

Chapter 2

Principles of Quality Software Development

So, you have figured out how to build your Java applications, and they work just like the ones from which you learned. You are getting paid to write these applications, so you are now a professional Java developer. But how do you know if you are doing a good job?

There are literally thousands upon thousands of articles debating the measures of quality software with each of them offering you their own solution for how you should answer this question. Realizing that this discussion is well beyond the scope of this book (thankfully), this body of work can be boiled down to a few questions:

Does the software do what it is supposed to do?

Of course, this is a loaded question. It is entirely possible to say that a piece of software does what it is supposed to do (as defined by a requirements specification), but this is absolutely worthless. In essence, you are talking about a failure of your requirements gathering process, which leads you to build the wrong thing. Your software is being built to serve a particular need, and if it does not satisfy that need (for whatever reason), the software is a failure.

Does the software do things it shouldn’t do?

Developers like to refer to this phenomenon as undocumented features, but your users will refer to them as bugs. Everyone prefers to build bug-free software, but in the real world, this just doesn’t happen. All men may be created equal, but all bugs are not. Bugs that do not impact the functioning of the system — or the business process that they support — are obviously far less important than those that do.

Did you deliver the software in a timely manner?

Timing is everything, and this is true nowhere more than in software in which the pace of change is incredible. If your software takes so long to deliver that it is no longer appropriate to the business process it supports, then it is worthless. The great untold secret behind the high percentage of software projects that end in failure is that many of them simply could not keep up with the pace of technological innovation — and died trying.

Could you do it again if you had to?

Of course, you will have to! This is the job — writing and delivering software that complies with the above questions. The key here is that you should not have to learn all of your hard knocks lessons every time you build software. You will invariably be asked to deliver your software again with fixes and enhancements, and you hopefully do not have to fix the same bugs over and over again nor have the same integration challenges repeatedly. “At least we don’t have to deal with this next time” should be a truth that comforts you in your integration and bug fixing and not a punch line to a development team joke.

These questions may seem like common sense — because they are! But there is an old saying that “common sense is neither,” so it is important to not assume that everyone is on the same sheet of music. Furthermore, the US Army Rangers have a saying, “Never violate any principles, and do not get wrapped up in technique.” You will find this a helpful maxim in dealing with the maze of processes, products, and techniques involved in software development. These are the core principles of software development, and how you get there is technique. Do not lose sight of the distinction between these two things.

74

Tools and Techniques for Developing Java Solutions

Habits of Effective Software Development

Motivational sayings and common sense questions do not make a strategy for making you into an effective Java developer. You need to consider the how in delivering on quality software. Along those lines, there are a set of habits that are shared among effective software developers. They are as follows:

Communicate

The picture of the egg-headed recluse software engineer sitting in the dark part of some basement while banging away on a keyboard like an eccentric secretary is an outmoded stereotype (well mostly, the dark is good). As you learned before, software is built to satisfy a need in some particular business process. In order to be successful, you need to tap in and really appreciate that need. This is very difficult to do by reading a specification. You want to talk to the users, and, if you cannot talk to the users, you want to talk to someone who was a user or speaks with users. You want to learn what it is they do, how they are successful, and how your software will help them be more successful. If the use of your software is simply by management fiat, then your software purpose is already on critical life support.

You also want to communicate with your fellow developers — explaining to them what you learned, learning from their mistakes, and coordinating how your software will work together. Make it a point to try to establish some social interaction amongst your teammates, even if it is an occasional lunch or brief chat. Software can be a hard and stressful job; it helps if you have a basic familiarity with your teammates.

Model

Before you go running out to buy the latest in fashion apparel, check the cover of this book. It is pretty clear that this book will not have you doing any posing! Modeling builds upon communication by allowing a more tangible way to visualize a given concept or idea.

Don’t assume that everyone on your team needs to attend UML training or buy thousands of dollars of UML modeling software. UML is a great package for expressing a lot of things in a common format that should be understandable by a wide variety of people — from users to developers. Of course, you know this is not the case. The key to any notation is that it must be well understood by those who read it. If your team is UML-savvy or will commit to being that way, then it is a fantastic notation — planned out by a large committee of very smart people.

Of course, the old joke is, “A camel is a horse designed by a committee.” This means that you should recognize that UML contains a toolset that extends well beyond what you may need for your project’s modeling needs. The key is to find a notation that everyone (including users) understands and sticks with it.

Also, if your tools provide more of a hindrance than an aid in your modeling, then don’t use them. Ambler suggests in his book Agile Modeling that you can draw your models on a whiteboard, take a digital camera snapshot of the whiteboard, and have exactly what you need — without the burden or cost of a tool. [AMBLER]

Be Agile

Change is an inevitable part of software development. Not only is technology consistently changing, but so is your customer’s business process, if for no other reason than the fact that you have actually provided some automation support.

75

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