Software Design
After software requirements are finalized, the process moves into the software design phase. Software design is a critical stage in software engineering. Its fundamental purpose is to answer the question "How should the system be implemented?" The task of software design is to transform the functional elements specified in the software requirements specification into a technical solution that meets the software system requirements, considering actual conditions, thereby laying the foundation for the subsequent software implementation phase.
Overview of Software Design
Software design is a key stage in the software development process that determines the quality of the software product. Decisions made during the software design phase ultimately determine the success of software development and, more importantly, these design decisions dictate the ease of software maintenance.
Software design activities are the most crucial环节 for obtaining high-quality, low-cost, and easily maintainable software. Its main purpose is to create a blueprint for the software, weigh and compare the pros and cons of various technologies and implementation methods, allocate resources reasonably, build detailed plans and related models for the software system, and guide the smooth progress of software implementation.
Software design is the starting phase of the development period and affects the quality of the entire software development period. The information flow during the software development period describes how software design connects software requirements to software coding, serving as a bridge, as shown in Figure 5-1.

Figure 5-1 Information Flow During the Software Development Period
Tasks of Software Design
The task of software design is to start from the software requirements specification, design the overall structure of the software system based on the functions determined during the requirements analysis phase, divide functional modules, determine the implementation algorithm for each module, and form the specific design plan for the software. Software design is a creative activity in which the designer considers different perspectives, such as how the software meets customer needs, how it can be easily implemented, and how its functionality can be conveniently extended to accommodate new requirements.
From a software engineering perspective, software design is generally divided into two stages: high-level design (architectural design) and detailed design, as shown in Figure 5-2. Depending on the size and complexity of the software project, high-level design and detailed design can be merged into a single software design phase or iterated repeatedly until all software requirements are fully realized.

