Why Software Engineering Is Difficult
Chapter 1 • Introduction
5
5. Operation and Maintenance
- Running the system; Fixing bugs and adding new features
The lifecycle usually comprises many other activities, some of which precede the above ones, such as marketing survey to determine the market need for the planned product. This text is
restricted to engineering activities, usually undertaken by the software developer.
The early inspiration for software lifecycle came from other engineering disciplines, where the above activities usually proceed in a sequential manner or at least it was thought so. This
method is known as waterfall process because developers build monolithic systems in one fell swoop. It requires completing the artifacts of the current phase before proceeding to the
subsequent one. However, over the years the developers noticed that software development is unlike any other product development in the following aspects:
• Unlike most of other products, software is intangible and hard to visualize. Most people experience software through what it does: what inputs it takes and what it generates as
outputs • Software is probably the most complex artifact—a large software product consists of so
many bits and pieces as well as their relationships, every single one having an important role—one flipped bit can change the entire sense of a program
• Software is probably the most flexible artifact—it can be easily and radically modified at any stage of the development process or, at least it is so perceived
These insights led to adopting iterative or evolutionary development methods. These methods are also recently characterized as agile. A popular iterative process is called Unified Process
[Jacobson et al., 1999]. Each iteration should involve progressing through the design in more depth. Iterative process seeks to get to a working instance
2
as soon as possible. Having a working instance available lets the interested parties to have something tangible, to play with and make
inquiries. Through this experimentation preferably by end users, unsuspected deficiencies are discovered that drive a new round of development using failures and the knowledge of things that
would not work as a springboard to new approaches. This greatly facilitates the consensus reaching and building the understanding of all parties of what needs to be developed and what to
expect upon the completion. So, the key of iterative methods is to progressively deepen the understanding or “visualization” of the target product, by both advancing and retracting to earlier
activities to rediscover more of its features.
All lifecycle processes have a goal of incremental refinement of the product design, but different people hold different beliefs on how is this to be achieved. This has been true in the past and it
continues to be true, and I will occasionally comment on different approaches below. Personally, I enthusiastically subscribe to the iterative approach, and in that spirit the exposition in this text
progresses in an iterative manner, by successively elaborating the software lifecycle phases. For every new topic, we will scratch the surface and move on, only to revisit later and dig deeper.
A quick review of any software engineering textbook reveals that software engineering is largely about management. Project management requires organizational and managerial skills such as
2
This is not necessarily a prototype, since “prototype” creates impression of something that will be thrown away after initial experimentation. Conversely, a “working instance” can evolve into the actual product.
Ivan Marsic • Rutgers
University 6
identifying and organizing the many tasks comprising a project, allocating resources to complete those tasks, and tracking actual against expectedanticipated resource utilization. Successful
software projects convey a blend of careful objective evaluation, adequate preparation, continuous observation and assessment of the environment and progress, and adjusting tactics.
It is interesting to compare the issues considered by Brooks [1975] and compare those of the recent agile methods movement—both put emphasis on communication of the development team
members. My important goal here is, therefore, to present the tools that facilitate communication among the developers. The key such tools are:
• Modular design: Breaking up the system in modules helps to cope with complexity; however, the modularization can be done in many ways with varying quality of the
results. • Symbolic language: The Unified Modeling Language UML is used similar to how the
symbols such as ∞, ∫, ∂, and ∩, are used in mathematics. They help to abbreviate the
exposition of the material and facilitate the reader’s understanding of the material. • Design heuristics: Also known as patterns, they convey the best practices that were
proven in many contexts and projects. Partitioning a problem into simpler ones, so called divide-and-conquer approach, is common
when dealing with complex problems. In software development it is embodied in modularity: The source code for a module can be written and maintained independently of the source code for
other modules. As with any activity, the value of a structured approach to software development becomes apparent only when complex tasks are tackled.
It appears to me that agile methods, such as extreme programming, change the process management aspect, but make no difference in technology.