• No results found

Bitter servlets

In document Bitter Java (Page 82-86)

This chapter covers

The common Magic Servlet antipattern

A step-by-step refactoring guide for Magic Servlets

A core design pattern called the Triangle for server-side programming

54

It is springtime, and the hills are uncharacteristically green. I am mountain bik-ing near my home in Austin. I take a fairly remote trail windbik-ing through the rocky Bear Creek pass. It traverses the steep slopes beautifully, alternately sliding on and off the ridges to provide many technical climbs and screaming descents. I am winded as I arrive at a particularly technical climb on the Outback trail. I have not ridden for a long while. Most Outback climbs are not risky because it is hard to gather dangerous speed. Hills with very steep ledges are usually too diffi-cult to climb, but this one has teeth. It has enough rocks and ledges to make abruptly stepping off the bike on this steep terrain an adventure, as my shins remind me.

There are few good and many bad places to dismount, with cracks that can snap ankles or knees. Mentally rehearsing my dismount at a demanding ledge around a blind switchback that I seldom conquer, my mind wanders off the trail.

As I begin to round the tight bend at the bottom to start the climb, my body slips backward, my front wheel lifts off the ground, my weight abruptly shifts forward, and my back wheel spins out. I have lost momentum and am still depressingly close to the bottom. I step off my bike and start to walk it toward the top.

At the top of the hill, barely visible between the cracks, on a large, flat rock is a huge rattlesnake. It is not in a defensive posture, so there is no rattle and no other hint to its presence. The snake occupies the very flat rock that I would have landed on had things gone as in my rehearsed dismount. It seems that my poor condition-ing and technique today conspired to save me. I shudder, and continue to climb.

3.1 Getting off on the wrong foot

The basic gateway into most standards-compliant server-side Java applications is the ser vlet: a simple wrapper around a service, implemented in Java and reached through HTTP. This chapter lays out the most basic antipattern involving the first layer of server-side Java: the Magic Servlet. Projects bun-gling this first basic step have little hope for success. After examining the roots of this antipattern, we will lay out the design, the symptoms, and the problems of the Magic Servlet antipattern. Then, through a series of refactoring steps, we will transform this antipattern to the Triangle, a design pattern based on Model-View-Controller.

3.1.1 An early antipattern: The Magic Pushbutton

First, we should discuss an early version of an old antipattern. I encountered the Magic Pushbutton in many of my early consulting engagements. (Stewart Nickolas, a well-respected software architect, coined the phrase.) After I

Getting off on the wrong foot 55

started searching for the antipattern, I found what looked like the same wretched application at many different places and different circumstances. It didn’t matter what industry. It didn’t matter what language was used for the implementation, though Visual Basic was the most common. The problem was more common to inexperienced programmers, but hard-core program-mers were not immune. It was the simplest of antipatterns: an unstructured application consisting of a single, monolithic procedure fired by a user inter-face event. In a nutshell, this problem is a lack of decomposition. A simple example is an 11 KB application with 10 KB hanging off a pushbutton, as in figure 3.1. Many readers recognize this antipattern even before further description. This pushbutton is “magic” because it does most of the work for the application within a single function. These applications make me think of a fat plumber in tight Spandex. The proportions are comical and the results can be disastrous. The applications are obviously ugly and difficult to maintain, but the root cause or the refactored solution is not always obvious.

The Magic Pushbutton can actually be traced to the graphical tools that broke onto the programming scene in the early 1990s. The tools ushered in drag-and-drop programming. Like the ancient trading clipper ships that carried rats with new diseases hidden among the treasures they bore, these tools brought a new kind of antipattern. If you bring up an old copy of Visual Basic, it’s easy to see why. The program, and many others like it, first presents a screen that allows the development of the user interface. The programmer can rapidly prototype the user interface and then attach the necessary logic. The sublimi-nal message is clear: “Go ahead and start. You’re building a program, not a house. You don’t need a foundation. With this new tool, you will have plenty of time to design what you need down the road.” For some applications, this approach works because the back end is already defined. The back end might take the form of components built by someone else, stored procedures, or existing transactions. For these applications, the view and model are cleanly separated.

10 KB Script

OK

Figure 3.1

The Magic Pushbutton consists of a block of code hanging off a pushbutton and represents event-driven programming at its worst. It was most prevalent in the mid-1990s when Visual Basic, PowerBuilder, and similar languages were at their strongest.

56 CHAPTER 3 Bitter servlets

If the back-end logic is not well defined, then the application can easily adopt the user interface as the design. The programming scripts, in the form of basic functions, are attached to user interface events at key places. The big-gest event, like a Submit or OK pushbutton, usually attracts the most code, much like the jam side of a piece of toast attracts the floor. The Submit func-tion becomes the focal point of the applicafunc-tion and, without the appropriate organization, grows like an unmanageable blob.

3.1.2 Building with Model-View-Controller

Of course, the right way to design this type of application is by using one of the most famous and earliest design patterns: Model-View-Controller. This common design pattern has become a staple of modern programming. It is mentioned in the introductory chapters describing the utility of design pat-terns in the design pattern bible, Design Patpat-terns, by the Gang of Four. It has been refined and updated in such places as Core J2EE Patterns, by Deepak Alur, et al., and the Jakarta Struts framework. It has served as the foundation for frameworks in Java, C, C++, Smalltalk, LISP, and many others. In this chapter, we will introduce a variation called the Triangle pattern. With this pattern, the model is the business logic that drives the application. The user interfaces, called views, then present various aspects of the model. The interac-tion of the user and other input/output streams are managed with the control-ler. This design pattern is shown in figure 3.2.

3.1.3 Failing to separate model and view

Listing 3.1 is a program, written by a novice, that fails to use Model-View-Controller. This baby is admittedly too ugly for even a mother to love, but Java like this is more common than any of us would like to admit, especially in

View

Model

Controller

Figure 3.2 Model-View-Controller is a design pattern that advocates clear separation of the user interface, or view, and the business logic, or model. The controller helps to manage input and output. The advantages are widely recognized as easier maintenance, improved flexibility, and more readable code.

Getting off on the wrong foot 57

script-driven visual development environments. Listing 3.1 is an attempt at a bank account program. Float.valueOf(fieldValue.trim()).floatValue();

Float.valueOf(fieldValue.trim()).floatValue();

balance = Float.toString(balanceNumber);

This application is the logic for a simple ATM program. It takes the amount in an entry field and debits or credits the account appropriately, based on the state of a radio button. Notice that no attempt has been made to break out the business logic (the account) and the user interface. In fact, the model and view are so tightly intertwined that, in many places, both the model and view are

Listing 3.1 A bank account without Model-View-Controller

In document Bitter Java (Page 82-86)