Chapter 3. Hello, World!

In this chapter

  • Classes and artifacts

  • Static models and dynamic models

  • Connections among models

  • Extending the UML

Brian Kernighan and Dennis Ritchie, the authors of the C programming language, point out that “the only way to learn a new programming language is by writing programs in it.” The same is true of the UML. The only way to learn the UML is by writing models in it.

The first program many developers write when approaching a new programming language is a simple one, involving little more than printing the string “Hello, World!” This is a reasonable starting point, because mastering this trivial application provides some instant gratification. It also covers all the infrastructure needed to get something running.

This is where we begin with the UML. Modeling “Hello, World!” is about the simplest use of the UML you'll ever find. However, this application is deceptively easy because underneath it all there are some interesting mechanisms that make it work. These mechanisms can easily be modeled with the UML, providing a richer view of this simple application.

Key Abstractions

In Java, the applet for printing “Hello, World!” in a Web browser is quite simple:

import java.awt.Graphics;
class HelloWorld extends java.applet.Applet {
 public void paint (Graphics g) {
  g.drawString("Hello, World!", 10, 10);
 }
}

The first line of code:

import java.awt.Graphics;

makes the class Graphics directly available to the code that follows. The java.awt prefix specifies the Java package in which the class Graphics lives.

The second line of code:

