- Shopping Bag ( 0 items )
|Ch. 2||Database Design||23|
|Designing a Database||24|
|Ch. 3||User Interface Design||61|
|The Development Process||61|
|Finding Reusable Code||87|
|Style and Techniques||94|
|Building Routines and Modules||113|
|Ch. 5||Object-Oriented Programming||121|
|Characteristics of Object-Oriented Languages||122|
|Ch. 6||Software Engineering||133|
|Object-Oriented Development to the Rescue?||134|
|The Cathedral and the Bazaar||136|
|The Spiral Model, 4GL, and RAD||138|
|OO and 4GL||139|
|The Magic Cauldron||143|
|Ch. 7||Object-Oriented Analysis||147|
|The Unified Modeling Language||148|
|Using UML in Object-Oriented Analysis||150|
|The Conceptual Model||160|
|System Sequence Diagrams||170|
|Ch. 8||Object-Oriented Design||179|
|Patterns for Object-Oriented Design||183|
|Using UML in Object-Oriented Design||188|
|Collaboration Diagrams for Borrow Books||190|
|UI and Database Design in Context||202|
|From Design to Code||205|
|What Is an RDBMS?||215|
|Getting Started with an RDBMS||222|
|Common Database Issues||241|
|Database Features Quick Reference||268|
|Ch. 10||Linux Development Tools Catalog||275|
|Drivers and Driver Managers||284|
|Ch. 11||Java, Swing, and JDBC||293|
|Running the Example Programs||298|
|Separating Content and Presentation||323|
|Ch. 12||DBI and Perl||335|
|The Perl DBI||335|
|User Interface in Perl||350|
|Tangram: Object-Relational Mapping in Perl||375|
|Keeping Up with the Developers||388|
|The GNOME Application Framework||389|
|Overview of GNOME-DB||413|
|Ch. 14||Software Architecture||449|
|Modularity and Troubleshooting||449|
|Message Passing Facilities||452|
|The Wonder of Relational Databases||456|
|Ch. 15||Introduction to CORBA||461|
|CORBA Implementations for Linux||464|
|App. A||SQL Reference||491|
|App. B||UML Reference||501|
Note: The Figures and/or Tables mentioned in this sample chapter do not appear on the Web.
Steve McConnell, Code Complete
Recognizing the potential irony of having a reference to a Microsoft book in the first sentence of a book about Linux, we added three extra sentences much as you would pad a data structure with extra bytes in hopes of aligning it optimally in memory. But, there's nothing we can do about that quote up there. It's from the same book, and we like that quote, so there it stays!
In Code Complete (Microsoft Press, 1993), Steve McConnell suggests that building a physical structure is an appropriate metaphor for software construction. Building a medium-sized software system is very close in complexity and cost to building a single-family house. Building a large software system parallels the complexity and cost of a large office building.
As with constructing a physical structure, the cost of fixing mistakes goes up the longer the mistake goes undetected. If you realize you need to make a fundamental change to the foundation of a house just as the shingles are going on, the cost can be prohibitive. It's the same for software development: The earlier a defect is introduced, the more expensive it is to fix as time goes on. For example, an error in the requirements analysis may cost a negligible amount with respect to the overall cost of the project if it is detected while you are validating the requirements. It will cost significantly more if it is detected while you are implementing the software. For this reason, it's important to get the requirements right. Before you build a system, make sure you are solving the right problem.
In this chapter, we'll look at some approaches to the traditional problems of system design. However, in Chapter 6, "Software Engineering," we'll take a fresh look at these problems in the context of open source development processes.
To build a system, you need a good blueprint. The first step in developing this blueprint is to state the problem that the system will solve. From there, you can develop a requirements document that states what the functionality of the system will be. You can then design the system, starting with its architecture, and move on to the design of its individual components.
The problem definition states the problem that needs to be solved. When I wrote that last sentence, I was tempted to say "the problem that the system will solve," but even that supposes too much. As a general guideline, the problem definition should state the problem without specifying a solution, including whether a system will be developed to solve the problem. This leaves room for other solutions to problems, such as modifications to existing business processes. Like other stages of the requirements process, the prob-lem definition should be developed by the users, system designers, and developers working together.
Let's take a look at a problem definition that violates this guideline:
We need a system to capture the amount of time an employee spends working on a given task and store that information in a database so we can query it later.
This problem definition skips over the problem itself and jumps right to the solution. It would be better to say:
Our present method of tracking the amount of time an employee works on a given task is inefficient. This method uses a spreadsheet for each employee to track informa-tion. It is error-prone, difficult to extract information from, and difficult to consoli-date. Consolidating spreadsheets from multiple employees is the most time-consuming and error-prone part of this process.
Given a statement of the problem, you can move on to analyzing the problem and coming up with a requirements specification.
The process of analyzing requirements begins with an analysis of the prob-lem definition, and goes on to define and specify the requirements. The requirements analysis is a process that brings you and the user community together to discuss what must be done. The problem definition is your first clue. At the end of the process, you'll have a document that states what the user needs and what the user will get.
To do a thorough job of requirements analysis, you'll need to spend time with your user community, their managers, and other people affected by the system (such as the developers of systems that your system needs to exchange data with). All of these people are collectively referred to as stakeholders. To gather information for requirements analysis, you'll need to interview the stakeholders, converse with them to clarify ambiguities, and, ultimately, obtain their approval on the completed requirements document. This approval is colloquially called "buy-in," and reinforces the notion that the stakeholders have something invested in the success of the project.
In Software Engineering (Addison-Wesley, 1995), Ian Sommerville discusses several issues to keep in mind when you interact with stakeholders:
Differing terminology. Some stakeholders, such as end users, cannot articulate their needs in technical terms. Instead, they will articulate their needs using terms and concepts they are familiar with. These terms and concepts may not be familiar to you, the software engineer. You'll need to become familiar with the concepts and terminology of the problem's domain. If possible, ride shotgun with users and learn their business.
Misunderstanding of scope and scale. Stakeholders who are not versed in software engineering have no idea of the costs and complexity involved with software development. You should use metaphors (such as the one discussed at the beginning of this chapter) to explain how complicated software development is. Explain that it's easy to verify when something like a Web page is finished by inspection (and the fact that the Web browser doesn't generate an error when you load the document). You can't do this with software. In practice, you can't verify the correctness of software with 100-percent confidence.
Conflicting requirements. Different stakeholders may have requirements that conflict with others. This is especially likely if the group of stakeholders is made up of members from different communities and corporate cultures. Citing the requirements in a document that is readable by both you and the stakeholders helps everyone to come to a consensus on the end product. It also becomes the basis of a contract between the developers and the stakeholders.
External influences. Remember that political, business, and economic factors have an influence on the process. A high-level agenda may influence the way in which users deal with the requirements process. High-level organizational changes can result in a project being canceled. If business practices change, the requirements may also change.
Sommerville describes six activities that make up the requirements analysis process. These activities do not always happen in sequence. In other words, as you complete one activity, you may learn something that changes your understanding of an activity you've already completed. This iterative process is one of continual refinement. The following are some important steps in the analysis process:
Domain understanding. The domain is the area or realm that the problem affects. Before you analyze the problem and the requirements, you need to become an expert in the domain. For example, in investment banking, programmers often spend time on a trading desk to learn about the business. Some of them master the business so well, they become traders or analysts themselves. Many good software engineers have been lost this way!
Requirements collection. Don't wait until you've mastered the users' business to start learning about what they want. Interview the stakeholders to learn what kind of system they need. Write everything down. As you do this, you'll also develop a better understanding of the problem domain.
Classification. After you collect requirements, you'll no doubt be left with a random collection of notes written on cocktail napkins, index cards, and the back of your hand. Classification takes these random items and structures them by grouping similar or related items into the same general classifications. For example, you might classify all the attributes of a consultant (such as name, address, phone number) into data-related requirements, and all the activities (such as "set the consultant's rate," or "assign the consultant to a project") directly into functional requirements.
Conflict resolution. If the problem involves different stakeholders, you may be left with some conflicting requirements. You'll need to find these conflicts and resolve them. This process can be politically tricky. For example, in some cases, this conflict resolution can reanimate rivalries within the organization that had long slumbered.
Conflict resolution may also emphasize gaps in the knowledge of Pointy-Haired Bosses (of Dilbert fame: also known as PHBs). It's not always easy telling someone who signs the paychecks that he or she is wrong, but in many cases, the people in the trenches know better than the higher-ups. If you want to master the fine art of dealing with such situations, you might look at books on topics such as conflict management, interpersonal conflict, problem employees, or business communication.
Prioritization. Users may ask for the world. While you can't give it all to them, you can ask them to prioritize their needs. This lets you determine what is most important, and sets the stage for creating incremental deliverables later on in the process.
Validation. By now, you have a set of raw requirements. Next, you need to review the raw requirements to determine whether you have everything the stakeholders think they want. This won't be the last time you'll validate the requirements, but it's good to validate them before you move toward the final requirements document.
Assuming that we've been through this process with the problem definition that appears at the beginning of this chapter, the raw requirements might look like:
A system is needed that automates the capture and reporting on the number of hours a consultant works on a project. Our company provides consulting services, and we need to track how the consultants spend their time, and use this information to invoice the customers.
Each consultant may be assigned to one or more projects. The rate for that consultant is determined on a per-project basis. A project is associated with a single customer, who is responsible for paying us the consultant's rate.
Each project is broken down into tasks that have a fixed start and end date. When a consultant submits the number of hours she worked on a given day, those hours must be associated with a particular task.
The system should track the following information about a consultant:
The Staff Coordinator is responsible for assigning consultants to projects and setting their rates.
The system should track the following information about a project:
The Staff Coordinator is responsible for adding customers and projects to the system.
The system should track the following information about a task:
The Clerk is responsible for maintaining a list of tasks.
The task must also contain a list of days and hours (a timesheet). Each timesheet must contain:
Each timesheet entry must contain:
How a consultant is to submit a timesheet. By 9: 00 A. M. every Thursday, the consultant should submit a timesheet for the preceding week. (This form is shown in Figure 1.1.)
How the Clerk is to enter a timesheet into the system. When all the timesheets have been collected, the Clerk will enter in each consultant's timesheet information. They need to give the system all the information that is on the timesheet.
How the Staff Coordinator gets the timesheet figures. The system should gener-ate a Weekly Summary Report that lists each customer name. For each customer name, the report should state the total number of hours for all consultants, and the total amount to bill the customer. Within each customer, the report must show each project, the total number of hours for all consultants who billed to that project, and the total amount to bill for that project. Within each project, the report must show the name and rate of each consultant who worked on the project, the name of the task he or she worked on, and the total amount of hours and dollar amount billed for that task. An example of the report is shown in Figure 1.2.
Once you have the raw requirements written down and validated, you can make them easier to understand and absorb by using several representational models. For example, Sommerville suggests a viewpoint model. Used in conjunction with the raw requirements, viewpoint model diagrams can provide a great deal of insight about a system, and serve as the basis for the requirements document, system architecture, and detailed system design.
The viewpoint analysis takes a look at the requirements from the viewpoint of different users. Figure 1.3 shows a possible viewpoint hierarchy for the timesheet requirements.
Sommerville places the viewpoint model within a larger requirements analysis framework, which is worth investigating for further research on requirements analysis. For the purposes of the analysis in this chapter, the viewpoint hierarchy suffices to provide a visual representation of the requirements. This technique can also be used as inspiration for user scenarios (as described in Chapter 3, "User Interface Design") or use cases (see Chapter 7, "Object-Oriented Analysis") to arrive at a better understanding of the requirements.
Sommerville points out three major problems with requirements that are specified in natural language. First, natural language is ambiguous. Anyone who has read a document in legalese knows the extremes to which we must go to make natural language precise. Second, a free-flowing natural language description can fail to distinguish between important categories of information (such as functional versus nonfunctional requirements, described in the next paragraph). Finally, requirements that are expressed using informal natural language may amalgamate requirements (that is, they may express multiple requirements as a single requirement).
To avoid these problems, we need to put the raw requirements into a more formal statement. The level of formality will depend on the complexity of your project and your own style. Aside from the format presented here, Sommerville discusses alternative formats, including Program Design Language (PDL), a structured pseudocode notation used to design programs. We discuss PDL in Chapter 4, "Construction."
The raw requirements we have discussed so far include only functional requirements, which are the requirements directly related to the purpose of the system. Another class of requirements is nonfunctional requirements. These are usually constraints, such as choice of operating system, development language, response time, and so forth.
In the formalized requirement that follows, I have used three guidelines, inspired by Sommerville:
Each requirement should express only one system task. Do not express multiple requirements as a single requirement.
Use a stylized notation. For example, the key points of a requirement are shown in bold, and a numbered outline system is used to group related requirements.
Justify each requirement. Notice that each requirement is accompanied by a rationale.
Here are the requirements for the timesheet system:
Once you have established the formal requirements, you need to validate them. One of the best methods for validating requirements is to build a prototype. This prototype should not be confused with a prototype of the user interface, which is discussed in detail in Chapter 3.
As difficult as it may be to let something go, in most cases, you should throw away (or archive) your prototype and implement the system almost from scratch. You don't have to throw away everything. If you have followed a modular approach in building the prototype, you can reuse some of the modules and/ or objects you built while you developed the prototype. Take care when invoking this privilege, however. If you know that you might want to reuse a module, build it as though you were building it for a production system, not for a prototype. It may slow things down in the short term, but in the long run, you will save time.
Sommerville warns against building a general-purpose prototype. A prototype should have one purpose, such as one of the following: prototyping the user interface, validating the requirements, or demonstrating the feasibility of the project. If you are (and you should be) using the prototype to verify the requirements, make sure this is the only thing you use the prototype for. A prototype that is put together to validate the requirements may not make the best user interface prototype.
What to build the prototype with. Fortunately, Linux users have at their disposal many wonderful tools for developing prototypes. Any of the most popular scripting languages, such as Perl, Python, or Tcl, support a variety of user interfaces. These scripting languages can be used to quickly develop a prototype complete with a user interface and database connectivity (and any of these languages is fine for building the final product, as well).
How much design? How much design needs to go into the prototype? To a large extent, you should use this book to familiarize yourself with the techniques for building an application. Then, as you are building a prototype, you can select the techniques that you feel are appropriate for the level of detail your prototype will capture. Many prototypes focus on areas of uncertainty in the requirements: If the area of uncertainty is in something that greatly affects the database design, you may want to put more effort into the prototype's database design.
There is no such thing as a stable set of requirements. All you can hope for is a snapshot in time of what the stakeholders need. As time goes on, the requirements will change. In fact, it is likely that they will change as you design and develop the system. With this in mind, you need a firm change control procedure in place. The stakeholders must understand that a change in the requirements can have one of two outcomes.
One key to successfully building a system is successfully managing changes in the requirements. McConnell suggests some strategies for managing changes that can help you as you develop the software (however, see Chap-ter 6's section titled The Cathedral and the Bazaar, which refers to and is titled after Eric S. Raymond's essay of the same name, for a different perspective on this problem):
Create a formal procedure for requesting changes. This will help you manage the inevitable flood of requests and keep them from over-whelming you.
Establish a change-control board. The change-control board is a committee or group that is responsible for deciding what changes are allowed to be made.
Deal with changes in batches. All of us have given in to the urge to implement a change that seems easy to implement. If you implement every change this way, some good changes might fall through the cracks if they occur to you too late in development. Dealing with them in batches also gives small changes greater visibility in the overall schedule.
Estimate the cost of every change. Because of the inherent complexity in software development, even the simplest change can have large effects on other parts of the system. Before you agree to a change, make sure you know what it will cost.
Major change requests indicate something is wrong. If you're getting major change requests during development, you should strongly consider apply-ing the brakes on the development process and going back to the require-ments stage. Perhaps you had been prototyping to validate the requirements without knowing it!
Before you can proceed to a detailed design of the system, you need to sort out the system's architecture. The architecture is a high-level model of the system that clearly depicts its subsystems and the connections among them.
When you break the system down into its structure, you need to divide it into subsystems, smaller systems that function independently of other sub-systems. The requirements document shown earlier in this chapter hints at a system made up of three independent smaller systems: a Consultant Maintenance subsystem, a Company Maintenance subsystem, and a Timesheet Maintenance subsystem.
The fact that these subsystems exchange data does not make them dependent upon each other. Instead, we look to one of the models that Sommerville discusses, the repository model. In one type of the repository model, each subsystem exchanges data with the others through a shared database. Since this is a book about building database applications, we are going to use this model for every example in this book. Figure 1.4 shows a possible structure for this system.
Some features of the repository model include:
Agreement. Each subsystem must agree on the structure of the shared data-base. Since this book approaches database design from a system level (rather than on a subsystem-by-subsystem basis), this is not a problem. Chapter 2, "SQL and Relational Database Design," discusses how you can take the system requirements and develop a database design.
Centralization. The database administrator can maintain central control over access control, security, backups, and other issues.
Extensibility. Since there is an agreed-upon database structure, new tools can be easily integrated into the system.
The next step is to model how control will flow within and between the sub-systems. One of the models that Sommerville discusses is the event-based control model. In this model, there is no central system that governs the flow of control. Instead, events that originate outside of the system control determine which subsystems are activated and how control flows between subsystems. Such events can come from other systems or from the system's user interface.
Since this book is concerned with GUI-enabled desktop database applications, as opposed to batch-oriented systems, the event-based model fits our example rather well.
However, if we assume the existence of a single application entry point, we need to include that entry point (the Main Screen in Figure 1.5) in our control model. So, our model derives a bit from a centralized control model (also discussed by Sommerville), as well as an event-based control model. In the centralized model, a single subsystem takes responsibility for the initial control of the other subsystems. Figure 1.5 shows a control model for the timesheet system.
Rather than being completely controlled by a subsystem that has central control, many parts of it will be controlled by responding to external events: a user starting the application, clicking the mouse, or typing some text.
Once you have completed the previous steps, you can move on to breaking the system into smaller pieces. One of the biggest problems with large software projects is that it is not possible for any one person to comprehend the system as a whole. When you break the system down into smaller pieces, you create manageable components that can be understood by one person. In Chapter 8, "Object-Oriented Design," we look at techniques for designing systems that are made of manageable components.
There are three activities involved in designing the types of applications we are covering in this book: database design, user interface design, and module or object design. Once these activities are completed, developing the system becomes quite manageable. Although this book presents them in a specific order, don't look at these activities as something that must be performed one at a time, in sequence to completion. It's much more iterative than that. In fact, you may complete your database and user interface designs, and when you move on to object design, you may learn something that sends you back to user interface design. The reality is that these activities feed into one another.
Database design. This activity models the system data in a manner than can be easily processed by a relational database system. Unfortunately, the output of this process is not always something that is intuitive to humans. Instead, the output of the database design process ensures that the database is correct, consistent, and efficient. The burden falls on the user interface design to present a pretty face. Database design is covered in detail in Chapter 2.
User interface design. This activity models the system's data and behavior in a visual manner. User interface design involves many factors that affect human cognition, such as memory (human, not computer memory) issues, spatial organization, and aesthetics. User interface design is discussed in Chapter 3.
Module or object design. Object-oriented analysis and design models the system's data and behavior in a way that is close to how humans think of real-world objects. Modular design isolates related processes and data in a way that maximizes code reuse. Chapter 4, "Construction," discusses modularity, and object-oriented concepts are introduced in Chapter 5, "Object-Oriented Programming." Chapters 7 and 8 discuss object-oriented analysis and design.
The problem definition. This answers the question, "why am I building this system?" It's the most important thing to get right. If you don't get the problem definition right, you run the risk of solving the wrong problem.
Requirements analysis. In order to build up a document that serves as a roadmap for the system, you need to analyze the problem. To do this, you will need to become involved with the stakeholders, understand their business needs, and pay attention to many details.
The formal requirements document. Using a formalized, organized approach, you can build a document that unambiguously specifies what it is you are to build. As you build the system, you will need to exert some control over the changes that will be made to the requirements.
The prototype. Once you have developed this document, you may need to validate the requirements with a prototype.
System architecture and design. Before you can proceed to the design of the system objects, the database, and the user interface, you must determine the architecture of your system. This encompasses three stages: system structuring, control modeling, and modular decomposition. The concepts discussed in Chapters 4, 5, 7, and 8 can be applied to modular design.
This chapter offers the image of building a physical structure as a metaphor for constructing a software system. It's important to keep in mind that one metaphor does not fit all cases. In practice, the building metaphor is most appropriate to the specification and design stage of a software project. Where it still fits in other stages, we'll build on this metaphor. However, in Chapter 6, "Software Engineering," we'll take a look at some of the advantages that the open source approach can offer over (or in combination with) the approaches discussed in this chapter.
There is one thing we should make perfectly clear: this book does not talk about how to develop web database applications. There are many books on this topic (Brian has even written a couple of them), and perhaps we will address it in a future edition of this book. However, with the growth of desktop application environments such as KDE and GNOME, we felt challenged to produce a book with a desktop focus.
It wouldn't be fair to say that this book is only about plugging databases into a pretty user interface. In fact, it's much more than that. In this book, we're going to look at a lot of things that will help you build better applications, and you'll be able to apply many of these things to other programming endeavors. Here are some of the topics we discuss:
In this book, we look at five popular database systems for Linux: PostgreSQL, MySQL, Mini SQL, Sybase, and Oracle. Wherever possible (and incompatibilities permitting), we have developed example code that works with as many of these databases as possible. Differences that were known to us during writing and testing are documented where appropriate, and Chapter 9, "Databases," takes a close look at these databases. Two areas we focus on in particular are how you can get up and running with the database system of your choice, and how each database server deals with specific database development issues. We also take a good look at the different data types and date formats, two things that are confusing when developing cross- database applications.
If your favorite database system was not covered in this book, we apologize, but we had a limited amount of time to produce this book, and we chose these database systems so we could best leverage the experience of the authors. If you are interested in other database systems for Linux, see Christopher Browne's resource on this topic at www.ntlug.org/~cbbrowne/rdbms.html.
In this book, we spend as much time talking about what you must do to prepare for programming as we do about programming itself (I think I heard a groan from the back of the room). Don't fear - even the chapters about analysis and design are peppered lightly with some concrete examples, and we think you'll find it useful. We won't mind if you skip ahead to the implementation-oriented stuff, which begins in Chapter 9. We're hoping that if you do that, you'll eventually come back to the earlier stuff.
UML and Patterns
Perhaps these are two buzzwords you've heard a lot, or perhaps these are two things with which you are familiar. For those who don't know, UML and Patterns are modeling aids that are used by programmers and designers to better communicate with others. UML is a notation that documents a number of things, including the mental model you have of a system that you're going to build, the classes that make up a system, and how these classes are related. Patterns are a way of expressing solutions to problems in a context. When you are looking at a problem that needs to be solved, you can apply one or more Patterns to reach a solution. This makes it easy for you to find a solution, gives you confidence that you are doing something tried and true, and makes it easier for other people to understand your design. Chapter 7, "Object-Oriented Analysis," and Chapter 8, "Object-Oriented Design," talk about how you can apply UML and Patterns to analyze and design your project.
Chapter 2, "Database Design," specifically addresses SQL, the programming language used by all five database servers we discuss in this book. Before we dive into the SQL, though, we take a good look at how to design a database in the context of a problem that needs to be solved. We look at a particular set of requirements, plan a database for a system, and refine it until it's designed well enough to work well with an SQL database system. Then, we show you how to create the tables that make up the database, and how to work with them in SQL. Appendix A, "SQL Reference," will help you find your way around the language. Chapter 9 treats many database issues, including several special topics in SQL.
Chapters 11, 12, and 13 cover Java, Perl, and C, respectively. In all three chapters, we look at how you can develop graphical applications in these languages that talk to an SQL database back-end. Chapter 13 looks at C programming in the context of GNOME, an exciting desktop application framework for Linux and other operating systems.
Who Can Use This Book
Before we wrote this book, we decided to keep one user in particular in mind: someone who has been using the Linux system for a little while, and who may have learned a bit of programming. This is not to say that expert users or complete novices should be afraid; in fact, we felt that by targeting the inexperienced programmer, we would diminish barriers to entry as much as possible. Also, by concentrating on delivering a lot of information in this book, we felt there would be plenty of interest for even the most experienced programmers.
How to Use This Book
For the total Linux newbie, we suggest that you take the time to get comfortable with Linux, and get to know your way around the Linux shell (bash, the Bourne Again Shell) before you try to tackle this book. It's best if you've had some experience doing light programming in a language such as Perl, Tcl, or Python, and that you understand the basics of programming (functions, variables, and data structures such as arrays, linked lists, and hashtables, for example).
For the expert developer, there are certainly parts of the book that you can skip, if you feel like it. We think that the chapters are set up in a way that you can simply read the first few paragraphs of each chapter to decide whether the chapter will be helpful.
For the rest of you (and total newbies after you've learned the basics), we'd like you to try going through the book from start to finish. The first thing you'll see is Chapter 1, "Requirements," which talks about software development from a very traditional perspective. Although we use this approach as the basis of the next three chapters (Chapter 2, "Database Design"; Chapter 3, "User Interface Design"; and Chapter 4, "Construction"), we take a fresh look at the issue in the chapters that follow. Chapter 5, "Object-Oriented Programming," is a quick introduction to object-oriented programming, and in Chapter 6, "Software Engineering," we look at software engineering from an open source perspective. Finally, we wrap up the Part One of the book by looking at how you can use UML and Patterns to design a system. Then, it's on to Part Two.
Part Two of the book looks at implementation issues. Chapter 9 looks at what you need to get up and running with any of the five database servers we talk about in this book. Chapter 10, "Linux Development Tools Catalogue," takes a quick look at various tools that will help you develop Linux database applications; everything from graphical query tools to environments that are similar to 4GL tools like Access. From there on, the next chapters look at programming database applications in Java, Perl, and in C under the GNOME framework. After that, we wrap up the book with chapters on distributed components and CORBA.