0% found this document useful (0 votes)
56 views

CS211 Introduction

This document provides an overview of software engineering principles and models of software development. It discusses: 1) The definition of software engineering as applying engineering principles and methods to develop reliable software products. 2) Key topics that will be covered, including software engineering design principles, development models, components of software systems, modular programming, and debugging. 3) Two models of software development - the waterfall model and spiral model. The waterfall model involves sequential phases of requirements, design, implementation, testing, and maintenance. The spiral model incorporates risk analysis and control into each cycle.

Uploaded by

Jackson Mtonga
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
56 views

CS211 Introduction

This document provides an overview of software engineering principles and models of software development. It discusses: 1) The definition of software engineering as applying engineering principles and methods to develop reliable software products. 2) Key topics that will be covered, including software engineering design principles, development models, components of software systems, modular programming, and debugging. 3) Two models of software development - the waterfall model and spiral model. The waterfall model involves sequential phases of requirements, design, implementation, testing, and maintenance. The spiral model incorporates risk analysis and control into each cycle.

Uploaded by

Jackson Mtonga
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

THE COPPERBELT UNIVERSITY

SCHOOL OF ENGINEERING

APPLIED COMPUTING: CS211

@2021
1 Introduction
The term software engineering is composed of two words, software and engineering.
Software is more than just program code. A program is executable code, which serves
some computational purpose. Software is considered to be a collection of executable
programming code, associated libraries and documentations. Software, when made for a
specific requirement is called software product. Engineering on the other hand, is all about
developing products, using well-defined, scientific principles and methods. Thus, we can define
software engineering as an engineering branch associated with the development of software
product using well-defined scientific principles, methods and procedures. The outcome of
software engineering is an efficient and reliable software product. A small program can be written
without using software engineering principles. But if one wants to develop a large software
product, then software engineering principles are absolutely necessary to achieve a good quality
software product cost-effectively.

In this chapter, you will tackle the following topics:

1.1 Principles of software engineering design


1.2 Models of software systems development
1.3 Components of software systems development
1.4 Modular program development
1.5 Debugging programs

1.1 Principles of software engineering design


The discipline of software engineering is concerned with the design and implementation
of computer programs that work, are correct, and are well written. Software engineering principles
can be applied to small and large computer programs alike:

Small Computer Programs. Small computer programs are characterized by the data structures
and algorithms they employ, design of the program architecture, and the computational efficiency
of the program implementation. Small computer programs involve up to a few hundred lines of
source code. When you are learning to program in a new language, becoming familiar with its
syntax, data types, and control structures are the most important things because without them
you cannot transform a small-scale task into step-by-step programming instructions.

Large Computer Programs. In real-world engineering environments it is now commonplace for


computer programs to be hundreds of thousands (even millions) of lines long. Many of them are
so complex that even the best human minds cannot simultaneously comprehend all the details. It
is therefore vitally important that the design and implementation of large computer programs be
based on established procedures for software development, including attention to program
specification and design, organization, coding, testing, and maintenance of software. Careful
planning of these activities is needed because:

a. Large programs are most often written by programming teams. Team members must be
able to understand one another’s work. When the planning, design, and coding of a project
takes several years, communication of work among employees is of utmost importance.
b. Large programs are often developed within the constraints of short time-to-delivery
contract schedules. Programming teams may not have the luxury of starting again, even
after a key design flaw is identified.

c. Well-organized programs are easier to debug. A little extra time spent planning the layout
of a program may be saved many times over when it comes time to debug and upgrade
the software. Indeed, some estimates place maintenance at 60 to 80% of the overall cost
of a software project.

d. Large programs often evolve through a series of versions or updates. The programmer
making updates is likely to be a person other than the original developer.

1.2 Models of software systems development


Models of software systems development are an important component of large computer program
development because they provide the project participants with a framework for knowing what is
expected, and when. In some cases, the model may also form the basis of legal agreements, with
contract payments being tied to successful completion of a task identified in the model.

Waterfall Model of systems development


There are many models of software systems development used in industry but in this chapter, we
will only consider two, namely: - the waterfall and spiral models. Figure 1.1 is a schematic of the
waterfall model of software system development. The waterfall model views the software
development process as a sequence of stages that includes requirements specifications, design
and testing, integration, and maintenance.