Figure 5-2 Division and Tasks of Software Design Stages
High-Level Design (Architectural Design)
High-level design, also known as overall design, starts from the results of the requirements analysis phase, clarifies feasible technical solutions, performs preliminary work to divide the software structure, then partitions the physical elements composing the system, and carries out software architecture design, data design, and user interface design.
The main participants in high-level design include software analysts, users, software project managers, and relevant technical experts. Software analysts complete the physical scheme and final software structure design for the target system; users participate in the evaluation and final approval of the system's physical scheme and final software structure; software project managers participate in evaluating the system physical scheme and software structure designed by the software analysts and guide their design work; relevant technical experts mainly participate in evaluating the system physical scheme and software structure designed by the software analysts.
The main tasks of high-level design are to complete architecture design, data design, and user interface design.
- Architecture Design: Determine the data transfer and calling relationships among subsystems and modules. Under the structured design theme division, mainly determine classes and relationships between classes.
- Data Design: Data design includes the definition of databases, data files, and global data structures. In structured design, data models are established through entity-relationship diagrams and data dictionaries from the requirements phase. In object-oriented design, the data design process is completed through class abstraction and instantiation, as well as the design of persistent storage for classes.
- User Interface Design: Includes the design of the human-computer interaction interface with the system, as well as the interface relationships between modules, and between the system and external systems. In structured design, module interfaces and global data structures are defined based on data flow entries. In object-oriented design, association classes, interface classes, boundary classes, etc., are defined to satisfy the uniformity of human-computer interaction interface data and to complete data transfer between classes.
Detailed Design
The task of detailed design is to concretely implement the details of each part based on the high-level design, until all contents of the system have sufficiently detailed process descriptions, making the coding task essentially "translating" the content of the detailed design into a programming language. Specifically, the task of detailed design is to complete process design.
Process design includes determining the specific implementation process and local data structures within each software module. In structured design, module independence constrains the separation of data structures and algorithms, ensuring that both are designed with locality to reduce external influence on them. In object-oriented design, class encapsulation well reflects the internality of algorithms and data structures. Class inheritance provides a mechanism for multiple classes (a class family) to implement process design collectively.
Software Design Principles
With the continuous advancement of software development technology, many good design principles have been proposed and guide the software design process to ensure software quality.
(1) Divide and Conquer: Divide and conquer is a strategy used to solve large-scale, highly complex problems. By dividing a large problem into several small problems, solving a large problem is transformed into solving several small problems, greatly reducing the problem's complexity. Modularization is the technical means to implement the divide-and-conquer idea in software design. In structured design, modules can be functions, procedures, or even code snippets. In object-oriented design, classes are the main form of modules.
(2) Reuse of Design Patterns: Reuse refers to the mechanism where the same thing can be used multiple times without modification or with slight modifications. Since high-level design completes the system software structure, the content reused is software design patterns. Software design patterns target the process and model of a class of software designs, not a specific software design. By reusing design patterns, not only is software design quality guaranteed, but resources are also concentrated on new processes and methods in the design, and further consideration is given to the future reuse of these new processes and methods.
(3) Traceability: One of the tasks of software design is to determine the relationships among the various parts of the software. Because designing the system structure involves determining the mutual calling or control relationships among the parts and modules of the system, so that when a module needs to be modified, the other parts related to the modified module can be grasped and the root cause of the problem can be correctly traced.
(4) Flexibility: Design flexibility mainly refers to the ease of modification of the design. Modifications include activities such as adding, deleting, and altering the existing design. The main reasons for modifications include changes in user requirements, defects in the design, the need to optimize the design, and the use of reuse in design.
The flexibility of software design is mainly reflected through the abstraction used to describe system problems. Abstraction is a unified description of the same attributes or operations of things, with broad applicability. Therefore, the higher the degree of abstraction in system design and design patterns, the larger the scope they cover. For example, the abstraction of "bird" from "sparrow" not only embodies the characteristic that sparrows can fly but also covers descriptions of other birds. However, abstraction is a "double-edged sword"; excessive abstraction can cause difficulties in understanding and design. For instance, if "living being" is used to abstract the "sparrow" entity, many characteristics of a bird would be difficult to define within "living being."
(5) Consistency: Consistency is reflected in both software design methods and processes. In software design, the consistency of interface views ensures user experience and system loyalty. For example, although the Windows operating system interface has undergone multiple version changes, the basic user operation methods have remained largely unchanged. Unifying rules and constraints to standardize module interface definitions ensures uniform operations on interfaces and data structures during the coding phase, reduces ambiguity in data understanding, and guarantees software quality.
(6) Reliability: Design should be贯穿 throughout all aspects of functional design. While meeting basic functionality, it must comprehensively consider various factors affecting reliability. During design and implementation, software architecture should be reasonably designed to minimize coupling between modules and improve system fault tolerance, so that a single module failure does not affect other modules or the entire system. Furthermore, during the software development process, the principle of synchronous development and testing should be followed, with real-time testing and problem discovery, repeated verification, risk reduction, and improved software reliability.
(7) Extensibility: The design and implementation of software should ensure clear module boundaries, use standardized input/output interfaces, facilitate horizontal expansion of related software business, and ensure that data types, sub-functions, and operation interfaces contained in modules are independently compiled into dynamic libraries, facilitating vertical expansion of related software business.
(8) Maintainability: During design and implementation, each software configuration item should provide complete log records (including process logs and exception logs, etc.), and there should be clear exception information prompts when software errors occur. All fault states and information should be automatically recorded and stored for subsequent fault countermeasure analysis.
Improving software design and enhancing software quality requires adherence to the following principles.
- High Module Independence
After designing the initial software structure, further decomposition or merging of modules should be performed to reduce coupling and increase cohesion. For example, a sub-function shared by multiple modules can be defined as an independent module and called by these modules; sometimes, decomposition or merging of modules can reduce the transmission of control information and references to global data, and lower the complexity of interfaces.
- Appropriate Module Size
Large modules often result from insufficient decomposition, but further decomposition must conform to the problem structure; generally, decomposition should not reduce module independence. Very small modules have overhead greater than their effective operations, and too many modules will make the system interface complex. Therefore, very small modules are sometimes not worth existing independently, especially if they are only called by one module; they can usually be merged into the parent module without existing separately.
- Appropriate Depth, Width, Fan-out, and Fan-in
Depth represents the number of levels of control in the software structure and can roughly indicate the size and complexity of a system, as shown in Figure 5-3. There should be a rough correspondence between depth and program length, although this correspondence varies within a certain range. If there are too many levels, consider whether many management modules are overly simple and need to be merged appropriately. Width is the maximum number of modules at the same level within the software structure. Generally, a larger width indicates a more complex system. Module fan-out has the greatest impact on width.

Figure 5-3 Software Structure Related Terminology