Software Paradigms / Edition 1 available in Hardcover

- ISBN-10:
- 0471483478
- ISBN-13:
- 9780471483472
- Pub. Date:
- 03/17/2005
- Publisher:
- Wiley

Hardcover
Buy New
$183.95Buy Used
$118.29-
SHIP THIS ITEMIn stock. Ships in 1-2 days.PICK UP IN STORE
Your local store may have stock of this item.
Available within 2 business hours
-
SHIP THIS ITEM
Temporarily Out of Stock Online
Please check back later for updated availability.
Overview
Product Details
ISBN-13: | 9780471483472 |
---|---|
Publisher: | Wiley |
Publication date: | 03/17/2005 |
Pages: | 440 |
Product dimensions: | 6.42(w) x 9.51(h) x 0.99(d) |
About the Author
Read an Excerpt
Software Paradigms
By Stephen H. Kaisler
John Wiley & Sons
Copyright © 2005 John Wiley & Sons, Inc.All right reserved.
ISBN: 0-471-48347-8
Chapter One
INTRODUCTION
Programming is about the creation of software to solve problems. Problems come in many forms: simple to complex, small to large, I/O-intensive to compute-intensive. Over the past four decades, we've tried to solve a lot of different types of problems with software. At some, we have been exceptionally successful and the solution space is well understood. For others, such as those proposed by artificial intelligence, we have only been marginally successful (and, in many cases, not at all) within limited domains.
But, programming has always been both a knowledge-intensive and labor-intensive process. As PCs became more pervasive and the demand for applications increased, a problem arose-how to develop safe, robust software quicker.
Traditionally, the software industry has focused on delivering high-quality, special purpose application software to the end-user and high-quality, general purpose development software to the professional developer. End-users are not expected to develop their own applications. Much effort has been invested in making software development more efficient for professional developers by providing huge collections of prefabricated software components. Much effort has also been invested in increasing the utility of application software by providing customizable user interfaces.
Most software development tools are too complex for end-users. The few that are simple enough to attract nonprogrammers limit the user to simple applications that can't be combined with other software. Applications have to be built from scratch; they do not scale and, therefore, are often of limited practical use. On the other hand, commercial application software offers little modifiability beyond customization of the user interface. In particular, applications do not let users modify their behavior or reuse their functionality within other applications.
The solution to this problem requires the following assumptions:
1. High-quality software applications should be producible with some skill and effort by taking advantage of functionality in software components developed by others.
2. Flexible integration of new software applications should be achievable by decomposing applications into small functional components that can be reused independently and recombined efficiently.
The first assumption requires that users focus more on gluing components together rather than developing individual components, although they will have to do some of the latter. The second assumption requires that users have standard ways of describing and representing components as well as guides for how to connect those components together.
Software developers and users should be able to build small applications fast and easily. The learning effort required to start building an application should stay in the range of hours. Nevertheless, users should expect their applications to be comparable in look and feel to commercial software.
To achieve this goal, there are four problems to be addressed:
1. How do we build more complex structures from simple parts?
2. What is the best way to integrate ("glue together") multiple parts to form a whole?
3. How can we construct parts to make them reusable, and reuse them?
4. How can we ensure that small solutions can scale to bigger problems?
This book will provide some answers to these questions. We do so through examination of different conceptual paradigms-from the small to the large for constructing software applications.
1.1 THE MEANING OF PARADIGM
Paradigm (a Greek word meaning example) is commonly used to refer to a category of entities that share a common characteristic. Numerous authors have examined the concept of a paradigm. Perhaps the foremost user of the word has been Thomas Kuhn (1996), who wrote the seminal book The Structure of Scientific Revolutions.
Kuhn used the notion of paradigm in the scientific process by defining it as a scientist's view of the world and the structure of his assumptions and theories, which affect that view. In his definition, he included the concepts of law, theory, application, and instrumentation: in effect, both the theoretical and the practical.
Kuhn saw a "paradigm" as emerging as the result of social processes in which people develop new ideas and create principles and practices that embody these ideas. Large software development is a social process, because it is often a team effort. Each new software application is a unique creation in its own right. Rarely, if ever, does a team of programmers set out to create a program that exactly mimics the code and structure of some other program.
Kuhn's definition has been applied beyond his original application to the history of physical science. Others believe that paradigms are the basis of normal science; indeed, the basis of established scientific tradition. In this view, the formation of a paradigm is a sign of maturity for a given science. The notion of a paradigm for programming was first expressed by Floyd (1979) as far as I have been able to discern.
We are going to apply the notion of paradigm to the investigation of programming languages and software architectures to determine how well we can solve different types of problems. The question we would like to answer takes the form: Is there a taxonomy within a particular domain that serves to organize the element of that domain? In programming languages, most computer scientists would answer "yes." In software architectures, the answer is more likely a definite "maybe." By the end of this book, we believe that you'll see the answer for software architectures is "yes."
1.2 SOFTWARE SOLVES PROBLEMS
How do we classify problems? Put another way, is there a typology of problems? If so, can we find common solutions that are widely applicable to many or all of the problems in the class? The recent emergence of patterns and frameworks suggests that there is such a typology and that we can find common solutions to them. Much work needs to be done in this area, but early results are very promising.
For a given problem class, we'd like to be able to create software that solves the problem or parts of it efficiently. There are two aspects to creating such software: the software's architecture and the choice of programming language.
1.2.1 Software Architecture
Software architecture is the structure of the components of the solution. We decompose the problem into smaller pieces and attempt to find a solution for each piece. Sometimes, the solution for a piece requires further decomposition. When we have the solutions for each of the components, we have to integrate them and make them interoperate in order to have a piece of software, sometimes called an application, that solves the problem. Integration means the pieces fit together well. Interoperation means that they work together effectively to produce an answer.
There are many software architectures. Choosing the right one can be a difficult problem in itself. It is not clear yet what metrics are suitable for evaluating software architectures. We'll address software architecture in more detail in Part III of this book.
1.2.2 Choosing a Programming Language
The second problem we face is choosing the best programming language to implement our software. There are different paradigms for programming languages that drive their syntax and semantics. There is no one programming language that is right for all problems. Alternatively, we do not know yet if there is one programming language that is best for a particular class of problems. In addition, we do not yet have the right set of metrics for deciding if this is so.
There have been a large number of programming languages. Jean Sammet (1967) counted at least 700, but most are now defunct. New programming languages continue to emerge, although less frequently than in the past. Recently, much work has focused on evolving and/or extending existing programming languages rather than creating new ones. Perhaps that is a sign of maturity in the field. George Michael (1980) once said that there will always be a Fortran, although we may not recognize today's language in it. Some features are being recognized as essential for writing good software-such as the evolution of object-oriented versions of older programming languages. Others, such as concurrency, support the way to create more efficient and better performing software.
So, faced with developing a solution to a particular problem, we have three tasks to perform (see Figure 1-1). First, we need to decide which set of features comprise our problem. This is the requirements analysis task. Second, we need to develop a suitable software architecture or algorithm for each subproblem and develop a software architecture for the overall problem. This is the system design task. Third, we need to choose a good, if not the best, programming language for each subproblem and implement the solution. This is the implementation task. That's not all there is to achieving a useful application, but that's the primary focus of our effort here.
It is important to distinguish between the programming language, the paradigm on which it is based, and the algorithm that is used to solve the problem. Theoretically, it should be possible to write any algorithm in any general purpose language. However, some languages offer more support for particular software paradigms than others.
The problem of architecting a software solution to a problem is a complex one. It involves multiple tradeoffs that must be decided in order to yield a successful application that meets the requirements for solving the problems and the needs of the user(s) of the system. Inevitably, some combinations of trade-offs yield programming approaches that are clearly impractical for implementing an application. We have chosen to focus our attention in this book on structural paradigms for software systems.
1.3 DESIGNING AND DEVELOPING SOFTWARE
Software was originally called "soft" to distinguish it from the machine that executed it. Software is soft in a number of ways. It is not visible when it is running. It seems to change all the time, both when it is running and when it is being built. It is difficult to describe fully all aspects of software. In other words, there is no widely known way to describe the structure of a complete software system in the same way that the structure of a complete building, or an airplane, or a chemical plant is described. We can capture the static structure of a software system fairly well in many mature tools, but the dynamics continue to elude us. Nor do many of the well-known software analysis and design methodologies provide a notation for integrating the structure of the complete system with its dynamics.
We are interested in how to solve problems. In particular, we want to develop software that repeatedly can solve the same problem over and over with new data sets. In most cases, we understand the general approach to solving the problem. We may know, in fact, all the procedures and details. But, for all but the simplest problems, the thought of working through the algorithm(s) by pencil and paper is rather daunting.
Software allows us to capture the algorithms and detailed procedures in an electronically tangible form that permits almost effortless repetition ( just push the button, they say). The hard part is designing the software, developing the software, and ensuring that it is correct. This book is about software design; we leave the latter topics for other volumes.
Today, most large software systems are too complex for a single individual to understand. Most of the software development we do these days we do with others because a single person hasn't the required skill or time to solve a complicated problem alone. One way to facilitate working together is to use and reuse concepts or ideas for which we share a common understanding.
When we write our first program, it often involves an intense amount of effort. The next time we performed a similar task, it is/may be a bit easier because we learned some things that we could reuse in our next project. As we develop more experience, we not only continue to learn new practices, but we refine and hone the practices that we have already learned. Some of them become rote because we have recognized them as "best practices" for programming and software development.
When we can capture and share the things we learn each time, we can reduce the need to rediscover what we've done before and share them with others who can also save time. This leads to a very important aspect of developing software that most of us don't think much about but is basic to our success-the need for effective collaboration.
The technical literature is replete with books and technical papers on software design and the software design process. We do not intend to duplicate their efforts. We see software design as a three-pronged process: understanding the problem domain, designing the software architecture, and choosing the programming language. While addressing programming languages and problem taxonomies, our primary focus is on how to construct software.
1.3.1 Reusability
We have known for a long time that writing each new application "from scratch" is very expensive and time-consuming. There has long been an emphasis on reuse of software to mitigate some of the costs of developing new applications.
At the same time, developers felt that they could improve each succeeding application using the lessons learned from the preceding one, but that such use required a complete rewrite of the application. By the 1990s, we realized as a community that successive applications could be built by reusing knowledge and software from earlier applications. This meant that succeeding applications could often be built faster than their predecessors.
1.3.2 Types of Reuse
At first, reuse referred just to the actual source code itself. Basili and Rombach (1988) expanded the definition to encompass everything associated with a software development project. Prieto-Diaz (1988) describes a taxonomy of eleven types of reuse as depicted in Table 1-1.
1.4 UNDERSTANDING PROBLEM PARADIGMS
A problem paradigm is a model for a class of problems that share a set of common characteristics. These characteristics serve to differentiate one problem type from another. Some problem types that you may have encountered in the past include search problems and classification problems (see Figure 1-2).
Over the past 40 years of computer science, we have identified classes of problems that share common characteristics. Problems such as search, enumeration, classification, data organization and manipulation, and sorting are encountered routinely in just about every application that is written.
When one thinks about it, there are relatively few problem structures that we encounter in computer science. However, we encounter them over and over in different contexts with different features and twists that make for interesting programming challenges.
Some of these problem paradigms have to do with the way data is structured and some with the type of processing to be applied to the data. Search, for example, is a recurring problem in many applications. But searching through a randomly ordered data set is different from searching through a known, sorted set represented as a vector or a B*-tree.
1.4.1 Fundamental Operations
At the lowest level of computation, there are some fundamental operations that must be performed to solve any problem, no matter how they are syntactically represented. Among these are assignment of values to variables, decision making, and sequencing through instructions as shown by Bohm and Jacopini (1966). As one considers more complex programs, one realizes that other operations become fundamental as well. We would argue strongly that recursion, procedure calls, concurrency, and exception handling-to name a few-should also be considered as fundamental operations.
1.4.2 Algorithms and Architectures
An algorithm is a specification for how to solve a particular problem. Algorithms are ordered sets of unambiguous, executable steps that define a terminating process. The key idea is that an algorithm is deterministic. With the proper inputs to the algorithm, repeated execution of the algorithm will return the same result. In addition, an algorithm must complete (e.g., yield a result) in a finite amount of time.
(Continues...)
Excerpted from Software Paradigms by Stephen H. Kaisler Copyright © 2005 by John Wiley & Sons, Inc.. Excerpted by permission.
All rights reserved. No part of this excerpt may be reproduced or reprinted without permission in writing from the publisher.
Excerpts are provided by Dial-A-Book Inc. solely for the personal use of visitors to this web site.
Table of Contents
ADVICE FOR THE INSTRUCTOR.ACKNOWLEDGMENTS.
1 Introduction.
1.1 The Meaning of Paradigm.
1.2 Software Solves Problems.
1.3 Designing and Developing Software.
1.4 Understanding Problem Paradigms.
1.5 Overview of Book.
1.6 Conventions.
1.7 Exercises.
2 Paradigm Overview.
2.1 Problem Paradigms.
2.2 A Functional Classification of Problems.
2.3 Programming Languages.
2.4 Design Patterns.
2.5 Components.
2.6 Software Architectures.
2.7 Frameworks.
2.8 Further Reading.
2.9 Exercises.
I DESIGN PATTERNS.
3 Overview of Design Patterns.
3.1 A Brief History of Patterns.
3.2 Why Patterns?
3.3 Pattern Spaces.
3.4 Types of Software Patterns.
3.5 Describing Patterns.
3.6 How Do We Discover Patterns?
3.7 Using Patterns.
3.8 Further Reading.
3.9 Exercises.
4 Software Patterns.
4.1 Singleton.
4.2 The Wrapper Pattern.
4.3 The Abstract Factory Pattern.
4.4 Observer Pattern.
4.5 Exercises.
5 Human–Computer Interface Patterns.
5.1 Style Guides.
5.2 An HCI Pattern Language.
5.3 Web Design Patterns.
5.4 Further Reading.
5.5 Exercises.
6 Other Pattern Domains.
6.1 Coplien’s Patterns.
6.2 Object-Oriented Patterns.
6.3 Antipatterns.
6.4 Further Reading.
6.5 Exercises.
7 Pattern Design.
7.1 Design Pattern Issues.
7.2 Some Simple Pattern Design Principles.
7.3 Limitations of Design Patterns.
7.4 Further Reading.
7.5 Exercises.
II COMPONENTS.
8 Component Concepts.
8.1 What Are Software Components?
8.2 Why Use Components?
8.3 Component Models.
8.4 Using Components.
8.5 Component Reuse.
8.6 Exercises.
9 Types of Components.
9.1 Event-Based Components.
9.2 Java Events.
9.3 Distributed Components.
9.4 Transaction Processing.
9.5 Further Reading.
9.6 Exercises.
10 Component Technologies.
10.1 CORBA.
10.2 System Object Model.
10.3 Microsoft’s COM/DCOM.
10.4 JavaBeans.
10.5 Further Reading.
10.6 Exercises.
11 Component-Based Software Engineering.
11.1 Defining CBSE.
11.2 Problems with CBSE.
11.3 Problems in Using Components.
11.4 Problems with Glue Code.
11.5 Exercises.
III SOFTWARE ARCHITECTURES.
12 Overview of Software Architectures.
12.1 Software Architecture Elements and Description.
12.2 Why Do We Need a Software Architecture?
12.3 Software Architecting Versus Software Engineering.
12.4 Domain-Specific Software Architectures.
12.5 Roles and Benefits.
12.6 Software Architecture Models.
12.7 What To Look For.
12.8 Further Reading.
12.9 Exercises.
13 Data Flow Systems.
13.1 The Data Flow Model.
13.2 Batch Sequential Systems.
13.3 Pipe and Filter Architecture.
13.4 Further Reading.
13.5 Exercises.
14 Call-and-Return Systems.
14.1 Main Program and Subroutines.
14.2 Client–Server Systems.
14.3 Object-Oriented Systems.
14.4 Hierarchically Layered Systems.
14.5 Further Reading.
14.6 Exercises.
15 Virtual Machines.
15.1 Interpreters.
15.2 Virtual Machine Examples.
15.3 Rule-Based Systems.
15.4 Advantages and Disadvantages.
15.5 Further Reading.
15.6 Exercises.
16 Independent Component Systems.
16.1 Communicating Sequential Processes.
16.2 Event-Based Systems.
16.3 Event System Issues.
16.4 Broker Systems.
16.5 Further Reading.
16.6 Exercises.
17 Data-Centric Systems.
17.1 Database Systems.
17.2 Blackboard Systems.
17.3 The Linda Model and Language.
17.4 Further Reading.
17.5 Exercises.
18 Concurrent Software Architectures.
18.1 Basic Concepts.
18.2 Parallel Programming.
18.3 Data Parallel Systems.
18.4 Message Passing Systems.
18.5 A Parallel Programming Methodology.
18.6 Further Reading.
18.7 Exercises.
19 Software Architecture Challenges.
19.1 Software Architecture Description.
19.2 Design Issues.
19.3 Analysis of Software Architectures.
19.4 Further Reading.
19.5 Exercises.
IV FRAMEWORKS.
20 Framework Concepts.
20.1 Types of Frameworks.
20.2 Framework Elements.
20.3 Using Frameworks.
20.4 Documenting Frameworks.
20.5 Designing Frameworks.
20.6 Problems with Frameworks.
20.7 Framework Domains.
20.8 Further Reading.
20.9 Exercises.
21 GUI Frameworks.
21.1 Smalltalk-80 Programming Environment.
21.2 MacApp Framework.
21.3 The Taligent Framework.
21.4 Other Frameworks.
21.5 Further Reading.
21.6 Exercises.
22 Development Frameworks.
22.1 Java as a Framework.
22.2 Microsoft’s .NET Framework.
22.3 IBM’s San Francisco Project.
22.4 POOMA.
22.5 Further Reading.
22.6 Exercises.
23 Challenges in Frameworks.
23.1 Developing Frameworks.
23.2 Application Development Using a Framework.
23.3 Testing Frameworks.
23.4 Issues in Framework Usage.
23.5 Exercises.
BIBLIOGRAPHY.
GLOSSARY.
INDEX.
What People are Saying About This
"...an excellent course reference for someone with significant but varied...software development ideas...a handy reference for identifying the similarities between...software development elements…" (IEEE Software Magazine, January/February 2006)
"…useful to some programmers." (CHOICE, October 2005)
"This is a good survey of the various topics…quite relevant to the CSQE body of knowledge architecture topic." (Software Quality Professional, September 2005)
"…a timely work that helps put recent advances in software architecture and framework development in context with earlier software design concepts." (Computing Reviews.com, July 29, 2005)
"…a welcome…addition to the literature on software development paradigm." (Computing Reviews.com, May 3, 2005)