Fig 1.1: Waterfall model of systems development


Each phase of sequential development is completed, via formal review, before the next phase
begins. The waterfall model of development is appropriate when the problem and solution method
are well understood.

a. Analysis phase
Often known as Software Requirements Specification (SRS) is a complete and
comprehensive description of the behavior of the software to be developed. It requires
system and business analysts to define both functional and non-functional requirements.
Usually, functional requirements are defined by means of use cases which describe the
users’ interactions with the software. They include such requirements as purpose, scope,
perspective, functions, software attributes, user characteristics, functionalities
specifications, interface requirements, and database requirements. In contrast, the non-
functional requirements refer to the various criteria, constraints, limitations, and
requirements imposed on the design and operation of the software rather than on
particular behaviors. It includes such properties as reliability, scalability, testability,
availability, maintainability, performance, and quality standards.

b. Design phase
It is the process of planning and problem solving for a software solution. It requires
software developers and designers to define the plan for a solution which includes
algorithm design, software architecture design, database conceptual schema and logical
diagram design, concept design, graphical user interface design, and data structure
definition.

c. Implementation phase
It refers to the realization of business requirements and design specifications into a
concrete executable program, database, website, or software component through
programming and deployment. This phase is where the real code is written and compiled
into an operational application, and where the database and text files are created. In other
words, it is the process of converting the whole requirements and blueprints into a
production environment.

d. Testing phase
It is also known as verification and validation which is a process for checking that a
software solution meets the original requirements and specifications and that it
accomplishes its intended purpose. In fact, verification is the process of evaluating
software to determine whether the products of a given development phase satisfy the
conditions imposed at the start of that phase; while validation is the process of evaluating
software during or at the end of the development process to determine whether it satisfies
specified requirements. Moreover, the testing phase is the outlet to perform debugging in
which bugs and system glitches are found, corrected, and refined accordingly.
e. Maintenance phase
It is the process of modifying a software solution after delivery and deployment to refine
output, correct errors, and improve performance and quality. Additional maintenance
activities can be performed in this phase including adapting software to its environment,
accommodating new user requirements, and increasing software reliability.

Waterfall Model Application


Every software developed is different and requires a suitable Software Development Life
Cycle approach to be followed based on the internal and external factors. Some situations
where the use of Waterfall model is most appropriate are: -
a. Requirements are very well documented, clear and fixed.
b. Product definition is stable.
c. Technology is understood and is not dynamic.
d. There are no ambiguous requirements.
e. Ample resources with required expertise are available to support the product.
f. The project is short.

Waterfall Model Advantages


a. Simple and easy to understand and use.
b. Easy to manage due to the rigidity of the model. Each phase has specific deliverables
and a review process.
c. Phases are processed and completed one at a time.
d. Works well for smaller projects where requirements are very well understood.
e. Clearly defined stages.
f. Provides for a good understanding of milestones.
g. Easy to arrange tasks.
h. Process and results are well documented.

Waterfall Model Disadvantages


a. No working software is produced until late during the life cycle.
b. High amounts of risk and uncertainty.
c. Not a good model for complex and object-oriented projects.
d. Poor model for long and ongoing projects.
e. Not suitable for the projects where requirements are at a moderate to high risk of
changing.
f. Cannot accommodate changing requirements.
g. Adjusting scope during the life cycle can lead to premature termination of a project.
h. Integration is done as a "big-bang. at the very end, which doesn't allow identifying
any technological or business bottleneck or challenges early.
The Spiral model of systems development
The spiral model of development, shown in Figure 1.2, is simply a sequence of waterfall
models with risk analysis and control incorporated at regular stages in the project. This
risk-oriented approach to iterative enhancement recognizes that implementation options
are not always clear at the beginning of a project. For example, a software project that is
scheduled for development over a number of years may need technology that has not yet
come to market. Maybe the technology will evolve as expected, and maybe it will not.

Fig 1.2: Spiral model of systems development

The radial direction of Figure 1.2 corresponds to the cumulative cost incurred in the
project, and the angular direction corresponds to progress made in completing each cycle
of the spiral. Each cycle of development has the following phases:-

a. Identify the design and development objectives for the cycle, as well as the
alternatives that are possible to achieve the goals.
b. Evaluate different alternatives based on objectives and constraints. Where
appropriate, identify uncertainties and risks. Risk means “something that can go
wrong” as the consequence of incomplete information, or perhaps, as the result of
human errors.

c. Develop strategies such as simulation, prototyping, and benchmarking for resolving


uncertainties and risks.

d. Plan the next stage, allowing for any of the possible lifecycle models to be used.

Spiral Model Application


Spiral Model is very widely used in the software industry as it is in synch with the natural
development process of any product i.e. learning with maturity and also involves minimum
risk for the customer as well as the development firms. Following are the typical uses of
Spiral model:
a. When costs there is a budget constraint and risk evaluation is important.
b. For medium to high-risk projects.
c. Long-term project commitment because of potential changes to economic priorities as
the requirements change with time.
d. Customer is not sure of their requirements which is usually the case.
e. Requirements are complex and need evaluation to get clarity.
f. New product line which should be released in phases to get enough customer
feedback.
g. Significant changes are expected in the product during the development cycle.

Spiral Model Advantages


a. Changing requirements can be accommodated.
b. Allows for extensive use of prototypes
c. Requirements can be captured more accurately.
d. Users see the system early.
e. Development can be divided into smaller parts and more risky parts can be developed
earlier which helps better risk management.

Spiral Model Disadvantages


a. Management is more complex.
b. End of project may not be known early.
c. Not suitable for small or low risk projects and could be expensive for small projects.
d. Process is complex.
e. Spiral may go indefinitely.
f. Large number of intermediate stages may result in excessive documentation.
1.3 Components of software systems development
The key steps in the development of a large software project are as follows:

Requirements Specification. The objective of the requirements specification is to state the goals
of the program as carefully as possible. The goals could include, for example, expected input
(keyboard/files/IO board) and output. The requirements should also identify any known limitations,
possible errors, and accuracy issues.

Analysis. Carefully analyzing a problem and its possible solutions is of utmost importance. Either
you have to develop an algorithm yourself or find one that is already available. Do not hesitate to
look for established techniques; for example, an engineering problem might involve solving a set
of linear equations using a standard numerical algorithm such as Gaussian Elimination. To
develop algorithms from scratch when an already well-thought out and documented technique is
available is a waste of time.

Design. The next most important phase of program development is to develop a viable design
that you believe will work. Studies indicate that up to 50% of all errors in the software lifecycle are
made during the design phase of the software; the remaining errors tend to be programming and
syntax errors (as described previously). Unfortunately, design errors are also the most expensive
to repair since many appear only at run-time, and often after the software has been delivered to
the customer.

Implementation. The implementation phase focuses on the specification, writing, and


documentation of modules of code. When the details of specification are particularly complicated,
pseudocode is often inserted as an intermediate step. Pseudocode is simply a high-level
description of the code (or algorithm) to be implemented, where the semantics are less strict than
the programming language itself.
Always document program source code so that it can be understood by you and others at
a later date. Documentation includes recording details of your specific solution – how the analysis
phase will transfer to the program, what language-specific constructs were used, what method
of problem decomposition was used, and any important restrictions in your software design. An
executable program is the result of the implementation phase.

Test and Verification. In many engineering industries, such as airplane flight control, airport
traffic control, nuclear power plant control, medical instruments, and communications network
control, reliability of software is the most sought-after attribute. The software must execute as
expected and without errors. Obtaining software that performs with a high degree of confidence
requires a solid program design, a careful implementation, and a carefully designed suite of test
problems that may illuminate software bugs and weaknesses. The identification of bugs and
weaknesses is highly desirable, because this is the point at which fixing them is easy.
Maintenance. It is frequently stated that up to three quarters of a programmer’s time is spent on
maintaining existing software. Maintenance activities include (1) repair of coding (and design)
errors, (2) adapting the software to changes in the computing environment (e.g., an update in the
operating system), and (3) adapting the software to changes in the customers’ requirements.

1.4 Modular Program Development


The goal of modular programming is to break a complex task or program into an ensemble of
weakly coupled (independent) modules. Each module should be viewed as an independently
managed resource, with access highly restrained. Programs consisting of well-designed modules
are much simpler to design, write, and debug than equivalent programs that are poorly designed.
Guidelines for the design of program modules are:

a. Psychological studies indicate that the average human can only simultaneously
comprehend seven (plus or minus two) pieces of information. Hence, one module should
have no more than seven subordinate modules.

b. There should be separation between the controller and worker modules.

c. Every module must perform a task appropriate to its place in the hierarchy.

d. Every module should only receive as much information as it needs to perform its function,
and ideally, they should exchange as little information as possible.

Modules should enforce the principle of information hiding, namely, that all information about a
module should be private to the module unless it is explicitly declared public. Public data
should be avoided because it exposes implementation details that make reuse unlikely and
maintenance difficult. A key benefit of information hiding is the opportunity it affords for updating
the internal details of a module (here we assume that the details of the public interface will not
change) without affecting other modules in the system.

Coupling. Coupling measures the extent to which different modules in a system are
interconnected with one other. See Figure 1.3. In design we should keep the interfaces as minimal
and as simple as possible. Designing for minimal coupling among modules helps to ensure that
errors occurring in one module will not propagate across the whole system.

Cohesion. Cohesion is a concept that describes how strongly the attributes and functions of a
module are connected together. Ideally, a module should just perform one task. In design we
should keep related functions together and unrelated functions apart.
Fig.1.3: Highly coupled and loosely coupled modules

Abstraction
Programmers often apply techniques of abstraction to the development process, meaning that
they concentrate on the essential features of one part/module of the computer program, and
abstract from details of the computer program that are not immediately relevant to the current
module. In the development of computer software, two types of abstraction are common:

a. Procedural. Software development is based on a stepwise refinement of the system’s


abstract function. This type of abstraction is most common in programming languages
such as C, MATLAB, and FORTRAN.

b. Data. Software development is based on the system data and the operations that can be
applied to the data. Implementations of data abstraction correspond to objects and the
operations that can be applied to the objects. This type of abstraction is common in object-
oriented programming languages such as C++ and Java.

Top-down and Bottom-up Software Design


Techniques of abstraction are often used in conjunction with a combination of top-down
and bottom-up development strategies, as shown in Figure 1.4.
Top-down software development begins at the conceptual level and passes through three stages:

1. The high-level design establishes the important subsystems of the design, the purpose and
intended behavior of each subsystem, and the relationship among subsystems. As already
mentioned, a good design corresponds to subsystems that are as uncoupled as possible.

2. The intermediate-level design breaks subsystems into modules. Each module should have
one well-defined purpose, hide its data from other modules, and have a minimal number of
connections to other modules in the program.
3. The low-level design involves detailed specification of algorithms and data structures.

Fig.1.4: Top-down and bottom-up design approaches

As can be observed, the top-down design delays detailed decisions about the program flow and
data structures until they absolutely have to be made.

The strategy of bottom-up design starts with low-level procedures, modules, and subprogram
library routines, and tries to combine them into higher-level entities. A key benefit of bottom-up
design is its use of already implemented code. For example, numerical linear algebra packages
are one area where libraries are routinely linked to C programs for finite element and numerical
analysis, solution of differential equations, and solution of engineering control problems. No need
to reinvent the wheel.

Software designers never embark on the construction of a new system without first considering
available libraries/modules. Conversely, they never build software modules without a
preconceived vision of their future use. A balance of the above-mentioned criteria is usually
needed and desirable.
1.5 Debugging programs
Debugging is a methodical process of finding and reducing the number of bugs, or defects, in a
computer program. All bugs stem from a one basic premise: something thought to be right, was
in fact wrong. Due to this simple principle, truly bizarre bugs can defy logic, making debugging
software challenging. The typical behaviour of many inexperienced programmers is to freeze
when unexpected problems arise. Without a definite process to follow, solving problems seems
impossible to them. The most obvious reaction to such a situation is to make some random
changes to the code, hoping that it will start working again. The issue is simple: the programmers
have no idea of how to approach debugging.

The importance of a method of finding errors and fixing them during the life cycle of a software
product cannot be stressed enough. Testing and debugging are fundamental parts of
programmer’s everyday activity, but some people still consider it an annoying option. When not
carried out properly, consequences can be dreadful. In 1998, for example, a crew member of the
guided-missile cruiser USS Yorktown mistakenly entered a zero as data value, which resulted in
a division by zero. The error cascaded and eventually shut down the ship’s propulsion system.
The ship was dead in water for several hours because a program didn’t check for valid input.
Bugs can also be very expensive. In 1999, the 125 million dollars Mars Climate Orbiter was
assumed lost by officials at NASA. The failure responsible for loss of the orbiter was attributed to
a failure of NASA’s system engineering process. The process did not specify the system of
measurement to be used on the project. As a result, one of the development teams used Imperial
measurement while the other used the metric system. When parameters from one module were
passed to another, during orbit navigation correction, no conversion was performed, resulting in
the loss of the craft.

Despite being the realm of ingenuity and uncertainty, a debugging process can be divided into
four main steps:

1. localising a bug
2. classifying a bug
3. understanding a bug
4. repairing a bug

Localising a bug
A typical attitude of inexperienced programmers towards bugs is to consider their localisation an
easy task: they notice their code does not do what they expected, and they are led astray by their
confidence in knowing what their code should do. This confidence is completely deceptive
because spotting a bug can be very difficult. As it was explained in the introduction, all bugs stem
from the premise that something thought to be right, was in fact wrong. Noticing a bug implies
testing. Testing should be performed with discipline and, when possible, automatically, for
example after each build of the code. In case of a test failure, the programmer must be able to
see what went wrong easily, so tests must be prepared carefully.
Classifying a bug
Despite the appearance, bugs have often a common background. This allows to attempt a quite
coarse, but sometimes useful, classification. The list is arranged in order of increasing difficulty
(which fortunately means in order of decreasing frequency).

a. Syntactical Errors should be easily caught by your compiler. I say "should" because
compilers, beside being very complicated, can be buggy themselves. In any case, it is vital
to remember that quite often the problem might not be at the exact position indicated by
the compiler error message.
b. Build Errors derive from linking object files which were not rebuilt after a change in some
source files. These problems can easily be avoided by using tools to drive software
building, like GNU Make or Cmake, among others.
c. Basic Semantic Errors comprise using uninitialised variables, dead code (code that will
never be executed) and problems with variable types. A compiler can highlight them to
your attention, although it usually has to be explicitly asked through flags.
d. Semantic Errors include using wrong variables or operators (e.g., && instead of & in
MATLAB). No tool can catch these problems, because they are syntactically correct
statements, although logically wrong. A test case or a debugger is necessary to spot them.

Understanding a bug
A bug should be fully understood before attempting to fix it. Trying to fix a bug before
understanding it completely could end in provoking even more damage to the code, since the
problem could change form and manifest itself somewhere else, maybe randomly. A typical
example is memory corruption: if there is any suspect memory was corrupted during the execution
of some algorithm, all the data involved in the algorithm must be checked before trying to change
them.
The following check-list is useful to assure a correct approach to the investigation:
a. do not confuse observing symptoms with finding the real source of the problem;
b. check if similar mistakes (especially wrong assumptions) were made elsewhere in the
code;
c. verify that just a programming error, and not a more fundamental problem (e.g. an
incorrect algorithm), was found.

Repairing a bug
The final step in the debugging process is bug fixing. Repairing a bug is more than modifying
code. Any fixes must be documented in the code and tested properly. More important, learning
from mistakes is an effective attitude: it is good practice filling a small file with detailed
explanations about the way the bug was discovered and corrected.
A check-list can be a useful aid. Several points are worth recording:
a. how the bug was noticed, to help in writing a test case;
b. how it was tracked down, to give you a better insight on the approach to choose in similar
circumstances;
c. what type of bug was encountered?
d. if this bug was encountered often, in order to set up a strategy to prevent it from recurring;
e. if the initial assumptions were unjustified; this is often the main reason why tracking a bug
is some time consuming.

Exercise
1. Briefly explain the terms abstraction, modularity, coupling, cohesion, and information
hiding?
2. What are the goals of top-down and bottom-up design?
3. What is the difference between procedural abstraction and data abstraction?
4. What are the basic steps involved in the development of software?
5. What is the difference between syntax and semantic errors?
6. As an employ of Toyota, you are developing software for a computer vision system for
next generation self-driving cars, select an appropriate software development model for
the project and justify your choice.

You might also like