Learning Objectives
By the end of this section, you will be able to:
- Describe the intent of software engineering and how it relates to computer science
- Recognize various categories of software
- Identify the skills that are required for a software engineer
This section introduces software engineering along with the challenges associated with the creation and evolution of software. The various fundamental facets of software engineering are presented including the skills required to properly engineer software and the role that a software engineer is expected to play within a software team.
The Intent of Software Engineering
The IEEE1 defines software engineering as the application of a systematic, disciplined, quantifiable approach to the development, operation, and maintenance of software; that is, the application of engineering to software. It is important to understand how software engineering fits into the larger context of computer science. It is also important to understand the role of a software engineer and how it fits within an organization.
The reference to “a systematic, disciplined, quantifiable approach” does not mean a bureaucratic, document-laden approach. Software engineering relies on various methodologies/processes, methods and tools that may be used to professionally develop and maintain quality software while optimizing the use of resources such as time and cost. Selecting the right processes and methods for a project and using tools to accelerate the ongoing development of a solution is challenging especially when requirements are changing and many software developers are working together to tackle a large project. Part of the issue is that software engineering as a process cannot (in general) be fully automated and therefore it is difficult to keep all the activities aligned with the end goal of delivering a solution on time and within budget.
Selecting and tailoring software engineering processes and methods as well as using the right tools in the right fashion to meet this end goal, which in essence defines a majority of what a software engineer does, is covered in detail as part of this chapter.
Concepts In Practice
Software and Our Daily Lives
Software is everywhere, and most of us interact with a software system on a daily basis. Yet the importance of software is expected to grow even greater in the coming decades. Although most software revenue comes from a generic software, software systems tailored to specific needs can be found everywhere, from our cars to our smartwatches. Thus, quite a few of us can expect that we will be involved as customers in some software engineering process during our professional lives. People who are familiar with concepts of software engineering can better oversee the projects they are working on by interacting with customers so their needs are clearly specified and by working with developers to smooth out the development process and ensure the final product meets customers’ expectations.
Software Engineering Teams
In most organizations, software is developed by a team of software engineers, as well as other people with different backgrounds and skills. To be effective, the project team must be organized in a way that maximizes the use of each person’s skills and abilities and emphasizes the importance of teamwork to address all the aspects of the projects. This is especially true for complex projects. Effective project managers focus on problem-solving and end-product quality, and thus they may organize software teams in a variety of ways. The key factors considered when selecting a team organizational model are as follows:
- difficulty of the problem to be solved
- degree to which the problem can be modularized
- required quality, reliability, and other nonfunctional requirements of the system to be built
- delivery date
- budget limitations
- team lifetime (i.e., overall period of time during which the team members will work together)
During the creation of a software solution, software engineer team members may take on various roles, such as:
- project manager, who is responsible for making sure that the project gets completed on time and on budget
- enterprise or solution portfolio architect, who makes high-level design decisions on high-level modeling or solution design building blocks and their interconnections to best address functional requirements as well an nonfunctional ones such as performance and usability
- user experience (UX) designer, who plans how users will interact with the software system; this involves tasks like designing the user interface (UI), making wireframes and prototypes, and conducting user testing to ensure the software is user-friendly and meets user needs
- software developer, who analyzes requirements, refines the design, writes and tests code, and collaborates with the operations team to deploy the software into testing and production environments
- quality assurance tester, who checks for bugs and validates that the system meets the requirements
It is common for one team member to act in several roles (for example, a solution architect might also be a software developer), and some roles may be filled by multiple team members (for example, there are typically multiple software developers on a project). Additionally, a software engineer may work directly with other people, including:
- product owners, who are generally project sponsors and provide the requirements and overall guidance on what is expected from the solution
- subject matter experts (SMEs), who are specialists in areas such as business, technology, products, or other topics as needed
- database administrators, who focus on areas such as data storage, organization, and access associated with a software solution
- operations specialists, who are IT and/or DevOps professionals with a focus on computer hardware and software operations
Because projects can involve a large number of people working in many different roles, communication and interaction among team members is critical for a project to succeed. To keep the team running smoothly, projects are ideally structured so they include the following:
- deadlines that provide sufficient time for team members to fully complete their tasks and ensure results that match the requirements
- standards for how business and technology decisions are made to avoid business or technology-related disagreements
- processes and procedures that make it easy for team members to coordinate their activities
- clear definitions of each team members’ role and authority so that everyone knows who is accountable for each task and where questions should be directed
Cost Management
An important part of the role of a software engineer is to handle the project management triangle of timeliness, quality, and cost. The goal is to deliver projects as quickly as possible with the highest quality and the lowest cost. Doing this requires good communication, planning, and focus as well as the setting of realistic expectations. Furthermore, because the cost of maintaining a software solution over time can be significant, various cost-management strategies must be used to manage costs effectively. These strategies include the use of estimation techniques, resource allocation, and cost tracking tools. Estimation techniques help create accurate estimates of project scope and effort, and cost, which helps with budgeting and resource allocation. Resource allocation involves assigning the right people (i.e., those with the necessary skills) to complete each task, and this helps optimize efficiency and cost. Cost tracking tools help track project costs and identify areas for potential savings.
The ongoing evolution of computing technology, such as web, mobile, and cloud computing, has had a significant impact on the way modern software engineering is done. Nevertheless, it is still common to get into trouble when designing and developing high-quality software on time and within budget. The major reasons for that are as follows:
- Software systems are the most complex types of systems humans create.
- The pace of change in computer and software technology is high. The programming techniques and related processes that work well when used individually or in a small team fail when applied in a large team developing a large complex system.
- There are not enough qualified software engineers, and thus software systems are designed and developed by people who have insufficient backgrounds or experience.
Software Engineering and Computer Science
Where does software engineering fit within computer science? Both software engineering and computer science deal with the creation of software, and while there appears to be an overlap between these two disciplines, software engineering tends to focus on software applications, more specifically, on the design and development of software solutions. This makes software engineering a branch or subarea of computer science.
Computer science focuses on the study of algorithms and their realization in terms of computers, computer systems, and related computational processes. It focuses heavily on the theoretical and mathematical principles involved with the creation of algorithms and data structures. While computer science includes software engineering, it also covers a variety of other disciplines. In comparison, software engineering focuses specifically on the application of engineering principles to understand, design, construct, and deploy production software. It starts with eliciting and analyzing requirements and results in providing a practical software solution that meets those requirements. Computer science goes beyond just creating software solutions, and includes software design and development. While software engineers need to have a solid knowledge of fundamental computer science (e.g., the basics of algorithms and data structures), they are not expected to exhibit the same level of theoretical knowledge as that of a computer scientist. For example, while a computer scientist would need to be able to establish the asymptotic time complexity of the algorithms they pick, a software engineer would not.
Software engineering departs from the general focus of computer science and is complementary in the following ways:
- Software engineering tends to focus on applying technology to create solutions, whereas computer science tends to focus much more on understanding the technology itself.
- Software engineering tends to focus on software. Computer science can focus on software, hardware, and the interaction between the two.
- A software engineer tends to focus on developing solutions that meet the requirements of an organization or project. A computer scientist tends to focus on the underlying computational processes required to create solutions in the optimal or most efficient ways.
The essence of the software engineering practice is based on the work of numerous researchers such as the mathematician George Pólya. Pólya’s heuristic for generalized problem-solving includes the following steps:
- Understand the problem.
- Devise a plan.
- Carry out the plan.
- Look back and examine the solution.
The Nature and Impact of Software
Software has become an essential part of our lives. It has revolutionized how we communicate, work, learn, and entertain ourselves. From the smartphones in our pockets to the complex systems that power hospitals and transportation networks, software is everywhere.
Because the focus of software engineering is to build software, it is important to understand what software is. A piece of software is made up of instructions that can be executed and generally includes documentation that describes the software operation and use. These instructions tell computers what to do. They function like a recipe that tells a chef how to cook a meal. Software is designed to accomplish a specific objective or purpose. Word processing software has the objective or purpose to help people create documents. A game has the objective or purpose of providing entertainment. The software built into an automobile has many purposes, including helping a driver drive the car, helping the owner maintain the car, and helping a driver and/or passengers avoid getting lost.
Software is generally created based on a set of requirements, and although software does not wear out, these requirements often change over time. Software must, therefore, be updated often to respond to these changes. In addition, software can contain defects (i.e., bugs), which are expected to be fixed in a reasonable time after they are reported.
Over the years, software engineering researchers and practitioners have converged on defining a generic software engineering process model, or process framework, that can be used as a template to characterize the generic activities performed by all the software engineering process models that are used to support the software development life cycle (SDLC). The SDLC is a structured set of the framework activities required to develop a software solution based on a set of requirements. A process framework generally encompasses four framework (or generic) activities: inception, elaboration, construction, and deployment. These activities are also known as phases.
You’ll learn more about each of these phases later in the chapter. In the meantime, it should be noted that the deployment phase covers integration and user acceptance testing, installation, and maintenance/support activities. This means that maintenance is an integral part of the software engineering process. In fact, the cost of software maintenance/continuous deployment today often exceeds the cost of software construction, especially if software remains in use for a long time.
Categories of Software
There are three main categories of software. Software that enables you to control hardware and provides an environment in which other software can run is called system software. An example of this is an operating system, such as Microsoft Windows, Android, and MacOS, which runs on a laptop or a mobile phone and typically controls and provides access to the computer’s basic functionality. This system software also includes driver software, which is the code used by hardware devices to interact with the operating system.
Software that enables you to fulfill common tasks, such as creating a text document, drawing a picture, or playing music, is called application software. Examples include Microsoft Word and Paint, MacOS Pages, and iOS Files. Application software may include specialized categories of software such as scientific (or engineering) software, which is software that aids you in solving mathematical, scientific, and engineering problems, such as finding the roots of an equation. It can also include software services, which are software programs that provide specific responses or actions based on a request, such as returning stock quotes, obtaining weather conditions, or finding what current jobs are available.
Software that is integrated with hardware and can include both application and system software features is called embedded software. Examples include software in a smartwatch, an automobile control system, or microwave. Interaction with embedded software is usually limited, and users are often unaware that they are interacting with software. With the increased popularity of the Internet of Things (IoT), embedded software development is increasing.
Software engineers must often deal with legacy software that has been written in the past, relies on obsolete technology, and is still in use today. This software presents special challenges to those who maintain it, especially when they need to adapt it to a new computing environment or technology and when they are to extend its functionality so that it is interoperable with new software systems. The need for software maintenance of legacy software stems from the rapid changes that have taken place in hardware. For example, a common smartphone contains a more powerful processor and more memory than computers that were used just twenty years ago. Changes in hardware are accompanied by changes in software technologies, and these are quickly adopted by users who are then reluctant to use legacy software in its original shape. For example, the graphical user interface of a software system that was developed twenty years ago now looks outdated and leads to an unpleasant user experience.
There have also been dramatic changes in processor technology. Twenty years ago, most processors consisted of a single core, while now it is common for a processor to have multiple cores and coprocessors. This requires changes in how software is programmed because software that can utilize multiple processor cores has a competitive advantage compared with software that uses only a single core. To support these new capabilities, major programming languages have evolved toward supporting multithreading, which makes maintenance of a legacy code base even more challenging.
Concepts In Practice
The Ever-Changing World of Software Platforms
Imagine the life of a software engineer developing programs in the 1980s, which required typing programs on a terminal and printing punch cards that were fed into a mainframe computer! The world of software development is constantly evolving, and the platforms where software runs change rapidly, too. Software engineers need to stay up-to-date on current platforms and also become aware of what is coming next.
A Trip through Time
Can you imagine using a computer without a mouse or a graphical interface? Let us take a look at the way software platforms have evolved over time:
- Early Days (1980s): Mainframes and minicomputers were giant, even room-sized, and software was often run from the command line.
- The Rise of the Desktop (1990s): Welcome to the age of Windows and Mac! Graphical interfaces made computers more user-friendly, and client-server systems allowed applications to run across multiple machines.
- The Web Takes Over (2000s): The Internet exploded, and Java and C# became popular languages for building web applications.
- Mobile Mania (2010s): Smartphones like the iPhone changed the game. Software development focused on mobile apps that took advantage of constant connectivity.
The Future Is Unknown but Exciting
Augmented and virtual reality (AR/VR), machine learning (ML), artificial intelligence (AI), the Internet of Things (IoT), and blockchain are some emerging technologies that are shaping up the future of Metaverse software platforms. Who knows what exciting new platforms await? Curious and adaptable software engineers will be best positioned to thrive in this ever-changing landscape.
Software Requirements
Software is developed based on requirements, which are categorized as functional and nonfunctional, as shown in Figure 9.2. Functional requirements state what the software needs to do in terms of tangible functionality, such as the login or registration functionality that allows users to access a given piece of software such as their Facebook account. Nonfunctional requirements are measurable qualities of a piece of software, such as usability, performance, and other quality aspects.
As noted earlier, a functional requirement relates to the services the system provides to the users. It reflects the user’s expectation about the inherent characteristics of the software, (i.e., the functions it must perform). Functional requirements can include those phenomena that are generally seen or done when using a software solution, such as the information that is entered or that is generated by the software, the authenticating rules for using the software, or whether there should be an audible alert (such as a beep) when an action is selected. A nonfunctional requirement describes a desired quality or feature (i.e., constraint) and covers aspects of the software such as flexibility, maintainability, performance, portability, reliability, scalability, security, and more. For example, a nonfunctional requirement could specify that responses from the software must occur within a specific time frame, or that a software system must be able to handle a certain number of transactions at any given time. Another example of a constraint that a nonfunctional requirement may express is the need to use a specific programming language or follow a particular standard.
Nonfunctional features are sometimes categorized in terms of static or dynamic qualities. A static quality is a nonfunctional feature that is unchangeable and thus might be associated, for example, with the source code and related documentation, or with legal or project-environment specific requirements. A dynamic quality is a nonfunctional feature that relates to the qualitative behavior of software while it is in use, which means that is also depends on the hardware that the system runs on. Both quality types are measurable features rather than functions that are present or absent. Examples of static qualities include:
- maintainability, which is a measure of the amount of work required to fix bugs, improve performance, and keep the system running
- extensibility, which is a measure of the amount of work and cost of adding new features to software
- flexibility, which is a measure of the difficulty of updating the system to meet changing requirements
- portability, which is a measure of the amount of work and cost of migrating software solutions
- usability, which is a measure of how intuitive the user interface is
Examples of dynamic qualities are:
- performance, which is a measurement of how quickly the system responds to requests it receives
- throughput, which is a measure of how much input the system can process within a given time frame
- availability, which is a measure of how often the system will be ready and active for users
- scalability, which is the measurement of the work and cost to increase a system’s throughput
- security, which is a measure of confidence that data is protected from unauthorized disclosure and that systems are protected from unauthorized access
The relative importance of the preceding characteristics depends on the solution requirements and the environment in which they are to be used. For example, in an Internet banking application, availability and usability are typically key features advertised to customers. Security would also be important, as the software solution would need to comply with regulatory requirements. In a brokerage system, performance would be an important requirement because the software system will need to display prices and process users’ orders in real time.
Think It Through
Professional Responsibility in Software Engineering
Given the professional responsibility of software engineers working on various projects across the world, what is right or wrong, in your opinion, about the following matters in a software engineering context: developing systems for the military (e.g., creating an autonomous military drone); adding a backdoor to an existing system (e.g., providing authorities with a way to unlock a locked mobile phone); or modeling patient medication needs (e.g., prescribing pain medication for each hospital patient based on historical data).
In each of these cases, the development of the system could provide real benefits. For example, an autonomous drone allows the military to act without putting its soldiers’ lives at risk, and a backdoor ensures law enforcement officials can get access to information they may need to solve a crime. But there are also drawbacks to each of these systems. The backdoor risks everyone’s privacy because anyone could use it to access private data on a phone, and relying on past medication data risks institutionalizing existing biases about who needs more (or less) pain medication. It is important for software engineers to consider all of the impacts that a system will have and determine whether these impacts are acceptable or not.
Software Engineer Skills
As mentioned earlier, a software engineer is involved in the creation of software. Software engineers work with others and are a part of a team. They must be able to understand and act on a vast array of requirements. To accomplish what is required, a successful software engineer must have strong analytical and problem-solving skills, must communicate well with their peers, must be a team player, must take responsibility for their commitments, must exhibit attention to detail, and must be pragmatic when adapting software engineering practices based on circumstances. In addition, software engineers must be flexible when it comes to adopting new technologies. Therefore, in terms of technical skills, software engineers must have a solid foundation in the following areas:
- Problem-solving and algorithms: Software engineers are like detectives who solve puzzles. They use algorithms, which are step-by-step instructions, to efficiently solve problems. Understanding different algorithms allows them to choose the best approach for a specific task. There are many algorithms that can be considered essential, and it can be hard to learn all of them. Understanding the importance of algorithms and being willing to learn new things is a required skill for software engineers.
- Data structures: Imagine a well-organized toolbox where each tool has its designated spot. Data structures are like these toolboxes, but for data! Knowing different data structures (such as arrays, lists, trees, stacks, and queues) and being able to assess their benefits and drawbacks helps software engineers organize information efficiently for their programs. The knowledge of fundamental data structures is essential because without efficient data structures, you cannot write efficient code.
- Programming languages: There are many programming languages and each one of them has strengths and weaknesses. Software engineers should be familiar with at least a few core languages, such as Java, Python, or C++. Most important, they should be adaptable and willing to learn new languages as needed.
- Software engineering process: Software is usually developed in a team and follows a process. This process describes how to organize a team of developers effectively as well as how to approach the creation of the software. There are many approaches to team-driven software development and software engineering processes can be either continuous or discrete. Discrete processes, such as those advocated by Agile development2, encourage flexibility as to what activities are required and to what degree within a given project. Usually, all activities will be conducted when using continuous processes. A software engineer should be familiar with the pros and cons of various software engineering processes to be able to apply the best one to their own software development projects. Later in this chapter, both traditional and Agile software development life cycle (SDLC) processes, and various related models and frameworks, are covered in more detail.
- Testing: The purpose of testing is to ensure that a software system is free of defects and meets the functional and nonfunctional requirements. It is important to realize that testing is an ongoing activity that occurs throughout the software engineering process. For example, software engineers may conduct unit testing of a website’s checkout functionality as part of their software construction activities to make sure that the software calculates the total of a customer’s order correctly. They may also be involved in integration testing as components developed by other team members are being integrated.
- Tools: There are many tools that can be used in software development, and these tools go beyond just being used to create software code. They can, for example, facilitate communication within the team, help support engineering tasks, and maintain a historical record of source code versions. Each software engineer should be familiar with major tools and their underlying principles so that they can use them effectively.
- Computer technology: Software engineers need at least a high-level understanding of the computer technology that might be applicable to the software solutions they may be required to create or work with. This includes areas such as operating systems, cloud services, security, networking, communications, database technology, and UI/UX. Software engineers might also be called upon to work with computer technologies such as machine learning (ML) and its applications to artificial intelligence (AI), business intelligence (BI), and the multitude of ever-evolving applications of computer technologies that are available today. A successful software engineer is aware of current computer technology and understands how to leverage it.
- Soft skills: A software engineer should have the soft skills required to assume their role such as problem solving, communication, and time management, as shown in Figure 9.3. Soft skills tend to be more innate, but are often just as critical as the previously listed skills. For example, a software engineer could be tasked with developing a software solution within twelve months that tracks and displays relevant driving information onto a heads-up display presented on the windshield of a new model of an automobile. To deliver this solution on time, the software engineer would need to manage a schedule. As part of a team project, they would also need to understand how to effectively communicate and interact with other project team members. Additionally, they would need to problem-solve the requirements to derive a solution using appropriate algorithms and patterns. Problem-solving includes understanding how and when to bring subject matter experts or non–software engineer resources onto a project. Being able to apply these softer skills can be just as critical to a software engineer’s success as applying the right processes, methods, tools, and data structures/algorithms.
Technology in Everyday Life
Programming Languages: A Software Engineer’s Toolkit
Imagine a toolbox with specialized tools—a hammer for carpentry, or a paintbrush for art. Software engineers also use various tools, and some of their tools are programming languages! Just as the right tool makes a job more accessible, the correct programming language helps engineers build different software applications.
Can You Guess the Language?
Identify the programming languages commonly used to build the following types of applications:
- Mobile app (like Instagram)
- Website (like Wikipedia)
- Video game
Possible answers include JavaScript, Python, C++, Java.
Why So Many Languages?
Each programming language has its strengths. Some languages are great for building an application’s core functionality (like C++ or Java), while others are better suited for adding interactivity (like JavaScript). Understanding different languages allows software engineers to choose the right tool for the job.
How Many Languages Should a Software Engineer Know?
There is no right or wrong answer to this question. It is possible, though not common, to be employed as a software engineer knowing only a single programming language. Typically, however, successful software engineers understand the different categories of programming languages and the common structure and design features of each.
It is often recommended that a software engineer learn a primary programming language that can be used for system-level programming such as C, C#, or C++. Additionally, in today’s world, a software engineer should understand object-oriented programming, which is done in languages like Python, C++, and Java. Because web development often is a part of solutions, knowing a scripting language, such as JavaScript, Python, PHP, Perl, or Ruby, is also beneficial. Finally, understanding markup languages such as HTML and XML is also important.
Of course, the best languages to know are dependent on the projects that are worked on. If a software engineer is creating embedded solutions, then the programming language is likely going to be much different than if they are doing high-end gaming solutions or web-based solutions. Chapter 7 High-Level Programming Languages delves deeper into programming languages.
Footnotes
- 1While IEEE is an acronym for the Institute of Electrical and Electronics Engineers, the organization has expanded to include all technology professionals. This worldwide organization is “dedicated to advancing technology for the benefit of humanity.” Examples of the work it does is publishing journals to disseminate the latest research, creating model curricula that help universities provide up-to-date degree programs, and defining standards that ensure electronic devices are interoperable. You can find more about the IEEE at www.ieee.org.
- 2The original goals of Agile development were laid out in the Agile Manifesto. This is at https://AgileManifesto.org.