Chapter 2: Software Design
Contents
- 1 Software Design Fundamentals
- 2 Key Issues in Software Design
- 3 Software Structure and Architecture
- 4 Software Structure and Architecture
- 5 User Interface Design
- 6 Software Design Quality Analysis and Evaluation
- 7 Software Design Notations
- 8 Software Design Strategies and Methods
- 9 Software Design Tools
- ADL
- Architecture Description Language
- CBD
- Component-Based Design
- CRC
- Class Responsibility Collaborator
- DFD
- International Council on Systems Engineering
- ERD
- Entity Relationship Diagram
- IDL
- Interface Description Language
- MVC
- Model View Controller
- OO
- Object-Oriented
- PDL
- Program Design Language
Design is defined as both “the process of defining the architecture, components, interfaces, and other characteristics of a system or component” and “the result of [that] process” [1]. Viewed as a process, software design is the software engineering life cycle activity in which software requirements are analyzed in order to produce a description of the software’s internal structure that will serve as the basis for its construction. A software design (the result) describes the software architecture—that is, how software is decomposed and organized into components—and the interfaces between those components. It should also describe the components at a level of detail that enables their construction.
Software design plays an important role in developing software: during software design, software engineers produce various models that form a kind of blueprint of the solution to be implemented. We can analyze and evaluate these models to determine whether or not they will allow us to fulfill the various requirements.
We can also examine and evaluate alternative solutions and tradeoffs. Finally, we can use the resulting models to plan subsequent development activities, such as system verification and validation, in addition to using them as inputs and as the starting point of construction and testing. In a standard list of software life cycle processes, such as that in ISO/IEC/IEEE Std. 12207, Software Life Cycle Processes[2], software design consists of two activities that fit between software requirements analysis and software construction:
- Software architectural design (sometimes called high-level design): develops top-level structure and organization of the software and identifies the various components.
- Software detailed design: specifies each component in sufficient detail to facilitate its construction.
This Software Design knowledge area (KA) does not discuss every topic that includes the word “design.” In Tom eMarco’s terminology[3], the topics discussed in this KA deal mainly with D-design (decomposition design), the goal of which is to map software into component pieces. However, because of its importance in the field of software architecture, we will also address FP-design (family pattern design), the goal of which is to establish exploitable commonalities in a family of software products. This KA does not address I-design (invention design), which is usually performed during the software requirements process with the goal of conceptualizing and specifying software to satisfy discovered needs and requirements, since this topic is considered to be part of the requirements process (see the Software Requirements KA).
This Software Design KA is related specifically to the Software Requirements, Software Construction, Software Engineering Management, Software Engineering Models and Methods, Software Quality, and Computing Foundations KAs.
The breakdown of topics for the Software Design KA is shown in Figure 2.1.
1 Software Design Fundamentals
The concepts, notions, and terminology introduced here form an underlying basis for understanding the role and scope of software design.
1.1 General Design Concepts
In the general sense, design can be viewed as a form of problem solving. For example, the concept of a wicked problem—a problem with no definitive solution—is interesting in terms of nderstanding the limits of design. A number of other notions and concepts are also of interest in understanding design in its general sense: goals, constraints, alternatives, representations, and solutions (see Problem Solving Techniques in the Computing Foundations KA).
1.2 Context of Software Design
Software design is an important part of the software development process. To understand the role of software design, we must see how it fits in the software development life cycle. Thus, it is important to understand the major characteristics of software requirements analysis, software design, software construction, software testing, and software maintenance.
1.3 Software Design Process
Software design is generally considered a two-step process:
- Architectural design (also referred to as high-level design and top-level design) describes how software is organized into components.
- Detailed design describes the desired behavior of these components.
1.4 Software Design Principals
A principle is "a comprehensive and fundamental law, doctrine, or assumption" [7]. Software design principles are key notions that provide the basis for many different software design approaches and concepts.
Software design principles include abstraction; coupling and cohesion; decomposition and modularization; encapsulation/information hiding; separation of interface and implementation; sufficiency, completeness, and primitiveness; and separation of concerns.
- Abstraction is "a view of an object that focuses on the information relevant to a particular purpose and ignores the remainder of the information" [1] (see Abstraction in the Computing Foundations KA). In the context of software design, two key abstraction mechanisms are parameterization and specification. Abstraction by parameterization abstracts from the details of data representations by representing the data as named parameters. Abstraction by specification leads to three major kinds of abstraction: procedural abstraction, data abstraction, and control (iteration) abstraction.
- Coupling and Cohesion. Coupling is defined as “a measure of the interdependence among modules in a computer program,” whereas cohesion is defined as “a measure of the strength of association of the elements within a module” [1].
- Decomposition and modularization. Decomposing and modularizing means that large software is divided into a number of smaller named components having well-defined interfaces that describe component interactions. Usually the goal is to place different functionalities and responsibilities in different components.
- Encapsulation and information hiding means grouping and packaging the internal details of an abstraction and making those details inaccessible to external entities.
- Separation of interface and implementation. Separating interface and implementation involves defining a component by specifying a public interface (known to the clients) that is separate from the details of how the component is realized (see encapsulation and information hiding above).
- Sufficiency, completeness, and primitiveness.Achieving sufficiency and completeness means ensuring that a software component captures all the important characteristics of an abstraction and nothing more. Primitiveness means the design should be based on patterns that are easy to implement.
- Separation of concerns. A concern is an "area of interest with respect to a software design" [8]. A design concern is an area of design that is relevant to one or more of its stakeholders. Each architecture view frames one or more concerns. Separating concerns by views allows interested stakeholders to focus on a few things at a time and offers a means of managing complexity [9].
2 Key Issues in Software Design
A number of key issues must be dealt with when designing software. Some are quality concerns that all software must address—for example, performance, security, reliability, usability, etc.
Another important issue is how to decompose, organize, and package software components. This is so fundamental that all design approaches address it in one way or another (see section 1.4, Software Design Principles, and topic 7, Software Design Strategies and Methods). In contrast, other issues “deal with some aspect of software’s behavior that is not in the application domain, but which addresses some of the supportingdomains” [10]. Such issues, which often crosscut the system’s functionality, have been referred to as aspects, which “tend not to be units of software’s functional decomposition, but rather to be properties that affect the performance or semantics of the components in systemic ways” [11].
A number of these key, crosscutting issues are discussed in the following sections (presented in alphabetical order).2.1 Concurrency
Design for concurrency is concerned with decomposing software into processes, tasks, and threads and dealing with related issues of efficiency, atomicity, synchronization, and scheduling.
2.2 Control and Handling of Events
This design issue is concerned with how to organize data and control flow as well as how to handle reactive and temporal events through various mechanisms such as implicit invocation and call-backs.
2.3 Data Persistence
This design issue is concerned with how to handle long-lived data.
2.4 Distribution of Components
This design issue is concerned with how to distribute the software across the hardware (including computer hardware and network hardware), how the components communicate, and how middleware can be used to deal with heterogeneous software.
2.5 Error and Exception Handling and Fault Tolerance
This design issue is concerned with how to prevent, tolerate, and process errors and deal with exceptional conditions.
2.6 Interaction and Presentation
This design issue is concerned with how to structure and organize interactions with users as well as the presentation of information (for example, separation of presentation and business logic using the Model-View-Controller approach). Note that this topic does not specify user interface details, which is the task of user interface design (see topic 4, User Interface Design).
2.7 Security
Design for security is concerned with how to prevent unauthorized disclosure, creation, change, deletion, or denial of access to information and other resources. It is also concerned with how to tolerate security-related attacks or violations by limiting damage, continuing service, speeding repair and recovery, and failing and recovering securely. Access control is a fundamental concept of security, and one should also ensure the proper use of cryptology.
3 Software Structure and Architecture
In its strict sense, a software architecture is "the set of structures needed to reason about the system, which comprise software elements, relations among them, and properties of both" [14*]. During the mid-1990s, however, software architecture started to emerge as a broader discipline that involved the study of software structures and architectures in a more generic way. This gave rise to a number of interesting concepts about software design at different levels of abstraction. Some of these concepts can be useful during the achitectural design (for example, architectural styles) as well as during the detailed design (for example, design patterns). These design concepts can also be used to design families of programs (also known as product lines). Interestingly, most of these concepts can be seen as attempts to describe, and thus reuse, design knowledge.
4 Software Structure and Architecture
4.1 Architectural Structures and Viewpoints
4.2 Architectural Styles
4.3 Design Patterns
4.4 Architecture Design Decisions
4.5 Families of Programs and Frameworks
5 User Interface Design
5.1 General User Interface Design Principles
5.2 User Interface Design Issues
5.3 The Design of User Interaction Modalities
5.4 The Design of Information Presentation
5.5 User Interface Design Process
5.6 Localization and Internationalization
5.7 Metaphors and Conceptual Models
6 Software Design Quality Analysis and Evaluation
6.1 Quality Attributes
6.2 Quality Analysis and Evaluation Techniques
6.3 Measures
7 Software Design Notations
7.1 Structural Descriptions (Static View)
7.2 Behavioral Descriptions (Dynamic View)
8 Software Design Strategies and Methods
There exist various general strategies to help guide the design process. In contrast with general strategies, methods are more specific in that they generally provide a set of notations to be used with the method, a description of the process to be used when following the method, and a set of guidelines for using the method. Such methods are useful as a common framework for teams of software engineers. (See also the Software Engineering Models and Methods KA).
7.3.
Object-Oriented
Design
[4*, c16]
Numerous software design methods based
on objects have been proposed. The field has
evolved from the early object-oriented (OO)
design of the mid-1980s (noun = object; verb
= method; adjective = attribute), where inheri
-
tance and polymorphism play a key role, to the
field of component-based design, where metain
-
formation can be defined and accessed (through
reflection, for example). Although OO design’s
roots stem from the concept of data abstraction,
responsibility-driven design has been proposed
as an alternative approach to OO design.
7.4.
Data
Structure-Centered
Design
[4*, c14, c15]
Data structure-centered design starts from the data
structures a program manipulates rather than from
the function it performs. The software engineer
first describes the input and output data structures
and then develops the program’s control structure
based on these data structure diagrams. Various
heuristics have been proposed to deal with special
cases—for example, when there is a mismatch
between the input and output structures.
7.5.
Component-Based
Design
(CBD)
[4*, c17]
A software component is an independent unit,
having well-defined interfaces and dependen
-
cies that can be composed and deployed inde
-
pendently. Component-based design addresses
issues related to providing, developing, and
integrating such components in order to improve
reuse. Reused and off-the-shelf software com
-
ponents should meet the same security require
-
ments as new software. Trust management is
a design concern; components treated as hav
-
ing a certain degree of trustworthiness should
not depend on less trustworthy components or
services.
8.1 General Strategies
Some often-cited examples of general strategies useful in the design process include the divide and-conquer and stepwise refinement strategies, top-down vs. bottom-up strategies, and strategies making use of heuristics, use of patterns and pattern languages, and use of an iterative and incremental approach.
8.2 Function-Oriented (Structured) Design
This is one of the classical methods of software design, where decomposition centers on identifying the major software functions and then elaborating and refining them in a hierarchical top-down manner. Structured design is generally used after structured analysis, thus producing (among other things) data flow diagrams and associated process descriptions. Researchers have proposed various strategies (for example, transformation analysis, transaction analysis) and heuristics (for example, fan-in/fan-out, scope of effect vs. scope of control) to transform a DFD into a software architecture generally represented as a structure chart.
8.3 Object-Oriented Design
8.4 Data Structure-Centered Design
8.5 Component-Based Design (CBD)
8.6 Other Methods
Other interesting approaches also exist (see the Software Engineering Models and Methods KA). Iterative and adaptive methods implement software increments and reduce emphasis on rigorous software requirement and design. Aspect-oriented design is a method by which software is constructed using aspects to implement the crosscutting concerns and extensions that are identified during the software requirements process. Service-oriented architecture is a way to build distributed software using web services executed on distributed computers. Software systems are often constructed by using services from different providers because standard protocols (such as HTTP, HTTPS, SOAP) have been designed to support service communication and service information exchange.
9 Software Design Tools
Software design tools can be used to support the creation of the software design artifacts during the software development process. They can support part or whole of the following activities:
- to translate the requirements model into a design representation;
- to provide support for representing functional components and their interface(s);
- to implement heuristics refinement and partitioning;
- to provide guidelines for quality assessment.
Matrix of Topics vs. Reference Material