Any fool can write a program that the computer can understand. It takes a good programmer to write a program that other people can understand.
- Martin Fowler.
Software design is, broadly speaking, the activity of sitting around thinking about how you are going to structure the computer program that you are about to write. Often this design is done while thinking about what a pain it is to work on the current project's code base, and how those mistakes are going to be rendered impossible in future by the new design.
Alternately you can do software by experimentation, by hacking up some code, and refactoring it until it looks optimal for the task at hand.
Software design does not directly refer to the way that the program looks to the user - that is Interface design. Software design refers to the internals of the program, the source code. However those internals must allow the front end to exist, and so are severely constrained by it.
An enormous number of structured methodologies, techniques and vocabularies have been brought to bear on software design, but it still remains an art or a craft, not a science. IT is still governed by experience, gut feel and rules of thumb. Some of the most successful aids developed so far are UML, design patterns and refactoring. Modern programming languages are arguably also aids to good design, nudging programmers in the right directions with features such as modularisation, object orientation and strong typing.
Software design, as opposed to the de facto design resulting from unplanned construction, aims to produce readable, maintainable, flexible, robust and elegant code by forethought about the structure of the program constructed. The more ambitious the program, the more forethought is needed.
I do not regard software design as completely separated from software construction. Each procedure implemented involves some decisions about how it will behave; and design decisions taken in vacuum, without the reality checks of implementation, may not work as well as intended.
Software design is concerned with programming on a larger scale than how to phrase a single line of code. It aims to make the large-scale structure of a system understandable by means of consistently used metaphors. It adds an aesthetic. In order to make good software, it is often necessary to create one or more levels of abstraction between the vocabulary of the problem domain and the vocabulary of the programming language. Doing this, and doing it well, is software design.
See also:
- Software development is not an engineering discipline
- Structured Programming, Cohesion and coupling
- Learn to Program: Philosophies of Coding
- Good programmers, What it takes to be a good programmer, virtues of a good programmer
- The Art of Computer Programming, Programming as art, The Art of Unix Programming
- Code Complete
- Program Design
- Design patterns and antipatterns, Ball of Mud
- Object Oriented Design Principles, Law of Demeter
- Refactoring, Extreme Programming, Manifesto for Agile Software Development and design debt
- Unified Modeling Language, The Unified Software Development Process
- Martin Fowler, Kent Beck, Gang of Four, the three amigos
- Specification, business specification
- Software Engineering, methodology
- Rapid application development
- good design, The three golden rules of user interface design, User Centered Design, Interface design
- Any I've forgotten?