class HelloWorld extends java.applet.Applet {

introduces a new class named HelloWorld and specifies that it is a kind of class just like Applet, which lives in the package java.applet.

The next three lines of code:

public void paint (Graphics g) {
 g.drawString("Hello, World!", 10, 10);
}

declare an operation named paint, whose implementation invokes another operation, named drawString, responsible for printing the string "Hello, World!" at the given coordinates. In the usual object-oriented fashion, drawString is an operation on a parameter named g, whose type is the class Graphics.

Modeling this application in the UML is straightforward. As Figure 3-1 shows, you can represent the class HelloWorld graphically as a rectangular icon. Its paint operation is shown here as well, with all its formal parameters elided and its implementation specified in the attached note.

Key Abstractions for HelloWorld

Figure 3-1. Key Abstractions for HelloWorld

Note

The UML is not a visual programming language, although, as the figure shows, the UML does allow—but does not require—a tight coupling to a variety of programming languages, such as Java. The UML is designed to allow models to be transformed into code and to allow code to be reengineered back into models. Some things are best written in the syntax of a textual programming language (for example, mathematical expressions), whereas other things are best visualized graphically in the UML (for example, hierarchies of classes).

This class diagram captures the basics of the “Hello, World!” application, but it leaves out a number of things. As the preceding code specifies, two other classes—Applet and Graphics—are involved in this application and each is used in a different way. The class Applet is used as the parent of HelloWorld, and the class Graphics is used in the signature and implementation of one of its operations, paint. You can represent these classes and their different relationships to the class HelloWorld in a class diagram, as shown in Figure 3-2.

Immediate Neighbors Surrounding HelloWorld

Figure 3-2. Immediate Neighbors Surrounding HelloWorld

The Applet and Graphics classes are represented graphically as rectangular icons. No operations are shown for either of them, so their icons are elided. The directed line with the hollow arrowhead from HelloWorld to Applet represents generalization, which in this case means that HelloWorld is a child of Applet. The dashed directed line from HelloWorld to Graphics represents a dependency relationship, which means that HelloWorld uses Graphics.

This is not the end of the framework upon which HelloWorld is built. If you study the Java libraries for Applet and Graphics, you will discover that both of these classes are part of a larger hierarchy. Tracing just the classes that Applet extends and implements, you can generate another class diagram, shown in Figure 3-3.

HelloWorld Inheritance Hierarchy

Figure 3-3. HelloWorld Inheritance Hierarchy

Note

This figure is a good example of a diagram generated by reverse engineering an existing system. Reverse engineering is the creation of a model from code.

This figure makes it clear that HelloWorld is just a leaf in a larger hierarchy of classes. HelloWorld is a child of Applet; Applet is a child of Panel; Panel is a child of Container; Container is a child of Component; and Component is a child of Object, which is the parent class of every class in Java. This model thus matches the Java library—each child extends some parent.

The relationship between ImageObserver and Component is a bit different, and the class diagram reflects this difference. In the Java library, ImageObserver is an interface, which, among other things, means that it has no implementation and instead requires that other classes implement it. You can show that class Component implements interface ImageObserver by the solid line from the rectangle (Component) to a provided interface circle (ImageObserver).

As these figures show, HelloWorld collaborates directly with only two classes (Applet and Graphics), and these two classes are but a small part of the larger library of predefined Java classes. To manage this large collection, Java organizes its interfaces and classes in a number of different packages. The root package in the Java environment is named, not surprisingly, java. Nested inside this package are several other packages, which contain other packages, interfaces, and classes. Object lives in the package lang, so its full path name is java.lang.Object. Similarly, Panel, Container, and Component live in awt; the class Applet lives in the package applet. The interface ImageObserver lives in the package image, which in turn lives in the package awt, so its full path name is the rather lengthy string java.awt.image.ImageObserver.

You can visualize this packaging in a class diagram, shown in Figure 3-4. As this figure shows, packages are represented in the UML as a tabbed folders. Packages may be nested, and the dashed directed lines represent dependencies among these packages. For example, HelloWorld depends on the package java.applet, and java.applet depends on the package java.awt.

HelloWorld Packaging

Figure 3-4. HelloWorld Packaging

Mechanisms

The hardest part of mastering a library as rich as Java's is learning how its parts work together. For example, how does HelloWorld's paint operation get invoked? What operations must you use if you want to change the behavior of this applet, such as making it print the string in a different color? To answer these and other questions, you must have a conceptual model of the way these classes work together dynamically.

Studying the Java library reveals that HelloWorld's paint operation is inherited from Component. This still begs the question of how this operation is invoked. The answer is that paint is called as part of running the thread that encloses the applet, as Figure 3-5 illustrates.

Painting Mechanism

Figure 3-5. Painting Mechanism

This figure shows the collaboration of several objects, including one instance of the class HelloWorld. The other objects are a part of the Java environment, so, for the most part, they live in the background of the applets you create. This shows a collaboration among objects that can be applied many times. Each column shows a role in the collaboration, that is, a part that can be played by a different object in each execution. In the UML, roles are represented just like classes, except they have both role names and types. The middle two roles in this diagram are anonymous, because their types are enough to identify them within the collaboration (but the colon and the absence of an underline mark them as roles). The initial Thread is called root, and the HelloWorld role has the name target known by the ComponentPeer role.

You can model the ordering of events using a sequence diagram, as in Figure 3-5. Here, the sequence begins by running the Thread object, which in turn calls the Toolkit's run operation. The Toolkit object then calls one of its own operations (callbackLoop), which then calls the ComponentPeer's handleExpose operation. The ComponentPeer object then calls its target's paint operation. The ComponentPeer object assumes that its target is a Component, but in this case the target is actually a child of Component (namely, HelloWorld), so HelloWorld's paint operation is dispatched polymorphically.

Artifacts

“Hello, World!” is implemented as an applet, so it never stands alone but instead is typically a part of some Web page. The applet starts when its enclosing page is opened, triggered by some browser mechanism that runs the applet's Thread object. However, it's not the HelloWorld class that's directly a part of the Web page. Rather, it's a binary form of the class, created by a Java compiler that transforms the source code representing that class into an artifact that can be executed. This suggests a very different perspective of the system. Whereas all the earlier diagrams represented a logical view of the applet, what's going on here is a view of the applet's physical artifacts.

You can model this physical view using an artifact diagram, as in Figure 3-6.

HelloWorld Artifacts

Figure 3-6. HelloWorld Artifacts

The logical class HelloWorld is shown at the top as a class rectangle. Each of the other icons in this figure represents a UML artifact in the implementation view of the system. An artifact is a physical representation, such as a file. The artifact called hello.java represents the source code for the logical class HelloWorld, so it is a file that may be manipulated by development environments and configuration management tools. This source code can be transformed into the binary applet hello.class by a Java compiler, making it suitable for execution by a computer's Java virtual machine. Both the source code and the binary applet manifest—physically implement—the logical class. This is shown by the dashed arrows with the keyword «manifest».

The icon for an artifact is a rectangle with the keyword «artifact» above the name. The binary applet HelloWorld.class is a variation of this basic symbol, with its lines made thicker, indicating that it is an executable artifact (just like an active class). The icon for the hello.java artifact has been replaced with a user-defined icon, representing a text file. The icon for the Web page hello.html has been similarly tailored by extending the UML's notation. As the figure indicates, this Web page has another artifact, hello.jpg, which is represented by a user-defined artifact icon, in this case providing a thumbnail sketch of the graphics image. Because these latter three artifacts use user-defined graphical symbols, their names are placed outside the icon. The dependencies among the artifacts are shown by dashed arrows.

Note

The relationships among the class (HelloWorld), its source code (hello.java), and its object code (HelloWorld.class) are rarely modeled explicitly, although it is sometimes useful to do so to visualize the physical configuration of a system. On the other hand, it is common to visualize the organization of a Web-based system such as this by using artifact diagrams to model its pages and other executable artifacts.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset