The Software Design and Development Book
With UML Examples by Mark Watson
Version 0.08 – July 21, 2003
This work is licensed under the Creative Commons Attribution-NoDerivsNonCommercial License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nd-nc/1.0 or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. Additional license terms: • No commercial use without author's permission • The work is published "AS IS" with no implied or expressed warranty - you accept all risks for the use of both the Free Web Book and any software program examples that are bundled with the work.
Table of Contents
<< Automatically generated table of contents: >> Table of Contents............................................................................................................ 2 Preface ............................................................................................................................ 4 Book audience............................................................................................................. 5 Programming Languages............................................................................................. 5 Acknowledgements ..................................................................................................... 5 Part I – Rethinking Design and Software Development ................................................... 7 Chapter 1. What’s wrong with current design and software development methods .......... 8 Chapter 2. Economics of software development ............................................................ 11 Advantages of Open Source and Commercial Software ............................................. 11 Chapter 3. Job satisfaction: aligning corporate and personal goals................................. 13 Chapter 4. History of software design and development ................................................ 14 Structured programming............................................................................................ 14 Object oriented.......................................................................................................... 14 Design patterns.......................................................................................................... 14 Extreme programming............................................................................................... 15 Aspect oriented programming ................................................................................... 15 Chapter 5. Introduction to UML .................................................................................... 16 Use Case Diagrams ................................................................................................... 16 Class Diagrams ......................................................................................................... 17 Sequence Diagrams ................................................................................................... 18 Chapter 6. Example UML Process: Developing an Automated Help Desk System ........ 19 Iterative Design and Development............................................................................. 22 Chapter 7. Model View Controller Design Pattern......................................................... 24 << Manually written table of contents: for planning purposes only – delete later: >> Preface Part I – Rethinking Design and Software Development 1. What’s wrong with current design and software development methods 2. Economics of software development 3. Job satisfaction: aligning corporate and personal goals Part II – Fundamentals of Design 4. 5. 6. 7. 8. History of software design and development Common design pattern used in this book Introduction to UML Importance of iterative development Use case analysis
9. Designing classes 10. Object interaction diagrams 11. Design patterns – an overview. 12. Design patterns for GUI applications. 13. Design patterns for web services. Part II – Example Design Projects 14. An Automated Help Desk System 15. Socket based client server models 16. SOAP based web services 17. Separation of content and control when creating dynamic web content 18. Abstraction layers between application code and relational database access 19. Model View Controller design pattern for GUI applications 20. Model View Controller design pattern for web based applications
The complexity of information increases faster than our ability to organize and use it to increase efficiency and profit. We have lived through the dot-com hype and crash and most developers now have a more realistic view of the benefits versus costs of software systems. As the complexity of information increases so does the software required to automate information processing. In the last few decades there have been many software design methods that have all promised the reduction of software costs. Most software developers have been involved with projects that used (in historical order) the waterfall method, structured programming, object oriented programming, various object modeling languages, and perhaps the most recent Unified Modeling Language (UML). Most developers will tell you that “their mileage varied” when discussing the utility and cost effectiveness of various software development methodologies. A common complaint with methodologies that promote formal up front design is that the design process and documents are not kept up to date during software development. Modern design tools do promote “round trip” engineering to keep model design documents and code in sync but many projects still ignore the maintenance of design documents in the rush to get projects complete. One of the great success stories in software engineering has been the series of design patterns books. These books codify and describe the designs for common programming problems. Developers reuse a proven design without having had to go through the “normal” process of making mistakes and then learning from these mistakes. In this book we will look at design practices that make sense in the reality of today’s economy. This book is a hybrid, combining new ideas for a lightweight approach to using UML for design and discussing in cookbook fashion design recipes for a few problems that modern developers face. These six design problems will be discussed in the proposed book: • • • • • • Socket based client server models SOAP based web services Separation of content and control when creating applications with both dynamic web content and standard GUI user interfaces Abstraction layers between application code and relational database access Model View Controller design pattern for GUI applications Model View Controller design pattern for web based applications
The goal of this book is to encourage the reader to step back and reevaluate how they design and write software systems. The great computer scientist Edsger Dijkstra, who died recently, once said “Computer science is as much about computers as astronomy is
about telescopes.” That is not simply a glib remark! Talk to successful software designers and developers and they will probably tell you that they do their best work in design and problem solving away from their computer, often taking a walk with colleagues or sitting outside with a pad of paper. So, the reader is expected to think about the entire software design and implementation process in the first part of the proposed book and reevaluate how they do their work. The second part of the book contains case studies for six design problems.
The computer industry in the U.S. and in other countries has seen a reduction of jobs and in the start of new projects in the last few years. No one can predict the future economy (well, economists do try) but there is one certain thing: computer scientists must continually educate themselves as new technologies capture the interest of the industry and the business world. I want to help you, the reader, not by concentrating on the details of the newest technologies but by reevaluating how you work and the meaning and means to productivity gains. This book is for software developers who worry about the economy and their careers and want to proactively do something about their fears by improving the way they design and write software.
The only assumption that I make regarding the reader’s preferred programming language is that it is object oriented. That said the examples in this book are written in Java. Using UML is a key part of this book. For Java, I recommend the Poseidon UML editor. A free community edition is available, with professional editions also available with added features. You can download Poseidon at www.gentleware.com. In addition to using a specific UML tool, I also like to use OmniGraffle running under Mac OS X to create UML diagrams. I believe that selecting a programming language for a project is important, but less important than proper design. I use a wide range of programming languages (in order of decreasing use): Java, Common Lisp, Python, Smalltalk, C++, C#, PHP, and Perl. For me, the selection of a programming language is driven by cost considerations: which language allows me to design and implement a system that will be maintainable, for the lowest cost. We will see later in the book that choosing the right infrastructure tools is a similar and related process to programming language selection.
I would like to thank the following readers who have provided ideas for design in this book: <none so far>. I would also like to thank the following people who pointed out typographical errors in the manuscript: <none so far>.
Part I – Rethinking Design and Software Development
Chapter 1. What’s wrong with current design and software development methods
This chapter expresses my personal opinions based on my experiences writing software in a variety of organizations with a wide variety of team sizes and organizations. I am writing this book in the fall of 2002, a year or two after the “dot-com bust”. In my personal experience the “dot com” era helps to demarcate three eras of software development: 1. The pre-dot-com era was characterized by moderate spending for software development and a real interest in doing software development “right” using the software development methodology that was in current vogue. 2. The dot-com period era was characterized by large and enthusiastic spending for software development and less emphasis on proper software development. I witnessed more of a frenzy to get products to market while that market was hot. 3. The post-dot-com era is characterized by conservative spending for software development and uncertainty in the future of IT spending. Sadly, I would argue that we have made negative progress! We need to get back to the values we used before the dot-com era while realizing that IT expenditures in today’s economy must be made efficiently. I have been programming since high school (for me, that is the mid 1960’s) and professionally programming since 1973. Roughly, my experience working on medium and large software projects falls in three categories: 1. Under designed – either because of a rush to get something working or general short sightedness, little time was spent on design, a quick hack got something working, and everyone was happy except for the people who had to maintain the system. 2. Good balance between design time and implementation time – the “just right combination”! 3. Over design – attempt to write the “perfect” design, not realizing that a good design methodology depends on staged prototypes that affect the design process. As you might guess, I prefer category 2. It is difficult to know how to plan software development. If, for example, you need to convert a structured text data source into a form that can be imported into a relational database, then it is not likely that the code to do this conversion will be reused. If we know that the results of a small project will not be reused (i.e., a “one-shot” project), there are obvious economies that we can make use of. For example: 1. Do not bother documenting the software.
2. Do not bother commenting the software for the benefit of future programmers who must maintain it. 3. Worry about code correctness, not efficiency (i.e., memory footprint, runtime efficiency). This book is really not about “one-shot” coding projects, but we need to define the margins of our discussion of planning software development and using the correct design process. At the other end of the spectrum of software development, we might consider systems for which software failure would endanger lives (e.g., embedded medical equipment, aircraft control software, etc.) This book is also not about designing and implementing this class of software. This book tries to take a Buddhist “middle of the road” approach: we want to develop software development planning and design habits for small, medium and large size projects that will be reused and must be efficiently maintained. So what is wrong with current design and software development methodologies? I think that to some extent, fault lies with industry leaders like Sun and Microsoft. Sun’s Java platform certainly has a lot going for it, especially developer loyalty. However, instead of placing resources to solve problems like too large of a memory footprint, runtime efficiency, and poor looking GUI applications, Sun seems too caught up in developing and releasing too many new APIs. One of the best additions to the Java platform has been the Hotspot just-in-time compiler, but that technology was purchased from a Smalltalk vendor (yes, it had been originally developed for a different platform!). Java is an incredible platform for developing server side or web based applications. Still, many in the developer community are disappointed by the overall design and complexity of Enterprise Java Beans (EJBs). Microsoft, of course, is not without their problems. Most of these problems are tied to legacy support for COM, so-called “DLL hell” (i.e., earlier versions of Windows that allowed developers to add DLLs to the system instead of “green installs” where all DLLs coexisted with specific applications. As a programmer, I have always disliked automatically generated code that is unreadable to most human beings. I do not like so called “wizards” that generate unreadable code. I spent a fair amount of time with VisualStudio.net before I started writing my last published book (which covered Java J2EE technologies). I wanted to “scope out the competition”. Microsoft’s .Net does have a lot going for it. It makes generating web applications easy and provides a uniform way to make both GUI and web based user interfaces for applications. Time will tell how .Net does in the market place and how it is viewed on technical merits.
Both Sun and Microsoft are corporations that have a legal obligation to their shareholders to make every attempt to be profitable. It is regrettable, but understandable that public companies need to worry more about the “bottom line” than uniformly creating software tools to support lean/mean/economical software development. Still, for many of the types of problems that we need to design and code for can be effectively solved with inexpensive or free software tools that certainly meet my lean/mean/economical criteria. For example: • • • • Java on the server, using JSP, JavaBeans, and JDBC database connections. Microsoft .Net for both Windows forms and web forms applications. Python for writing utility scripts and server side web programming. Smalltalk for server side Smalltalk servlet programming and general application development.
These four “platforms” are inexpensive or free but do have a cost for training: the Java, .Net, and Smalltalk class libraries all have a long learning curve. Knowing the syntax and general use patterns for an object oriented language is of limited use if you have not also mastered the standard class libraries for that language. So, in this book, we will look at my own approach to solving current software development problems. My approach involves using simple tools that are well understood by you the developer, and use “just the right mix” of up front design followed by staged implementations that positively affect the design process. When we build our software projects, we should strive to write code that works, is easily maintained, and is economical to develop and maintain.
Chapter 2. Economics of software development
Writing software costs money. Even Open Source projects have a cost to participants who either give up some of their free time to work on a project that interests them or for companies who pay their staff to work on Open Source projects in order to gain some competitive advantage by also utilizing the work of other people outside their organization. It is usually interesting to examine different ideas that are in vogue for reducing software costs. In the 1980s, managers at my company (SAIC) seemed preoccupied with Commercial Off The Shelf (COTS) software. This was a response to customers questioning why, for example, they spent a great deal of money paying for custom mapping software instead of buying a commercial package that could be licensed for $20K. In the 1990s, the new mantra was “software reuse”. Software reuse is a good idea of course, but I would argue that best practice procedures do not call for up front design for software reuse, especially when designing and implementing class libraries for a new project. Really, the problem with up front design for reuse is similar to the problem of over design without iterative staged prototypes: we really need some implementation experience to drive the requirements and design process. It is almost always better to simply pay the price of re-implementing a class library that has proven its usefulness after experience using it.
Advantages of Open Source and Commercial Software
There is absolutely no question, in my opinion, that organizations can save money by effectively using Open Source software. Strategically, the question for us to ask is how we mix Open Source, COTS software, and custom development. Best practice calls for (usually) using Open Source for infrastructure code. Here are a few common examples: 1. Static and dynamic web content – using the Apache web service software, adding a few custom CGI programs for database access, etc. 2. Static and dynamic web content for Java developers – using Apache Jakarta Tomcat with standard JDBC database connectivity tools, adding custom JSPs, JavaBeans. 3. Small scale enterprise web applications for Java developers – using Tomcat and JBoss, adding custom JSPs, EJBs. 4. A new Apple Mac operating system – uses BSD Unix for core functionality, adding Apple’s GUI magic (I am a Mac OS X user, and definitely a little biased). It is easy to see the common thread here: use free Open Source software for infrastructure, adding value added code where required. It often makes good sense to buy commercial software and tools. For example, if you live in the “Microsoft Windows world”, it is hard to beat the .Net framework for easily
writing web services. Some commercial applications, like Microsoft Office, are often used effectively as components in custom, vertical application development (i.e., applications targeted to narrow vertical markets). In all cases, it makes sense to devote some small fraction of a development budget on research of available tools (both Open Source and commercial). Best practices for tool selection use the following criteria: • • • • Cost – both purchase price and training Licensing issues when redistribution is required Maturity of tools (e.g., are they “industrial strength” or research prototypes) Prior team experience with tools
Chapter 3. Job satisfaction: aligning corporate and personal goals
At least in the U.S., most workers’ expectations of long-term employment at a single company have changed. To be sure, many companies still see the high value of long-term employees but with the increased cost of benefits the use of temporary employees and consultants is more common than it used to be. As with many “white collar” jobs (e.g., architectural design, evaluation of patient x-rays, staffing help desks, tax preparation, etc.), there has been major movement in outsourcing software development work to countries with lower costs of living (and therefore lower salaries). This chapter is a brief discussion based on both my experiences and those who I have talked to on the subject of what computer professionals want and expect in today’s economic situation. To summarize, professional programmers and engineers want the following from their employers (different people have different priorities, to be sure): • • • • • • Good salary Job stability Interesting work Work in technologies with a future Work environment Work location (e.g., large city vs. rural living)
Different people have additional desires for their career. It is important to understand our own priorities and to try to live our personal and professional lives in a way that meets our own priorities. While it is important for workers to share their priorities with their bosses at work, this sharing of information does little good if it is not acknowledged and acted on. A good first step in planning for success in meeting professional goals is to write down your priorities and discuss them with family members and friends. We are all responsible for our own decisions in life but that does not mean that we should not seek advice and alternative ideas. There has definitely been a change in the information technology (IT) industry since the dot-com bust. I argue that one very positive aspect of this bust has been that many people who looked at software development as “just a job” have left the field. Like any career, it is important for IT workers to have a real passion for their work. (Exercise: do a web search on “Joseph Campbell follow bliss” and read his philosophy on choosing a career.)
Chapter 4. History of software design and development
The history of software development methodologies is really a search for a “silver bullet”, that is, a search for some way to manage the complexity of software systems. My personal take: developing complex software systems is, well, complex and therefore time consuming and expensive. We will look at five popular methodologies in the rough order that they were developed and used.
I was programming professionally (started in 1973) for a few years before the ideas of structured programming started to gel and catch on. Structured programming deals with the correct use of block structure, procedure call statements, and various loop constructs. We had a new mantra: “go-to considered harmful”. The idea that programs should be well structured with transparent, easily understood flow of control seems like an obvious idea today. I would argue that the ideas from structured programming are integrated into all later methodologies.
Object Oriented Programming (OOP) methodology certainly grew out of structured programming ideas. OOP manages software complexity by packaging code and the data that code uses together. We are used to dealing with physical objects in the real world. In OOP, we sometimes model real world objects (e.g., writing simulation programs, where OOP concepts were first developed) as software objects and also model non-material things like processes, ways to organize information, etc. as software objects. A software object maintains its own internal state. This is very different from structured programs where the code may have been laid out in a structured and easily understood way, but global shared data was available to all parts of a software system – including those parts with no real need to access or to modify the data.
Intelligent people notice patterns in their worlds. As children, we might have noticed that classmates who exhibited patterns of good study habits earned better grades. When we learned to cook, we might have noticed that experienced cooks had work patterns like preparing ingredients before starting to cook, frequently tasted food as they added spices, etc. In software development, the use of design patterns is based on observations that some software projects fail while similar projects are successful (these could be management
patterns, scheduling patterns, testing patterns, etc.). In software design, the use of patterns is based on further observations that common design patterns for specific tasks are used repetitively for successful projects.
Extreme programming is based on identifying the needs of customers and concentrating on developing and delivering what customers need quickly. Using simple designs to communicate with customers, Extreme developers iteratively develop software prioritized on what is needed the most. Extreme programming is the opposite approach to the traditional scenario where developer and customer spend lots of time up front trying (usually with limited success) to document in detail what software is to be developed over a long period of time. Experienced developers understand that staged implementations positively affect the design process. Extreme programming is especially effective when requirements are complex and not well agreed upon. When we study UML in this book, we will look in some detail at user cases that detail individual aspects of how people will use a software system. Extreme programming uses something similar called “user stories” that are provided by the customer to describe their perception of how the system will be used. The user stories are then used to define both estimate development time and to help define automated tests that will be used for both development and for acceptance testing. Extreme programming is often described by a phrase that makes a lot of sense to me: test driven programming. Write the test code before writing the application code! Then write just enough software to pass the unit tests. Do not allow software updates to a source code repository until all unit tests pass. Use tools like JUnit (www.junit.org) to write automated tests.
Aspect oriented programming
The main idea behind aspect-oriented programming (AOP) is the separation of concerns of different parts of a software system. In principle, this philosophy allows for the development of systems that are more modular, with the modularity being driven by different concerns of developers. For Java programmers, I recommend looking at the AspectJ project (eclipse.org/aspectj). To quote the AspectJ web site: “AspectJ enables the clean modularization of crosscutting concerns such as:
error checking and handling, synchronization, context-sensitive behavior, performance optimizations, monitoring and logging, debugging support, multi-object protocols”
Both the free Eclipse Java IDE (www.eclipse.org) and the commercial IntelliJ Java IDE (www.intellij.com) support AspectJ. Aspectj is an extension of the Java language and requires preprocessing. Note: even though I have been following AOP for a while, I have not yet used it for a real project.
Chapter 5. Introduction to UML
In this chapter we will briefly cover the basic ideas of UML and object modeling. In the next chapter, we will look at the UML models for a simple commercial product that I wrote (a help desk system). It would be best to read this and the next chapter in one sitting because we will not see actual diagrams in this chapter – you have to wait for Chapter 6. I got my introduction to Object Oriented Modeling (OOM) by using Grady Booch’s methodology. I was writing a series of C++ books for McGraw-Hill at the time, and Grady sent me a (hand marked up) copy of his manuscript for a book on OOM. At the time, there were over ten different methodologies – a literal “Tower of Babel” situation in design notations. UML borrowed ideas from the Booch notation, Rumbaugh notation, and Jacobson’s notation. UML is now widely accepted as the standard notation for performing OOM activities. Most books on UML (e.g., the book Paul Harmon and I wrote, “Understanding UML”) go into some great detail on all UML diagram types. My approach here is a little different: in my own work, I find myself usually only using three types of diagrams and we will only discuss these three types of diagrams here: • • • Use Case – describes how users of a system interact with it Class – documents the public and (optionally) private APIs for a class Sequence – shows how objects of different classes interact as a function of time
A word of warning: be aware that we are just looking at the most commonly used aspects of UML in the web book; if you will be using UML with other team members, they are likely to want to use additional types of diagrams. That said, this chapter exposes you to the basics and provide a good starting point.
Use Case Diagrams
Even programmers who do not like to perform a lot of up front design work will find use case diagrams a very effective method to both understand customer requirements and as a type of contract between you and your customers. Like all aspects of good design, use case diagrams not only will help you to reduce the costs of writing all but the most trivial
programs, they will also serve as insurance that you are developing what your customers really want. In the next chapter, we will see an example use case diagram (Figure 6.1). As a developer, you will base the use cases that you write on conversations with your customer. A set of use cases can be refined until both you and your customer agree on the way that a system will be used and, in keeping with the philosophy of Extreme Programming, can be used to define test cases early in the development cycle. A good alternative to using UML modeling tool to create use case diagrams is to use 3x5 cards. Write a (very) brief description of each use case on a separate 3x5 card. In either case, the idea is to develop a set of independent example uses of the system under development.
Class diagrams are used to show both the APIs for a class and internal data and also to show the relationships between classes. I find class diagrams to be most useful when used to get a top-level overview of the major classes in a system and how they inter relate. For a complex system implemented with hundreds of classes, I do not think that it makes sense to produce class diagrams for all classes. Most UML modeling tools (e.g., Poseidon) offer “round trip” capabilities: if you already have source code, then they can import the source code and automatically produce diagrams. If you modify a diagram in the modeling tool, for example: adding a few methods and extra class data, then the modeling tool can automatically update your source code. If I need to quickly produce high-level UML class diagrams for a new project, I find it fastest to use a text editor to write skeleton code (i.e., just method signatures and data definitions) for the top level classes and import this source code into my UML modeling tool. I use the tool to clean up the layout of the diagrams, and tweak the initial class design before allowing the modeling tool to update the original source code. While I find modeling the high level classes for a new project useful, I also have a word of warning: design is far from a perfect science. You will be modifying your design as you get experience implementing the system. For this reason, I prefer for my own work to cycle between design and implementation work. Too much up front design time can be wasted if during early implementation you discover errors in requirements analysis (which I consider part of design, not a separate step) or design that requires large modifications. I consider best practices to be a cyclical development style. Figure 6.2 in the next chapter I an example of a top-level class diagram for an automated help desk system.
Sequence diagrams are a great way to understand and to explain to other people how the objects in a system inter relate as a function of time. The utility of sequence diagrams is incredible for at least three reasons: 1. Allows developers to really understand the time-sequenced interaction between system objects. 2. Allows technically oriented customers to get a better understanding of how the system will function. 3. Allows developers to identify “failure points” and facilitates setting up test cases. I personally consider UML sequence diagrams as the “big win” for UML that does the most to justify the time required for UML modeling. We will see an example sequence diagram in Figure 6-3.
Chapter 6. Example UML Process: Developing an Automated Help Desk System
For the first example design, we will look at a recent project that I designed and implemented: an automated help desk system. This is a good example both because it is realistic (it is a real product that my company sells and uses at www.markwatson.com) and because it is a good example of a web based application. This system is implemented as a Java servlet. Regardless of whether you are designing and implementing a commercial product or an Open Source project, or an in house project, or a project for a customer I recommend starting with this process: 1. Describe briefly how people will use the new system (one or two paragraphs) 2. Create one or more UML use case diagrams showing how the end user interacts with the system (note: if the new system is, for example, a back end server application, then the use case diagram could show how other system components interact with the new system) 3. Talk with users of the new system, customers, etc. to make sure that they agree with the preliminary use description and use case diagram(s). Here is a two-paragraph concept summary for the new product: The automated help desk servlet initializes by reading an XML document that contains product information. This XML document format is easily edited to add new products and product FAQ information. The user’s of the help desk access it by using a URL. There are three primary ways to use the help desk: view the complete table of contents for all product information, use key word search to find FAQs for a specific product, and to use natural language queries to search for information for a specific product. Figure 6.1 shows three end-user use cases for the help desk system.
key word search user 1 HelpDesk System natural language query
XML initialization data file
use table of contents menu system user 2
Figure 6.1 UML Use Case Diagram for the Automated Help Desk System Whenever I design and implement any system that contains a user interface, the first thing that I like to do is to cut the system in two: an engine and a presentation manager. Here, I will start by designing, then implementing, an engine that has a public interface for: • • • • • • Initialization from the XML product configuration file Generate an “HTML menu” element with links for each product Generate an “HTML data table” for any specified product including links for each FAQ for the product Generate an “HTML data table” for any specified FAQ for a specific product For a sequence of key words, return a list (in decreasing order of relevance) of FAQs for a specified product For a natural language query, return a list (in decreasing order of relevance) of FAQs for a specified product
The public API for this interface is a “contract” with the presentation manager. We will be free to change the internal implementation of the “engine” class at will without breaking the system. Figure 6-2 shows a detailed UML class diagram for the “engine” part of the help desk system. We show classes as a box with three vertical panes: name of class, listing of class
attributes, and listing of class methods. For high-level class diagrams, I often only specify the class name and leave the attributes list and methods list blank. It is often useful to list just the attributes (for data oriented classes like Faq and Product). A negative sign preceding an attribute or method implies that it is private while a plus sign indicates that it is public. Since the Help Desk product was a small effort, my design efforts were hand written on a few sheets of paper. Figure 6-2 was generated “after the fact” by importing the existing Java source files into the Poseidon UML tool.
HelpDeskEngine +DEBUG : boolean = false -singletonInstance : HelpDeskEngine = null -htmlMenu : String = null -htmlProduct : String = null ~v_products : Vector = new Vector() ~shared_FAQs : Hashtable = new Hashtable() ~invertedWordIndex : Hashtable = null ~products : Product = null ~title : String = "" -noiseWords : Hashtable = new Hashtable() +main(args:String) +getInstance() : HelpDeskEngine +HelpDeskEngine() : HelpDeskEngine -loadConfigFile() +getHTMLMenu() : String +getProductHTMLTable(in productIndex:int) : String +getFaq(in productIndex:int, in faqIndex:int) : Faq +getNumProducts() : int +getProductNames() : String +getFAQIndices(in productIndex:int, keyWords:String) : int +getFAQIndicesFromQuery(in productIndex:int, nlQuery:String) : int +getTitle() : String -createWordIndices() -readWords(counts:Hashtable, faq:Faq, in faqNumber:int) +wordsToArray(s2:String) : String -makeNoiseWords() contains Faq +title : String = "" +description : String = "" +ID : String = ""
Figure 6-2. UML Class Diagram for the Help Desk ‘Engine” There is an important point here: developing software is a complex task; here, we have effectively partitioned the job into two loosely connected tasks (i.e., developing the an engine and a presentation manager) that can be written and debugged separately. With the public interface defined between these two parts of the system, we can proceed with the
design, implementation, and unit testing of the engine without too much concern for the future task of designing, implementing, and testing the presentation manager. There is another fairly obvious advantage to splitting the problem into two pieces: we might in the future want to create a standalone application for the automated help desk. In this case, we could set aside the presentation manager that is implemented as a Java servlet and write a new presentation manager with, for example, the Java Swing library. Figure 6-3 shows a UML Sequence Diagram showing the interactions between a user (using a web browser), the HelpDesk servlet, and the HelpDesk Engine. Arrows represent requests or returned values from objects. This is general purpose: an arrow can be a method call between objects in the same Java Virtual Machine (JVM), a remote procedure call, etc. Time increases going down the page when looking at a sequence diagram.
Figure 6-3. UML Sequence Diagram for Help Desk System
Iterative Design and Development
It is difficult to know in advance all the features that a software system needs in order to be most convenient for users. As an example, after I did the preliminary requirements analysis in the last section for the help desk system, I started designing and coding the
“engine” module. As part of this effort, I set my emacs editor in XML mode and started to create an XML initialization file for the products on my www.markwatson.com web page. I quickly realized that there would be many common FAQs for several of my natural language processing products. My first thought was to implement an inheritance scheme for products. However, this seemed to violate a basic object oriented concept: subclasses should obey an “is a” type relationship with a super class. For example, a car “is a” type of vehicle. However, it did not seem right to create dummy products that would be super classes of real products. I decided that a simpler approach was better: independent of product definitions in a help desk XML initialization file, use a separate tag type, a “FAQ set”. Common FAQs can be defined in a “FAQ set” and any given product can simple list the FAQ sets that it uses.
Chapter 7. Model View Controller Design Pattern
There is a single design pattern that I use in most of my professional software projects and we will use repeatedly in this book: using the Model View Controller (MVC) pattern to separate the user interface from the “business logic” of programs. In this pattern, the model code has no user interface; rather, the model contains the main program logic, access to databases, access to other web services, etc. The view contains display code that is tied to the model by the controller code. Why is this useful? A short example will help to understand MVC as a software development strategy: I am, as I write this Web Book, also working on a commercial product for my company KnowlegeBooks.com that can best be described as an information appliance. I want two versions: web application and standalone application. Now, I really have two reasons for writing this product: 1. Web based version to act as an advertisement for the standalone application product and to perhaps attract consulting business from customers interested in the same general type of software. (Implementation of View and Controller pair). 2. Writing a useful product that can be run as both a standalone application and as a Java class library for customers to use in their own applications. (Implementation of the model). By using MVC, I can concentrate most of my development work building the classes for the model, including text based unit tests that I can frequently run to insure that I do not break any existing functionality as I write new code. I will not even worry about either the web based or standalone application user interfaces until the model functionality is (fairly) complete. Once the model code is done and tested, it will be a relatively small job writing the two view-controller pairs for the two user interfaces. So, when I am done, I will have three separate code modules: 1. Model code 2. View-Controller code for the web based user interface 3. View-controller code for the standalone application user interface For the examples in this book, we will discuss software design (at various levels of detail) for several common types of software systems. In software development, I almost always treat the requirements, design and implementation of model code separately from a viewcontroller pair.