Design Patterns - Core Java

When solving a problem, you don’t usually figure out a solution from first principles.

Instead, you are likely to be guided by past experience, or you may ask other experts for advice on what has worked for them. Design patterns are a method for presenting this expertise in a structured way.

In recent years, software engineers have begun to assemble catalogs of such patterns. The pioneers in this area were inspired by the architectural design patterns of the architect Christopher Alexander. In his book, The Timeless Way of Building (Oxford University Press, 1979), Alexander gives a catalog of patterns for designing public and private living spaces.

A window place

A window place

Each pattern in Alexander’s catalog, as well as those in the catalogs of software patterns, follows a particular format. The pattern first describes a context, a situation that gives rise to a design problem. Then, the problem is explained, usually as a set of conflicting forces. Finally, the solution shows a configuration that balances these forces. In the “window place” pattern, the context is a room in which you spend any length of time during the day. The conflicting forces are that you want to sit down and be comfortable and that you are drawn to the light. The solution is to make a “window place.” In the “model -view -controller” pattern, which we will describe in the next section, the context is a user interface system that presents information and receives user input. There are several forces. There may be multiple visual representations of the same data that need to be updated together. The visual representation may change, for example, to accommodate various look-and-feel standards. The interaction mechanisms may change, for example, to support voice commands. The solution is to distribute responsibilities into three separate interacting components: the model, view, and controller.

The model-view-controller pattern is not the only pattern used in the design of AWT and Swing. Here are several additonal examples:

  • Containers and components are examples of the “composite” pattern.
  • The scroll pane is a “decorator.”
  • Layout managers follow the “strategy” pattern.

One important aspect of design patterns is that they become part of the culture. Programmers all over the world know what you mean when you talk about the modelview- controller pattern or the “decorator” pattern. Thus, patterns become an efficient way of talking about design problems.

You will find a formal description of numerous useful software patterns in the seminal book of the pattern movement, Design Patterns—Elements of Reusable Object-Oriented Software, by Erich Gamma et al. (Addison-Wesley, 1995). We also highly recommend the excellent book A System of Patterns by Frank Buschmann et al. (John Wiley & Sons, 1996), which we find less seminal and more approachable.

The Model-View-Controller Pattern

Let’s step back for a minute and think about the pieces that make up a user interface component such as a button, a checkbox, a text field, or a sophisticated tree control.
Every component has three characteristics:

  • Its content, such as the state of a button (pushed in or not), or the text in a text field
  • Its visual appearance (color, size, and so on)
  • Its behavior (reaction to events)

Even a seemingly simple component such as a button exhibits some moderately complex interaction among these characteristics. Obviously, the visual appearance of a button depends on the look and feel. A Metal button looks different from a Windows button or a Motif button. In addition, the appearance depends on the button state:

When a button is pushed in, it needs to be redrawn to look different. The state depends on the events that the button receives. When the user depresses the mouse inside the button, the button is pushed in.

Of course, when you use a button in your programs, you simply consider it as a button, and you don’t think too much about the inner workings and characteristics. That, after all, is the job of the programmer who implemented the button. However, those programmers who implement buttons are motivated to think a little harder about them.

After all, they have to implement buttons, and all other user interface components, so that they work well no matter what look and feel is installed.

To do this, the Swing designers turned to a well-known design pattern: the model-viewcontroller pattern. This pattern, like many other design patterns, goes back to one of the principles of object -oriented design that we mentioned earlier: Don’t make one object responsible for too much. Don’t have a single button class do everything.

Instead, have the look and feel of the component associated with one object and store the content in another object. The model-view-controller (MVC) design pattern teaches how to accomplish this. Implement three separate classes:

  • The model, which stores the content
  • The view, which displays the content
  • The controller, which handles user input

The pattern specifies precisely how these three objects interact. The model stores the content and has no user interface. For a button, the content is pretty trivial—just a small set of flags that tells whether the button is currently pushed in or out, whether it is active or inactive, and so on. For a text field, the content is a bit more interesting. It is a string object that holds the current text. This is not the same as the view of the content—if the content is larger than the text field, the user sees only a portion of the text displayed.

Model and view of a text field

Model and view of a text field

The model must implement methods to change the content and to discover what the content is. For example, a text model has methods to add or remove characters in the current text and to return the current text as a string. Again, keep in mind that the model is completely nonvisual. It is the job of a view to draw the data that is stored in the model.

