* * Software design **
After the software requirements are determined, the software design stage is entered. Software design is an important stage of software engineering. The basic purpose of software design 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, consider actual conditions, and transform them into technical solutions that meet the requirements of the software system, laying the foundation for the next stage of software implementation.
* * Software design overview **
Software design is a critical stage in the software development process that determines the quality of software products. The decisions made during the software design phase will ultimately determine whether software development can be successful. More importantly, these design decisions will determine the difficulty of software maintenance.
Software design activities are the most important part of obtaining high-quality, low-cost, and easy-to-maintain software. Its main purpose is to draw a blueprint for the software, weigh and compare the advantages and disadvantages of various technologies and implementation methods, rationally allocate various resources, build detailed plans and related models of the software system, and guide the smooth development of software implementation.
Software design is the beginning of the development period and is related to the quality of the entire software development period. The information flow during the software development period describes the function of software design from software requirements to software coding, and plays a connecting role, as shown in Figure 5 - 1.

Figure 5 - 1 Information flow during software development
* * 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 according to the functions determined in the requirements analysis stage, divide functional modules, determine the implementation algorithm of each module, and form a specific software design plan. Software design is a creative activity that is considered from different perspectives in the designer's plan, such as how the software meets customer needs, how it can be easily implemented, and how it can be easily expanded to adapt to new needs.
From the perspective of software engineering, software design is generally divided into two stages: summary design and detailed design, as shown in Figure 5 - 2. Depending on the size and complexity of the software project, summary design and detailed design can be merged into the software design phase, or it can be iterated repeatedly until the software requirements are fully realized.

