Software design is the process of creating a specification for a software with the intention of achieving certain goals. It involves using basic components and adhering to certain constraints.
The term can also refer to the overall activities of conceptualizing, framing, implementing, commissioning, and modifying the software. This encompasses problem-solving, planning, and designing both the low-level components and algorithms, as well as the high-level architecture.
Software Design Basics
Software design is the process of envisioning and defining software solutions to solve problems. An important aspect of software design is software requirements analysis (SRA), which involves listing specifications used in software engineering.
When designing software that is “semi-automated” or user-centered, user experience design plays a role in determining these specifications through storyboarding. For software that is completely automated, the design can be as simple as a flow chart or descriptive text outlining the planned sequence of events.
There are various methods like Unified Modeling Language and Fundamental modeling concepts that can be used. Regardless of the approach, documentation of the design plan is typically produced.
Additionally, a software design can be platform-independent or platform-specific, depending on the technology used for the design.
The key distinction between software analysis and design is that analysis breaks down the problem into smaller parts to solve, while design is more about the capabilities and can have multiple approaches. The analysis process should be consistent among team members, whereas design can vary depending on the environment, such as using established frameworks or design patterns.
Some examples of design include:
Principles of Software Design
Software design includes both a process and a model. The design process involves a series of steps that allow the designer to describe all aspects of the software being built. Critical success factors for an effective design include creativity, past experience, understanding what makes software “good,” and an overall commitment to quality.
However, the design process is not always straightforward; it can be likened to an architect’s plans for a house. Initially, the design represents the entire structure (like a three-dimensional rendering of the house), and then it gradually refines to provide guidance for building each specific detail (such as the plumbing layout).
Similarly, the software design model offers different views of the computer software, and following basic design principles helps software engineers navigate the design process.
To ensure a good software design, the following basic principles and concepts should be considered:
- Consider different approaches and evaluate them based on problem requirements and available resources.
- Ensure the design can be linked back to the analysis model to track how requirements are addressed.
- Avoid reinventing the wheel by utilizing existing design patterns instead of starting from scratch.
- Aim to minimize the gap between the software and the real-world problem by aligning their structures.
- Strive for uniformity and integration in the design by establishing style and format rules and defining clear interfaces between components.
- Design should be flexible to accommodate changes.
- Design should gracefully handle aberrant data or conditions without crashing.
- Differentiate between design and coding; the design model should have a higher level of abstraction than the source code.
- Assess design quality during the development process, not retrospectively.
- Review design to minimize conceptual errors, focusing on key elements before nitpicking the details.
Software Design Concepts
Design concepts play a vital role in software development. They provide a foundation for applying more advanced methods. Here are some fundamental design concepts:
- Abstraction: It involves generalizing and focusing on essential features while excluding unnecessary details.
- Refinement: The process of elaborating on functions by breaking them down into smaller, more detailed instructions.
- Modularity: The software architecture is divided into modules or components.
- Software Architecture: It encompasses the overall structure of the software, ensuring conceptual integrity. Effective software architecture leads to positive project outcomes in terms of performance, quality, schedule, and cost.
- Control Hierarchy: Represents the organization of program components and establishes a hierarchy of control.
- Structural Partitioning: Divides the program structure both horizontally and vertically, creating modular branches for different program functions.
- Data Structure: Represents the logical relationship between individual data elements.
- Software Procedure: Focuses on the individual processing of each module.
- Information Hiding: Ensures that modules are designed in a way that restricts access to their internal information from other modules that don’t require it.
Grady Booch’s object model emphasizes Abstraction, Encapsulation, Modularization, and Hierarchy as fundamental design principles. These principles are sometimes referred to as PHAME (Principles of Hierarchy, Abstraction, Modularization, and Encapsulation).
Considerations When Designing Software
When designing software, there are several important considerations to keep in mind. The significance of each consideration should align with the goals and expectations of the software. Some key aspects include:
- Compatibility: The software should be able to work smoothly with other products, even those designed for previous versions.
- Extensibility: The ability to add new features to the software without making significant changes to the underlying structure.
- Modularity: Breaking down the software into independent components, enhancing maintainability and allowing for easier implementation and testing.
- Fault-tolerance: Ensuring that the software can handle component failures and recover from them.
- Maintainability: How easily the software can be updated or modified to fix bugs or introduce new functionalities. Achieving high maintainability is often a result of modularity and extensibility.
- Reliability: Ensuring the software can perform its intended function consistently over a specified period, under specific conditions.
- Reusability: The ability to use parts or all of the existing software in other projects with minimal modifications.
- Robustness: The software’s ability to withstand stress, tolerate invalid input, and operate reliably even under unpredictable circumstances.
- Security: Implementing measures to protect the software from malicious acts and influences.
- Usability: Creating a user-friendly interface tailored to the target audience, with default values that work well for most users.
- Performance: Ensuring that the software performs tasks within acceptable time frames and doesn’t excessively drain system resources.
- Portability: Designing software that can function effectively across a variety of conditions and environments.
- Scalability: Ensuring the software can handle increasing data, added features, or a growing number of users without compromising performance.
Graphical Modeling Languages
A modeling language is a defined artificial language used to express information, knowledge, or systems with consistent rules. These languages can be graphical or textual. Some examples of graphical modeling languages for software design include:
- Architecture Description Language (ADL): Describes and represents the software architecture of a system.
- Business Process Modeling Notation (BPMN): Used for process modeling.
- EXPRESS and EXPRESS-G: An international standard for general-purpose data modeling.
- Extended Enterprise Modeling Language (EEML): Commonly used for business process modeling.
- Flowcharts: Schematic representations of algorithms or step-wise processes.
- Fundamental Modeling Concepts (FMC): A modeling language for software-intensive systems.
- IDEF: A family of modeling languages, such as IDEF0 for functional modeling, IDEF1X for information modeling, and IDEF5 for ontology modeling.
- Jackson Structured Programming (JSP): A method for structured programming that connects data stream structure with program structure.
- LePUS3: An object-oriented visual Design Description Language and formal specification language primarily used for modeling large object-oriented programs (Java, C++, C#) and design patterns.
- Unified Modeling Language (UML): A general modeling language used to describe software structure and behavior, featuring a graphical notation and extension capabilities with Profiles.
- Alloy: A general-purpose specification language for expressing complex structural constraints and behavior in software systems, based on first-order relational logic.
- Systems Modeling Language (SysML): A general-purpose modeling language specifically designed for systems engineering.
- Service-oriented Modeling Framework (SOMF): A modeling framework for service-oriented architectures.
Design patterns are solutions to common design problems in software development that have been previously identified and solved by others. By reusing these patterns, software designers and architects can expedite the development process.
Designing the Design
One challenge in software design is that the source code essentially represents the design of the program it generates. Therefore, “software design” can refer to designing the design itself. This layering of semantic levels in programming is often considered a unique aspect.
The importance of active participation in the initial implementation must be emphasized. The implementation process leads to unexpected questions and insights that improve the original specifications. Merely specifying a program without active involvement in its implementation will often result in failure.
Software design documentation can be reviewed and presented to accommodate changes in constraints, specifications, and requirements before starting the actual programming. After reviewing a simulated or prototype version, redesigning may be necessary.
While it is possible to design software during the programming process without prior planning or requirement analysis, this approach is not feasible for complex projects. Conducting a separate design phase before programming allows collaboration between multidisciplinary designers and subject-matter experts (SMEs) with skilled programmers, resulting in software that is both functional and technically sound.