One of the advantages of the model-view-controller pattern is that a model can have multiple views, each showing a different part or aspect of the full content. For example, an HTML editor can offer two simultaneous views of the same content: a WYSIWYG view and a “raw tag” view (see Figure below). When the model is updated through the controller of one of the views, it tells both attached views about the change. When the views are notified, they refresh themselves automatically. Of course, for a simple user interface component such as a button, you won’t have multiple views of the same model.

Two separate views of the same model

Two separate views of the same model

The controller handles the user-input events such as mouse clicks and keystrokes. It then decides whether to translate these events into changes in the model or the view. For example, if the user presses a character key in a text box, the controller calls the “insert character” command of the model. The model then tells the view to update itself. The view never knows why the text changed. But if the user presses a cursor key, then the controller may tell the view to scroll. Scrolling the view has no effect on the underlying text, so the model never knows that this event happened.

the interactions among model, view, and controller objects. As a programmer using Swing components, you generally don’t need to think about the model-view-controller architecture. Each user interface component has a wrapper class (such as JButton or JTextField) that stores the model and the view. When you want to inquire about the content (for example, the text in a text field), the wrapper class asks the model and returns the answer to you. When you want to change the view (for example, move the caret position in a text field), the wrapper class forwards that request to the view. However, occasionally the wrapper class doesn’t work hard enough on forwarding commands.

Then, you have to ask it to retrieve the model and work directly with the model. (You don’t have to work directly with the view—that is the job of the look -and -feel code.)

Interactions among model, view, and controller objects

Interactions among model, view, and controller objects

Besides being “the right thing to do,” the model-view-controller pattern was attractive for the Swing designers because it allowed them to implement pluggable look and feel.

The model of a button or text field is independent of the look and feel. But of course the visual representation is completely dependent on the user interface design of a particular look and feel. The controller can vary as well. For example, in a voice-controlled device, the controller must cope with an entirely different set of events than in a standard computer with a keyboard and a mouse. By separating out the underlying model from the user interface, the Swing designers can reuse the code for the models and can even switch the look and feel in a running program.

Of course, patterns are only intended as guidance, not as religion. No pattern is applicable in all situations. For example, you may find it difficult to follow the “window places” pattern to rearrange your cubicle. Similarly, the Swing designers found that the harsh reality of pluggable look -and -feel implementation does not always allow for a neat realization of the model-view-controller pattern. Models are easy to separate, and each user interface component has a model class. But the responsibilities of the view and controller are not always clearly separated and are distributed over a number of different classes. Of course, as a user of these classes, you won’t be concerned about this. In fact, as we pointed out before, you often won’t have to worry about the models either— you can just use the component wrapper classes..

A Model-View-Controller Analysis of Swing Buttons

You already learned how to use buttons in the previous chapter, without having to worry about the controller, model, or view for them. Still, buttons are about the simplest user interface elements, so they are a good place to become comfortable with the modelview- controller pattern. You will encounter similar kinds of classes and interfaces for the more sophisticated Swing components.

For most components, the model class implements an interface whose name ends in Model; thus the interface called ButtonModel. Classes implementing that interface can define the state of the various kinds of buttons. Actually, buttons aren’t all that complicated, and the Swing library contains a single class, called DefaultButtonModel, that implements this interface.

You can get a sense of what sort of data are maintained by a button model by looking at the properties of the Button Model interface.

Properties of the ButtonModel Interface

Properties of the ButtonModel Interface

Each JButton object stores a button model object, which you can retrieve.

In practice, you won’t care—the minutiae of the button state are only of interest to the view that draws it. And the important information—such as whether a button is enabled —is available from the JButton class. (The JButton then asks its model, of course, to retrieve that information.)

Have another look at the ButtonModel interface to see what isn’t there. The model does not store the button label or icon. There is no way to find out what’s on the face of a button just by looking at its model. (Actually, as you will see in “Radio Buttons” on page 388, purity of design is the source of some grief for the programmer.)

It is also worth noting that the same model (namely, Default Button Model) is used for push buttons, radio buttons, checkboxes, and even menu items. Of course, each of these button types has different views and controllers. When using the Metal look and feel, the JButton uses a class called Basic Button UI for the view and a class called ButtonUIListener as controller. In general, each Swing component has an associated view object that ends in UI. But not all Swing components have dedicated controller objects.

So, having read this short introduction to what is going on under the hood in a JButton, you may be wondering: Just what is a JButton really? It is simply a wrapper class inheriting from JComponent that holds the Default Button Model object, some view data (such as the button label and icons), and a Basic ButtonUI object that is responsible for the button view.

All rights reserved © 2020 Wisdom IT Services India Pvt. Ltd Protection Status

Core Java Topics