he Web has changed software development forever, and it doesn’t take a prophet to know that this trend will continue. Even now, client/server and object-oriented programmers are tripping over basic differences between the old computing paradigm and the new Web paradigm.
As more and more sophisticated applications move online, the Web is no longer just a place for simple, static Web sites. As such, it’s time for software developers who haven’t yet mastered Web development to take a serious look at the most common stumbling blocks.
Clashing with Client/Server
The software industry has always been fond of pitting one development technique against another. Nowadays, one interesting debate is between supporters of client/server development and Web development.
Web proponents sometimes claim client/server is dead; client/server users see glaring weaknesses in the Web paradigm. The answer to this debate lies somewhere between the two extremes. The Web paradigm is useful for certain types of applications, but its inherent shortcomings and difficulties will cause many client/server applications that migrated to the Web to return to the client/server paradigm or to move to a hybrid that draws upon both.
When the industry first began to look at dynamic Web development, they saw the HTML output and assumed Web development was limited to providing changing text to viewers. Before long, however, developers realized the full potential of the technology; they could write applications that interacted with databases at the back end, and use a Web browser as a standard GUI at the front end. The age-old problem of teaching people to use a GUI would disappear because any computer owner?and, therefore, any potential software purchaser?knows how to use a Web browser.
It appeared at this point that client/server was in trouble. After all, every client/server application has a learning curve, and often a very steep one, because people must learn to use a proprietary client before they can put the application to full use. When companies realized they could deliver applications with a standard GUI that everyone already knew how to use, they flocked to the Web. Web-based applications offer additional benefits: they give developers the ability to update software in one place?the server?and rather than mail out updates, they streamline maintenance, and they increase the portability of applications. However, Web development isn’t a “silver bullet” solution, and client/server still has a valuable place in software development.
When Objects Won’t Do
Like general client/server applications, object-oriented languages are here to stay. But they’ll share time and vie for attention with Web-based applications. It is only natural that developers will look at these two approaches and examine how?or if?they can be used in concert.
A closer examination of these approaches reveals that there are some fundamental conflicts between object-oriented programming and Web development?conflicts that can be solved, ironically, by looking backwards to pre-OOP programming techniques such as those used in FORTRAN.
At my company, Parasoft, we set out to build a dynamic, consumer-oriented Web site, and we quickly experienced many of these drawbacks of the Web approach first-hand. The following are some of the main lessons we learned.1. Carrying State Is Critical
The chief problem with Web applications?and the one issue that consistently troubles new Web developers?is that they are stateless. Dynamic Web sites do not carry state from page to page; each instance of each page is displayed independently of what happened in the past. In other words, there is no way to tell how one page carries to the next. Because there is no way to “trigger” a dynamic page by itself, developers can only be sure they are viewing or testing the right page by ensuring their state variables are properly configured for each page. Unfortunately, configuring state variables for Web pages is a tedious and time-consuming task.
I discovered this first hand while building a dynamic Web site. Our developers struggled to connect the pages into a consistent application but failed because they neglected to consider that each page had its own state. It didn’t take long to see that the developers were chasing their tails trying to figure out how to connect the pages.
The code itself was complicated and convoluted?full of state variables for which nobody knew the values.
Then came the biggest clue to the nature of the problem. When the developers ran the code for the back-end applications, they encountered bugs that arose from going through multiple paths and ending up on the same page from different directions. Because they couldn’t control the state variables, the developers were invariably ending up with the wrong versions of pages, making it impossible to debug the application. The only available solution was to re-write the code for the entire project.
Object-oriented developers, too, must make earnest efforts to understand how state is recorded as they shift to Web development. Each interaction with a Web page has to be handled independently, without regard for what events occurred in the past. Even dynamic pages cannot keep track of state; each time you travel from one page to the next, you can only carry the state by using state variables. In other words, you have written code for the page itself, but part of the information for the page is stored outside the page in the state variables.
In principle, storing information in state variables breaks the object-oriented paradigm. A fundamental principle of object-oriented programming is that all necessary information is encapsulated inside the objects. Objects have to carry state information throughout the application, and as the information is modified, the object is “morphed” accordingly. But in Web development, objects don’t carry from one page to the next. A page is created and represented by objects, but then the objects die as the page disappears. The most important information from the objects can be stored in state variables and re-created. However, every time an object is re-created, it is inevitably a new, slightly different instance. This re-creation violates the fundamental object-oriented concept of flow throughout the application. So while the Web paradigm can seem object-oriented on a small scale, the object-oriented paradigm is broken on a larger scale.
Developers who are trained in object-oriented programming often enter Web development with the assumption that if they have the variables stored in their objects, they will be ready to apply to the new page. It is surprising for them to find that the variables are not, in fact, carried over. To master dynamic Web development, these developers need to switch their thinking. Ironically, they can gain a better understanding of Web development if they just think back to the old rules of FORTRAN programming. In FORTRAN, there were external variables that carried information between functions and subroutines. The functions and subroutines executed tasks on their own, out of the developer’s sight.2. Giving Up Client Control
The second major problem with Web-based applications is a significant usability problem. In a client/server application, when you write the client you control user movement through menus. By providing certain menu items on certain pages, you restrict the way users can move through the application and ensure that they will take a logical path. Client/server applications act as finite state machines, which have a limited number of states and always know what state the user is in.
On the Web, developers don’t have the benefit of knowing what state their users are in. To complicate matters, browsers typically contain a Back button and Forward button. Web users rely on these buttons as navigational shortcuts but they make it very difficult for the developer to control the user experience as part of the application.
Because of these buttons, the developer never really knows what path the user followed to end up on a particular page. By using the Back and Forward buttons, users can get out of sync without knowing it. Programmers have tried various methods to work around this obstacle, with little success.3. Updating Pages
A third problem is the issue of how to refresh dynamic Web site pages with updated information from the server. If you have small areas of the screen that are supposed to be interactive and are constantly changing, you face the challenge of providing the user with an updated display and connecting to the server. At first, developers tried to use HTML frames as a solution, but frames are not portable and are quickly falling out of common usage. The next potential solution was to use applets, small Java programs that are embedded in HTML pages and execute on the client. But applets, too, have a tragic flaw: they are slow to download.
Ideally, only the truly dynamic portion of pages would be updated with each update or change request. This would consume much less bandwidth and significantly reduce download speeds. However, technology that could perform such isolated updates must be tailored for the particular application that it runs. If you want quick front-end performance for your application, you have to write a proprietary thin client that acts as a smart browser. This customized browser would improve performance by updating only the parts of the pages that needed to interact with the back-end.
The problem with this solution is that it requires a trade-off between the performance increase enabled by the proprietary browser and the usability of the general browser: proprietary browsers can update pages much faster than general browsers, but if you use a proprietary browser, your users will need to learn how to use this specific type of browser. If the application has many repeat users, the performance benefit of the proprietary browser will likely outweigh the drawback of the initial learning curve. For example, users of online stock-trading applications would likely accept an initial learning curve in exchange for improved performance, but an application with a small percentage of repeat visitors should probably sacrifice performance for the instant usability associated with general browsers.5. Sophisticated Testing
After we built our dynamic site at Parasoft, we set out to test it. But the testing turned out to be almost as challenging as the creation. We encountered many Java exceptions that didn’t come from the code itself; they came up because of bad correlations between the code and the database. This was a new concept for us?having a well-written piece of code which caught exceptions the way it was supposed to, but which failed when it interacted with the database. We discovered that the code was failing because the database was in the wrong state when the code interacted with it. From an end-user’s standpoint it would appear that the application failed, but from the programmer’s perspective everything was correct. So we needed to move beyond merely testing that the code was well-written and seemed to work; we now needed to test how the code would talk to the database, because one failure could crash the application.
We designed a dynamic Web site development tool (WebKing) that allowed us to go through multiple cycles and arrive at, then test, the same page from different directions. We also used this tool to automate nightly builds and construction, functionality, and regression testing. Because traditional debuggers didn’t work for our situation, we relied on print statements as a primitive form of debugging. Jtest, our own Java unit testing tool, became a blessing because it helped us remove lots of “garbage” and allowed us to focus on important problems in the code.
The greatest lesson we learned from this experience is that the back-end code of any dynamic Web application must be robust enough to take care of inconsistencies in the database. The back-end literally has to fix the bad situations in which it finds itself so that the front end will continue to run flawlessly.The Death of Client/Server?
So is client/server dead? The answer is definitely “no.” Dynamic Web development has much potential, but it is also fraught with its fair share of problems. Client/server is more limited than Web development, but it can solve many of the problems inherent in the Web paradigm. We believe that the conclusion to this debate will not be the triumph of one approach over the other, but rather a movement to a hybrid of the two paradigms (such as a customized thin-client browser) that merges the two paradigms in a way that the advantages of each one compensate for the drawbacks of the other.
Dynamic Web development most certainly breaks the object-oriented paradigm, and it keeps object-oriented developers on their toes. For object-oriented developers, a key part of making the switch to dynamic Web design is keeping track of which state their Web pages are in, instead of just assuming that the current state is always valid. In object-oriented programming, we always know what the state is because nothing changes without our knowledge. But in dynamic Web development, many things change behind the scenes.
In the end, it seems that OOP is both a blessing and a curse to dynamic Web site developers. This is just one more example of the principle that we have always known: there is no single programming religion that every developer can blindly follow. No single language or concept will be applicable to all situations; as technology advances, unexpected problems will inevitably surface, and sometimes we must look backwards as well as forwards to solve these problems.