Figure 5 - 2 Division and tasks of software design stages
* * Outline design **
Summary design is also called overall design. Starting from the work results of the requirements analysis stage, it clarifies the optional technical solutions, does the preliminary work of dividing the software structure, and then divides the physical elements that make up the system, and carries out software architecture design, data design and user interface design.
The main participants in the summary design are software analysts, users, software project managers and relevant technical experts. Software analysts complete the physical plan and final software structure design of the target system; users participate in the evaluation and final approval of the system's physical plan and final software structure; software project managers participate in the evaluation of the system physical plan and software structure designed by the software analysts, and provide guidance to the software analysts in their design work; relevant technical experts mainly participate in the evaluation of the system physical plan and software structure designed by the software analysts.
The main tasks of summary design are to complete architecture design, data design and user interface design.
1)Architecture design. Determine the data transfer and call relationships between various subsystem modules. In the theme division of structured design, classes and relationships between classes are mainly determined. 2)Data design. Data design includes the definition of databases, data files, and global data structures. In structured design, a data model is established through the entity-connection diagram and data dictionary in the requirements stage. In object-oriented design, the data design process is completed through the abstraction and instantiation of classes, as well as the permanent storage design of classes. 3)User interface design. Including the design of the human-machine interface to interact with the system, as well as the interface relationships between modules, 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 not only meet the unification of human-computer interaction interface data, but also complete the transfer of data between classes.
* * Detailed design **
The task of detailed design is to implement the details of each part based on the summary design until all content of the system has a sufficiently detailed process description, so that the task of coding is to "translate" the content of the detailed design into the programming language. To be precise, the task of detailed design is to complete the process design.
Process design includes determining the specific implementation process and local data structure within each software module. In structured design, module independence constrains the separation of data structures and algorithms, making the two must be local when designing and reducing external influence on the two. In object-oriented design, the encapsulation of classes better reflects the internality of algorithms and data structures. Class inheritance provides a mechanism for multiple classes (class families) to jointly implement process design.
* * Software design principles **
As software development technology continues to advance, some good design principles are constantly being proposed to guide the software design process and ensure software quality.
(1) Divide and conquer: Divide and conquer is the strategy used to solve large, complex problems. Divide a large problem into a number of small problems, and transform the solution of a large problem into a number of small problems, which greatly reduces the complexity of the problem. Modularization is a technical means for software design to realize the idea of divide and rule. In structured design, modules can be functions, procedures, or even code fragments. In object-oriented design, classes are the main form of modules.
(2) Reuse design pattern: Reuse refers to a mechanism whereby the same thing can be used multiple times without modification or minor changes. Since the summary design completes the system software structure, the content that is reused is the software design pattern. Software design patterns target a type of software design process and model, rather than facing a specific software design. By reusing design patterns, not only can the quality of software design be guaranteed, but resources are also concentrated in new processes and new methods in design, and the reuse of new processes and new methods in the future is further considered during design.
(3) Traceability: One of the tasks of software design is to determine the relationships between various parts of the software. Because designing the system structure is to determine the mutual call or control relationship between various parts of the system and modules, so that when it is necessary to modify the module, we can grasp other parts related to the modification module and correctly trace the root cause of the problem.
(4) Flexibility: Design flexibility mainly refers to the ease of modification of the design. Modifications include additions, deletions, and changes to existing designs. The main reasons for modification are: user requirements change, design defects exist, design needs to be optimized, design reuse.
Software design flexibility is mainly embodied by abstracting system description problems. Abstract is a unified description of the same attributes or operations of things, with universality. Therefore, the more abstract the system design and design patterns, the greater the coverage. For example, the abstraction of "bird" to "sparrow" not only reflects the flying characteristics of sparrow, but also covers the explanations of other birds. But abstraction is a "double-edged sword", and excessive abstraction will cause difficulties in understanding and design. If "creature" is used to abstract the "sparrow" entity, many characteristics of a horse will be difficult to define in "creature".
(5) Consistency: Consistency is reflected in software design methods and processes. In software design, the consistency of interface views ensures user experience and loyalty to the system. For example, although the interface of the Windows operating system has undergone changes in multiple versions, the user's operating methods have remained basically unchanged. Standardize module interface definitions with unified rules and constraints to ensure unified operation of interfaces and data structures during the encoding stage, reduce ambiguity in data understanding, and ensure software quality.
(6)Reliability: Design should run through all aspects of functional design. While meeting basic functions, various factors affecting reliability must be comprehensively considered. During design and implementation, the software architecture design should be reasonable, minimize the coupling between modules, and improve system fault tolerance, so that when a single module fails, it will affect other modules and even the entire system. In addition, the principle of simultaneous development and testing should be followed during the software development process, real-time testing and discovery of problems, and repeated verification to reduce risks and improve software reliability.
(7) Extensibility: The design and implementation of software ensure that the functional boundaries of modules are clear, and a unified standard input and output interface is used to facilitate the horizontal expansion of software-related services. The data types, sub-functions and operation interfaces contained in the modules are independently compiled dynamic libraries, which is conducive to Vertical expansion of software-related services.
(8) Maintainability: During design and implementation, each configuration item of the software shall provide complete log records (including process logs and exception logs, etc.), and there shall be clear exception information prompts when software errors occur. All fault states and information should be automatically recorded and stored to facilitate subsequent fault countermeasures.
Improving software design and improving software quality needs to follow the following principles.
1)High module independence
After designing the preliminary structure of the software, modules should be further decomposed or merged to reduce coupling and improve cohesion. For example, a sub-function common to multiple modules can independently define a module and be called by those modules; sometimes modules can be decomposed or merged to reduce the transfer of control information and references to entire data, and reduce the complexity of the interface.
2)Moderate module size
Large modules are often caused by insufficient decomposition, but further decomposition must conform to the problem structure. Generally, module independence should not be reduced after decomposition. Too small a module costs more than effective operations, and too many modules will complicate the system interface. Therefore, a module that is too small is sometimes not worth living alone, especially when only one module calls it, and it can often be merged into the superior module without having to exist alone.
3)Depth, width, fan-out and fan-in Appropriate depths represent the number of layers controlled in the software structure and can roughly indicate the size and complexity of a system, such as
Figure 5 - 3 shows it. There should be a rough correspondence between it and the length of the program, but of course this correspondence changes within a certain range. If there are too many layers, you should consider whether many management modules are too simple and need to be merged appropriately. Width is the maximum number of modules at the same level within the software structure. Generally, the larger the width, the more complex the system. The factor with the greatest impact on width is the fan-out of the module.

Figure 5 - 3 Terms related to software structure