Software is the set of programs, concepts, tools, and methods used to produce a running system on computing devices 1
We often think of software as a program that we execute; you’ve probably already written a large number of small programs. Every computer system consists of hundreds or thousands of very specialized, small-to-medium sized programs working in harmony to deliver a functioning system. No single program exists in isolation, and any programs that we write and execute depend on a number of other programs for their creation and operation. When we talk about “software”, we’re talking about a very broad category that includes:
- System software: programs written to provide services to other software. This includes operating systems, drivers, compilers and similar systems.
- Application software: programs written primarily for users, to help them solve a problem or perform a task, typically by manipulating and processing information. This includes text editors, messaging clients, productivity software, video games, graphing tools, computer-aided design and so on. This can span desktop, mobile, or even web-based applications.
In this course, we’re going to focus on application software, or software designed to solve tasks for people. This includes work and productivity software, games or other types of useful programs that people use everyday. e.g. software to manipulate numbers (Excel), compose documents (Word), write code (Vim) or entertain ourselves (League of Legends).
Although we will be writing self-contained software, we’ll also talk about full stack software.
Full-stack is an overloaded term in software development. Historically, it referred to the idea that an application often has a “front-end” (user interface) and a “back-end” (server, or process performing the actual computation). A full-stack developer in that context is someone who is capable of working on both “sides” of this boundary: the graphical front-end, and the back-end that does the “heavy lifting” of the application.
In modern-usage, we similarly use this term to refer to the ability to write code at different levels of the architectural stack. e.g. web-developers might use a mix of HTML/CSS/JS on the client-side and a more robust language like Java for a remote service. Modern applications often consist of multiple front-ends servicing different platforms e.g. desktop and mobile, and back-end services that provide data and other capabilities to these application layers.
Full-stack application development refers to designing and building applications that offer client-side functionality, but that can also leverage back-end services as required.
We’ll build full-stack applications in this course. In particular, we’ll build standalone applications to start, and then extend their functionality to leverage a remote service.
“Software development refers to a set of computer science activities dedicated to the process of creating, designing, deploying and supporting software."
– IBM Research
Software development then is the complete process of taking a software system from inception, through design, implementation and ultimately delivery to a customer. Software development consists of many interrelated activities across different discipline.
This is a course on software development in this broad-sense: going from initial requirements and working through the process to deliver a final product that someone can use and enjoy. Although we will focus most of our attention on the design + implementation of software, we want to consider how to address these other concerns as well.
Software is only useful if it solves a problem for someone. We cannot develop software in a vacuum.
We’ll consider a more formal process to developer software in the next chapter.
Software development can be seen as the convergence of math and computer science, engineering, arts and creative design. It’s inheritently multidisciplinary. It’s a unique discipline that can be creative and expressive, but still require formal mathematical rigor.
One central theme to this course is that there can be many different ways of determining what to build, or how to design something, or what the code should look like, based on your perspective.
Imagine that you’re part of a team building a product. What you consider important will be determined by your role, and your imemdiate concerns.
A designer might be concerned with the usability of a system for its users, and care about the user experience, aesthetics, branding and so on.
A programmer, trained in Computer Science might be concerned about functionality, scalability (designing a solution that can grow to handle more data), performance, readability of the code and so on.
A manager or project manager might be concerned with delivering a product on-time, and not going over budget.
A software engineer might be concerned with the quality of the product that’s being delivered, and the process that we use to ensure this.
These are all valid perspectives! Part of the challenge for you is knowing how to address all of these needs.
“How to program correctly” is a contentious topic. There is rarely/never a definitive practice that everyone agrees with and uses consistently. Part of the reason for this is that we are often working in new domains, and solving new or unique problems. Part of the reason is also probably because there are many, many different perspectives that emphasize the unique needs of the writer. How do you deal this? Look beyond the surface and don’t be afraid to use what works for you in your particular situation.
The growth of software systems has easily been the most pervasive technological advancement of the past 50 years. Software underpins most industries: banking, finance, transportation, manufacturing, research, education, retail. It is practically impossible to live and work in modern society without interacting with software systems on a daily basis2.
Keeping pace with the speed of technological advancements is challenging. The reality of software today3:
- Software has become embedded in virtually every aspect of our lives. The number of people who have an interest in the features and functions provided by a specific application has grown dramatically. Although software was once the domain of experts, this is no longer the case, as software is routinely used by consumers. We should strive to build software to meet the needs of all people.
- The information technology requirements demanded by individuals, businesses, and governments grow increasingly complex with each passing year. Large teams of people now create computer programs. Sophisticated software that was once implemented in a predictable, self-contained computing environment is now embedded inside everything from consumer electronics to medical devices to autonomous vehicles. Software is complex and pervasive. Design is a critical activity to ensure that we address requirements and build the “right thing”.
- Individuals, businesses, and governments increasingly rely on software for strategic and tactical decision making as well as day-to-day operations and control. If the software fails, people and major enterprises can experience anything from minor inconvenience to catastrophic consequences. Software should be high-quality, safe and reliable.
- As the perceived value of a specific application grows, the likelihood is that its user base and longevity will also grow. As its user base and time in use increase, demands for adaptation and enhancement will also grow. Software should be adaptable and scalable.
[Tracy 2019] attributed to John Tukey in 1958. ↩︎
I’m writing this on a notebook computer, while wearing a smartwatch, with a smartphone in my pocket, a tablet on the table beside me and my speaker streaming music over the Internet. The amount of computing power at our disposal is astonishing. Also, I have too many gadgets. ↩︎
[Pressman & Maxim 2020]. ↩︎