Software Design
After requirements are defined for a software system, developers start working on a design. The goal of a software design is to decide on the structure of the software and the hardware configurations that support it. There are three main levels of software design: architecture, high-level design (HLD), and low-level design (LLD). All software designs model the structure of a system. The structure includes components, interfaces, and relationships. We use several diagrams to support the analysis model of the requirements and our representation of a software design. The diagrams, and other software artifacts related to design, will be detailed further below.
Software design evolves over time and may be refined as designers learn more about the system. A well-formed design provides functionality for the software system described in the requirements. A class in an object-oriented design should be complete and sufficient for the appropriate encapsulation of the class’ state and behaviors. Additionally, each class should be focused on one idea, abstraction, or service and the behaviors of the class should be cohesive and support that single responsibility. Finally, a class should have low coupling or minimize it’s collaborations or relationships with other classes. If classes in a software system are highly coupled, in that they have relationships with all other classes in the system, then the system is vulnerable to failures when one component of the system changes. Software systems with low coupling are more resilient to changes.
When creating a software design, you want to understand the requirements so that you know how the application will be used. The design of a stand-alone application is very different from the design of a web application.
Architecture
Architecture provides a representation or abstraction of a software system at a very high-level. The architecture can characterize a software system and provides a common language for communication. There are several common architectures:
- Data-Centered: All components of the system interact with a common data repository, typically a relational database.
- Call and Return: Components consist of subprograms invoked through a main program. Subprograms may invoke other subprograms forming a hierarchical or tree structure.
- Layered: Components are layered by their functionality. Most web applications use a layered architecture.
- Model-view-controller: Components are divided into the model (e.g., business logic), the view (e.g., the user interface), and the controller (e.g, the connection between the view and model). Model-view-controller architectures are also common in web applications.
All applications developed in CSC216 are stand-alone Java applications that use the model-view-controller (MVC) architecture. Since we are developing in Java, the view and controller are tightly coupled. That means they are represented in a single class which is the GUI class. The view is the look and feel of the application and includes the standard form components and the layout of those components. The controller portion of the GUI class are the methods that are executed when a component, like a button, is interacted with by the user. When a button is clicked the controller method will call a method in the underlying model. We typically have a class that represents the overarching model of the system that the controller methods interact with. The overarching model class will then delegate to the other classes in the system as appropriate for their abstraction.
High-level Design
High-level design describes the modules or packages that make up a software system. In Java, related classes are grouped together in packages. On the file system, a package is nothing more than a directory structure. However, in Java, the package identifies where a class exists and the top level portion of the package names the project.
Most package names follow the pattern <organization type>.<organization name>.<department or group>.<product name>. For our class, packages are named:
1
2
3
4
edu. //We're an educational organization
ncsu. //We're NC State!
csc216. //The class is csc216
project_name //The name of the current project
From there, we create sub packages that describe high-level features of the project. Common package names you might see are:
uiorgui: contains user interface classes that are the view/controller of the project.model: contains model elementsio: contains classes that perform file or console input and/or output (e.g., I/O)
Other package names will be more specific to the project. For example, in WolfScheduler, there is a package for the courses and a package for scheduler.
Low-level Design
For object-oriented systems, low-level design describes the classes, including their state and behaviors, and the relationship between those classes. Our low-level design must conform to the model-view-controller architecture and the classes will each belong to a package described in the high-level design. When creating a low-level design, we start by discovering classes and their state. The next step is to determine the responsibilities of each class. Finally, we describe the relationships between each class.
We can represent our low-level design using a class diagram.
There are several other diagram types that describe low-level design.
- Control-flow Diagrams: Control-flow diagrams model the flow-oriented elements of a software system. Control-flow diagrams can model the flow of control between methods or within a method and may be used to estimate the number of unit tests needed to fully exercise all paths in a method.
- State Diagrams: State diagrams describe the behavioral elements of a software system. State diagrams are frequently used to model finite state machines and show how inputs to the system can change the internal state of a class. State diagrams are typically implemented using the State Pattern.
- Sequence Diagrams: Sequence diagrams describe the behavioral elements of a software system by modeling the call chain of methods for a scenario. A scenario is a single path through a use case; black box tests are scenarios exercised against the system to evaluate if the validity of the software. A sequence diagram models a series of method calls and returns for a given scenario.
