Software design

Software design is concerned with how you assemble lines of code. It is about the structure of classes, functions, and modules within a single codebase.

Software design is distinct from system design, which is concerned with how you assemble services. System design is about the structure of a distributed system’s components, interfaces, data access, and network boundaries.

Both software design and system design are closely related to software architecture. The commonly-cited distinction is that architecture is concerned with design decisions that are expensive to change later. Architectural decisions include how services are partitioned and how data is distributed. Software design is more local and recoverable. However, all three sit on a spectrum with no clear boundary between them, and the terms are often used interchangeably.

High-level design and low-level design are also commonly used as synonyms for software architecture and software design respectively.

Within a single codebase, software design plays out through design principles such as preferring cohesion over coupling, and through use of reusable design patterns that solve recurring structural problems.

Modular design – organizing code into self-contained modules with narrow public interfaces – is one of the central concerns of software design.