Presentation is loading. Please wait.

Presentation is loading. Please wait.

Software Maintenance “Caveat Emptor: The cost of software maintenance increases with the square of the programmer’s creativity.” First Law of Programmer.

Similar presentations


Presentation on theme: "Software Maintenance “Caveat Emptor: The cost of software maintenance increases with the square of the programmer’s creativity.” First Law of Programmer."— Presentation transcript:

1 Software Maintenance “Caveat Emptor: The cost of software maintenance increases with the square of the programmer’s creativity.” First Law of Programmer Creativity, Robert D. Bliss, 1992 (Tbd. Investigate following notes: In some ways “software maintenance” is a misnomer because software doesn’t deteriorate like physical objects/tools. Software evolution might be a better term. “It doesn't take a lot of skill to get a program to work. The skill comes in when you have to keep it working.” --Robert Martin

2 What is software maintenance?
Changes made to software after delivery. Software may include source code, documentation, and operating procedures. Changes made to software after delivery are considered maintenance but preparation for maintenance should begin right after the decision is made to develop a new system. Prep includes: design for maintenance (modular, loose coupling, assertions), follow good coding standards, documentation (req, design implementation).

3 Motivation Any software system that is used will almost certainly require maintenance. Surveys show that 40-70% of the total life cycle cost of a software system is spent on maintenance. Software maintenance is more than just continued development after release. While there are many similarities between maintenance work and new development work, there are some important differences as well. Maintenance must be done in the context of an existing system which imposes additional constraints. Home builders and programmers alike prefer green field development. Why software maintenance is an important topic? “Although maintenance could be regarded as a continuation of new development, there is a fundamental difference between the two activities.” “The total cost of system maintenance is estimated to comprise at least 50% of total life cycle costs (van Vliet [2000]). The proportional maintenance costs range from 49 % for a pharmaceutical company to 75% for an automobile company in some studies according to Takang and Grubb [1996]. Zelkowitz et al [1979] also point out that in many large-scale software systems, only one-fourth to one-third of the entire life cycle costs can be attributed to software development.” From: Green field development is preferred by home builders and software programmers alike. Home builders like building homes in the suburbs in land that once was pasture. No old buildings with hazardous waste to remove. No tree stumps etc. Much easier to work with. There is a lot of asbestos in old software systems.

4 Why software maintenance is needed
Software providers have an obligation to fix defects that significantly impair the functionality of their software. Software systems that get used tend to generate requests for enhancements and new functionality. Heavy users of a software system often discover ways of enhancing existing functionality or opportunities for new features. When the environment around software changes (operating system, government regulation, business rules), the software must be updated, otherwise it becomes less useful. Changes that improve the maintainability of software without changing its functionality are sometimes helpful. Such changes make it easier to complete functional changes on a short schedule. When you introduce software into an environment it often changes how work is done in the environment which in turn propels/compels additional changes. “Maintenance is needed to ensure that the software continues to satisfy user requirements.” Oftentimes software changes must be completed on a short schedule. For example, a flaw that creates a security vulnerability must be fixed immediately. Software providers can prepare for change requests of this type by making preparations for maintenance early in the development cycle. (I.e. take actions that make it easier to understand and modify the software.)

5 Types of software maintenance
The four types of software maintenance are: Corrective. Despite your best efforts, any non-trivial program will likely have defects. Corrective changes are changes to fix defects. This includes defects discovered by end users and those found through internal testing and other means. Preventive. Software can have flaws that don’t rise to the level of defects. For example, a programmer might carelessly use single character variable names or neglect design. Neither causes a direct failure in the program but both make the program harder to maintain in the future. Preventive changes are changes that improve the maintainability of a program or reduce the potential for future failures. Adaptive. Deployed software operates in an environment comprised of hardware and other software. Changes in this operating environment may compel changes in hosted programs. For example, if your Internet Service Provider (ISP) moves to a newer version of PHP, you may have to make changes to your PHP scripts in order for them to continue to work in the new environment. Adaptive changes are changes needed to cope with changes in the operating environment. The changes don’t bring any new functionality, they simply keep existing functionality working in the new environment. Perfective. Perfective maintenance are changes that add new features or capabilities in response to changes in requirements. While most of the changes in this category are likely to be for new functional requirements , it also includes changes made to implement new non-functional requirements such as usability. Categorizing change requests helps to account for time and money spent during maintenance. At a minimum, recording the type of each change made can tell you how much is being spent on corrections vs enhancements. Tracking effort spent on corrections is useful because it provides a measure of product quality and process effectiveness Categorizing new change requests helps when evaluating and prioritizing requests. For example, the policy might be to give priority to defect repair over implementing new functionality. When requests for new functionality are lumped in with or disguised as problem reports, it can be difficult to prioritize work and assess product quality. Poor requirements specification can make it difficult to distinguish between problems (missing or incorrect functionality) and requests for new functionality. If something doesn’t work as expected and there are no requirements, it can be impossible to determine if it is a defect (missing feature), an enhancement (something extra). Especially important for contracted systems.

6 Summary of Maintenance Types
Correction Corrective Maintenance – changes made to correct defects Preventive Maintenance – changes made to improve maintainability or prevent problems from occurring Enhancement Adaptive Maintenance – changes made to adapt the software to changes in its technical environment Perfective Maintenance – changes made to add new features or capabilities

7 Terminology Warning While the above categories are probably the most common, they aren’t the only way of categorizing the different types of software maintenance. The different reasons or motivations for making a change are generally recognized but different literature sources use different taxonomies for grouping the reasons. For example, some sources don’t recognize a separate category for preventive changes. Without a category for preventive changes, refactoring would be considered new functionality since it addresses the non-functional requirement maintainability. Even more confusing are instances when the same category label is interpreted differently. For example, I (and others) define preventive changes in such a way to include changes made that improve maintainability. IEEE standard 14764, Standard for Software Life Cycle Processes — Maintenance, considers changes that improve maintainability to be perfective changes. The IEEE standard defines a preventive change as ones that is “made to detect and correct latent faults in the software product before they become operational faults”. Originally, there were just three categories: Corrective, Adaptive and Perfective [Swansan 1976]. [Software Maintenance: Concepts and Practice, Grubb] defines adaptive changes to include changes made to adapt to changes in not only the technical environment but also the problem domain or business environment as well. [ISO/IEC 14764] considers changes made to improve maintainability perfective changes, presumably because it indirectly provides benefit to the end user (future changes can be made more quickly). I, and others [Grubb, Bennett], consider it to be a preventive change. To me it’s not a perfective change because users don’t perceive a direct benefit and, more importantly, users can’t judge the value of the change and therefore can’t estimate its relative worth compared to other perfective changes.

8 Example Question: Assume you rewrite an algorithm to run at O(n log n) vs O (n2)? What type of change is it? Answer: It depends. If there is a non-functional performance requirement that isn’t being met and the change brings the software into compliance with this non-functional requirement it would be considered a corrective change. If the software was in danger of violating this requirement it would be considered a preventive change. If the change was in response to a new non-functional performance requirement, it would be considered a new capability. Consider a change request to improve performance. What kind of change request would that be? If the current response time of the system is within specifications, the change would be a perfective change because it is an enhancement of existing functionality.

9 Effort Distribution On average, about 80% of the maintenance effort goes toward non-corrective changes [Lientz and Swanson 1980, via Grubb 2003] Software maintenance isn’t just about bug fixes. In fact, on average only 20% of the changes made after release are for bug fixes. [tbd: p118 of Facts and Fallacies of s/w eng has more data on where the maintenance dollar goes.]

10 Metaphors for understanding and communicating subtle maintenance concepts
Two useful metaphors for understanding and communicating subtle concepts in software maintenance are: Software Entropy, and Technical debt

11 Entropy Entropy is a measure of “disorder” in a closed system. The more disorganized something is, the higher its entropy. According to the Second Law of Thermodynamics, a system free of external influences will tend to become more disordered with time. Left alone, cars rust, gardens become overgrown with weeds, and houses fall into a state of disrepair. It takes extra effort from outside a closed system in order to reverse the tendency toward disorder within a closed system. Just to preserve the status quo, gardeners must periodically pull weeds and homeowners must perform routine maintenance. Things don’t spontaneously organize themselves. In physical systems and software there are many more states of disorder than order. If you drop a load of bricks off the back of a dump truck there is an infinitesimally small chance they will land in a nice neat orderly stack. It is a statistical certainty they will land in random disorder. Photo of rundown barn is from License is CC attribution , no derivative works. High Entropy

12 What a city block might look like if no effort was made to reverse natural tendency toward higher entropy. Source:

13 Software Entropy Software isn’t a thermodynamic system but the concept of increasing entropy or disorder applies just the same. As software is modified or extended its internal structure tends to degrade unless extra effort is devoted to making sure changes not only work but also leave the resulting code no harder to understand and modify. If extra effort isn’t devoted to controlling system entropy, future changes will be harder. Entropy in software takes the form of: Duplicate code. It’s often easier in the short run to copy-paste-modify code rather than factor out commonalities and represent separately only what is unique. Comments that explain “what” rather than “why” and comments out-of-sync with code. Classes that expose (don’t encapsulate) important design decisions and implementation details. Software entropy increases when principles of good design and construction aren’t followed. System entropy can be avoided or reversed by following the principles of good design discussed in chapter x and by applying systematic refactorings to recognized code smells as discussed later in this chapter. Often the quickest way to implement a feature is by duplicating related code with a slight modification for the new feature. The consequence is duplicate code that makes it harder to make changes in the future. A better solution is to make the change in a way the preserves the points of commonality and variability in the code.

14 Technical Debt Teams are often under pressure to cut the time and cost of enhancements. By compromising internal code quality and taking other shortcuts it is possible to rush features into production but not without consequences going forward. Technical debt is a metaphor for communicating these consequences to non-technical stakeholders. Software changes can be accelerated in the short-term by: Taking less time for design. Design time can be shortened by neglecting non-functional requirements like maintainability and testability. Writing and running fewer tests. Development time can be shortened by writing fewer tests and/or performing less regression testing. Also, some initial time might be saved by executing manual tests rather than taking the time to write automated tests that can be reran. Postponing needed changes to design documents. None of the above are time savers; they all time shifters. Skimping on design might help get a feature out the door but it will also increase complexity and the cost of making future changes. Missing test cases have to eventually be written or stakeholders have to accept a higher risk of errors. If documentation isn’t keep up to date, it will take more time for new staff members to come up to speed on the software. Software is intangible so managers and other external stakeholders you can’t see technical debt piling up. The technical debt metaphor can make everyone more aware of the amount of future liabilities a project is taking on. Your manager repeatedly asks you to rush features and bug fixes into production. You tried to explain to him the risks of hurried development but he doesn’t seem to understand. Perhaps you need to explain the dangerous using a metaphor he can related to. Perhaps you should introduce him to the idea of technical debt. What happens to this technical debt built up in a software system after the system is retired? The debt has to be paid off all at once before the software system can officially be retired. The debt retires with the system The debt can be paid off immediately or can be gradually paid down over several years. Any technical debt that isn’t paid off after the retirement of a software system should be rebated to the customer. Q. T/F Technical debt is the same as product obsolescence. False. Technical debt effects the cost of change. Obsolescence is a decrease in value due to technological change. At most high technical debt leads to a decrease in value due to inability to change a product. Technical debt is “the obligation that a software organization incurs when it chooses a design or construction approach that's expedient in the short term but that increases complexity and is more costly in the long term.” [Steve McConnell] Technical debt is a wonderful metaphor for communicating to non technical stakeholders the consequences of skimping on internal code quality in return for faster delivery. Taking these shortcuts amounts to borrowing from the future. You are incurring technical debt that must be serviced going forward. Software entropy and technical debt are being describe here in the context of software maintenance, but the concepts apply equally well to new development. Software entropy and technical debt are both metaphors for understanding and communicating the consequences/dynamics of different development approaches. As a metaphor, technical debt is more general and has broader appeal than entropy. Just about everyone can relate to financial debt. Fewer people understand physical entropy. Non-technical stakeholders who are more likely to be able to relate to financial analogies than scientific ones. Can think of increased system entropy as a technical debt that has to be serviced. A useful metaphor for understanding and explaining the consequences of increasing system entropy is technical debt. When maintenance activities are performed haphazardly, system entropy increases. This increase in system entropy can be thought of as technical debt.

15 Servicing Technical Debt
Taking these shortcuts amounts to borrowing from the future. The consequence for taking shortcuts during development is growing technical debt that must be serviced in the future. Certain types of technical debt have ongoing interest payments in the form of lower productivity / velocity going forward. Shortcuts that increase software entropy make it harder to understand and modify the software in the future. The extra effort needed to modify the software caused by increased system entropy can be thought of as interest payments on the technical debt. The greater the technical debt; the greater the interest payments. Don’t like spending (wasting?) money/time on interest payments? The alternative is to pay down the principle on the debt. Paying down principle on technical debt amounts to redirecting effort from new feature development to rework and/or catching up on work postponed (e.g. updating design documents, writing automated test cases, etc.) Taking on technical debt amounts to time-shifting costs.

16 Strategic Debt Not all debt is bad. Businesses regularly borrow money to purchase raw materials which are processed and converted into useful products. The products are sold at a profit relative to the cost of the raw materials and labor input. Voila! Wealth creation. While there is a range of personal views on debt, most people recognize good and bad (strategic and non-strategic) debt. Borrowing money to purchase a house or an education: good. Both have the potential to appreciate in value. Borrowing to finance a vacation to Tahiti: bad. Assuming a delayed vacation would be just as enjoyable (and maybe more enjoyable because you wouldn’t be worrying about how you were going to pay for it) you are better off to wait and pay cash. (Caution: Tax law greatly complicates the merits of debt.) Debt is a tool.

17 Strategic Debt [Cont] Debt (for an individual for a nation for a software system) is a beneficial if: The debt is small relative to income (or assets) (GDP for a nation, staff hours for a project) The debt is put to productive use. In other words, the benefits of time shifting purchasing power are worth the costs. In financial terms: there is an adequate return on the investment. Valid reasons you might take on technical debt: In order to meet a deadline or catch up with a competitor or beat the competition to market. You simply might not have the resources to finance “the right approach.” This is especially likely for cash-poor startup companies. You plan to retire the system in the near future. As long as the current changes work, who cares how unstructured the code is? Image is as of 6/9/2010. Today’s debt : GDP is, I think, 75% The benefits of Just as there are good and bad reasons for taking on financial debt, there are good and bad technical debt.

18 Non-Strategic Debt Unproductive reasons for taking on technical debt:
It’s just easier to throw together a solution rather than think it through. If management presses for features to be completed 20% of the estimated schedule, developers will work more efficiently. Anyone unfamiliar with the concept of system entropy and technical debt could inadvertently take on technical debt by not considering the consequences.

19 Strategic Debt [Cont] Sometimes it pays to take on technical debt. A team might hack some features in order to meet a deadline with the understanding that any shortcuts taken will be reworked or paid for in the future. (See notes below.) Figure X illustrates the strategic use of technical debt. The graph shows the rate at which features are added during two types of projects: one takes on technical debt early, the other avoids the accumulation of technical debt. Graph assumes same amount of effort over time for both types of development. There is a net benefit to taking on technical debt if there is important/consequential advantage to having X features before time B. Taking shortcuts allows you to have X features as early as time A. You get the features early but in return you have slower development moving forward. The slope of the lines represents productivity or velocity. Notice the slope of the debt-encumbered development approach is less than that of the debt-free development approach after time A. Technical debt accumulation is worthwhile only if the benefits of having the X features before time B is greater than the future costs of slower development and/or principle reduction (e.g. refactoring).

20 Retiring Principle When software entropy is a significant component of technical debt, you can get back to normal development rates by retiring principle. You can live with the slower development rate (continue to pay interest) (see figure x) or retire the principle (see figure y). Figure x illustrates how refactoring (and other types of rework) can lead to a reduction of principle (debt) and restoration of normal rates of productivity.

21 Understanding debt levels
National debt clocks—physical and virtual—are used to draw attention to the growing national debt in the US and around the world. As of 6/10/2010: How nice it would be if all software systems came with a technical debt clock that clearly showed the amount of technical debt in the system. Project managers could use it in planning. “Hum…looks like technical debt increased 10% since the last iteration. I had better make allowances for lower productivity during the next iteration.” During an acquisition the acquiring company could use it to estimate the value and liabilities of the company being acquired.

22 Understanding debt levels [Cont]
Unfortunately, technical debt, like many other forces of software development, is intangible and hard to measure. Some ways of assessing the level of technical debt being carried by a software system: Tracking project velocity/productivity. (Admittedly a lagging indicator.) A drop in productivity could signal a rise in technical debt. Track rework. What percentage of time is being spent on rework (corrective maintenance) as apposed to extending existing capabilities. Understanding technical debt levels is important for planning. If velocity (productivity) drops during a project that is a sign that technical debt has increased.

23 Lehman’s Laws of Software Evolution
The Law of Continuing Change – The environments around most software systems undergo continuous change. Systems in a changing environment must be continuously adapted or they become progressively less useful. Just as biological organisms must adapt to a changing environment (or become extinct), software systems must adapt or become progressively less useful and possibly extinct (retired). Continuous change in the environment is almost guaranteed because, in kind of a feedback loop, the addition of the software system is a change itself. The Law of Increasing Complexity – Recall from the discussion above that entropy is a measure of the disorder or randomness in a closed system. According to the Law of increasing Complexity, as a software system evolves its complexity (disorder) increases unless work is done to maintain or reduce it. (See notes below for a corollary to this and other laws.) A corollary of the second, first and seven laws is: the rate of system growth will decline as the system ages. Here’s the logic: According to the first and seventh laws, there will be pressure to make changes to any software system that is used. According to the second law, as changes are made to a software system complexity increases unless effort is devoted to maintaining or reducing the complexity. There is a finite amount of time and money available for work on the system. If you allocate it toward new feature development complexity will increase and the rate of system growth will slow. If you allocate it toward managing complexity you will have less available for new feature development. Either way, system growth slows. First law: systems that are used must change or automatically become less useful The entropy or disorder of a closed system tends to increase over time. Now for a little bit of theory. We will look at 8 “laws” of software evolution. These are called Lahman’s Laws of Software Evolution. Work on these laws began in the late 1960’s. The 7th and 8th law were formulated in 1996. Theory = “set of statements or principles devised to explain a group of facts or phenomena” Studying these laws will give you a deeper understanding of software maintenance. These “laws” apply to what he calls E-type systems. An E-type system is a software system that solves a real-word problem and is valid to the extent that users and stakeholders are satisfied with its performance. Law #2 can be used to justify preventive maintenance.

24 Lehman’s Laws of Software Evolution [Cont]
The Law of Self-Regulation – A self-regulated system tends to maintain a stable, constant condition. For example, warm-blooded animals maintain a roughly constant body temperature regardless of the ambient temperature. The program evolution process is self-regulating. Product and process measures such as number of reported errors and time between releases is invariant across releases. The Law of Conservation of Organizational Stability – The average output or production during maintenance is invariant over the product life time. The number of people devoted to system maintenance might increase or decrease but the effective output or production tends to remain the same.

25 Lehman’s Laws of Software Evolution [Cont]
The Law of Conservation of Familiarity – Users and other stakeholders must maintain a certain level of familiarity with the software from release to release in order to make effective use of the software. There is a limit to stakeholders’ capacity to assimilate changes. Consequently, the content of successive releases is statistically invariant. Stakeholders’ ability to assimilate new information bounds the amount of change allowed. The Law of Continuing Growth – Both the first law and this law say that E-Type systems are destine to grow. The first law says they will grow through adaptive maintenance in response to changes in the environment. This law says they will grow through perfective maintenance in order to maintain user satisfaction.

26 Lehman’s Laws of Software Evolution [Cont]
The Law of Declining Quality – The perceived quality of a software system will appear to decline unless it is rigorously maintained and adapted to changes in its operational environment. (see notes below for justification) The Feedback System Law – Evolution processes are complex multi-loop, multi-level, multi-agent feedback systems. This feedback must be taken into account when planning and following software evolution processes. This law generalizes the idea of feedback present in the other laws. Justification for 7th law: assumptions bound the behavior of any software system. For example, you might assume users understand the concept of a file system. Changes in the environment are likely to invalidate certain assumptions on which the software is built. For example, a growing number of users come to your application without understanding the concept of a file system. Unless you devote effort to identifying and rectifying assumptions that no longer hold, perceived quality is likely to decline. This is especially true when your application is compared to other alternative applications that aren’t based on the same assumptions. Perceived quality is based user satisfaction. This law is similar to the second law except rather than forecast increasing complexity this law predicts declining quality.

27 Reengineering Legacy Systems
Reverse Engineering Restructuring Forward Engineering Reengineering Maintenance concepts and terminology. Reverse engineering – create representations of the system in another form usually at a higher level of abstraction. Eg you might recover design from implementation (design recovery) Restructuring – transforming a system from one representational form to another at the same level of abstraction without changing functionality. Forward engineering – traditional new development: requirements -> design -> implementation Reeingineering – reverse engineering plus optional restructuring followed by forward engineering.

28 The lure of the complete rewrite
Legacy systems are expensive to maintain. At times it may seem like the answer is a total rewrite. A complete rewrite is (almost) never the best way to deal with the headaches of maintenance. The problems and cost of ongoing maintenance—as unpleasant as they might be—usually pale in comparison to the risks and cost of rewriting a system from scratch. Reengineering can be applied to a portion or the whole system. Factors that lead organizations to consider embarking on a complete rewrite: Code is ugly, hard to understand and hard to change. All code is ugly, hard to understand and maintain. Knowing what you know now, you could do a much better job. This is recursive. You will learn more during the rewrite. There is a newer more interesting language. How you write code is much more important than the language used. P 55 S/W maintenance Concepts and Practice

29 Things to consider before making the decision to rewrite a system
Cost. Maintenance is a relatively small incremental cost spread over time. Rewriting the software takes a large upfront investment. Consider the time value of money. How to handle the transition. Time spent creating a new system is time not spent maintaining the existing system. During the transition you will likely need to devote some time to maintaining the old system. The existing system embodies years of accumulated knowledge. Extracting or reengineering this knowledge can be difficult. The existing system has been tested for years. It will take several years before the new code can reach the same level of reliability. New code might be better structured and easier to understand but it is not likely to have fewer defects. Developers and management tend to underestimate the cost of rewriting software. They tend to forget or under appreciate the full scope of the existing software. Good example of the importance of Engineering economics. Engineers seek cost-effective solution to practical problems. Need to understand economics, ie time value of money, how cash flows are discounted, return on investment, etc. Almost certain to be on the upcoming PE exam for s/e engs.

30 Maintenance Process Models
Quick Fix Model – When a problem occurs, fix it and release the fix as quickly as possible. Skip making a detailed analysis of the long-term effects and don’t worry about degrading code structure. Using the quick fix model during maintenance is analogous to using code-and-fix during development. Might work for small, non-critical systems, maintained by a single person. Does deliver fixes quickly and cheaply. (It only delivers change economically if it doesn’t cause more expensive problems later.) Keeping up with preventive maintenance (keeping entropy low) gives you the option of doing quick fixes once in awhile. May need to do a quick fix (eg critical security vulnerability). Process models guide development. They tell you want to do and in what order to do it.

31 Maintenance Process Models [Cont]
Alternative to quick fix model: Adapt one of the more modern development models (spiral, staged, evolutionary prototyping, evolutionary delivery) to the maintenance environment. Maintenance process models have two stages not found on new development models: Evaluate need for the change. Not all defects have to be fixed. Not all requests for new features are economically justifiable. Understand the current system. You have to understand the current system before you can safely change it.

32 Generic Maintenance Process Model
A request for change is received (aka Modification Request or MR) Categorize change request (Corrective, Perfective, Preventive or Adaptive) and estimate priority. Analyze change request. Do impact analysis to determine ramifications of change. Is it feasible? Needed? Economical? Change control board (CDB) decides whether or not to accept request. Understand existing program and how to effect change. (Initial investigation and review might begin during step 3.) Design / Implement and Unit test change. System test and regression test Acceptance test Delivery

33 Defect Triage Consider gathering defect data at the point of failure (assertions are an ideal mechanism for accomplishing this). Statistics gathered will help direct resources where they can have the biggest impact. Number of users affected and severity of defect will determine priority. Error reports send back from users of Microsoft office indicate that about 20% of the defects cause 80% of the errors. Gathering statistics helps to identify the order in which defects should be addressed. Ref:

34 Maintenance compared to new development
Maintenance work is done within the parameters and constraints of an existing system It’s like the difference between waterproofing a basement during construction vs. after construction. It’s relatively easy to waterproof a basement during construction—you add a waterproof membrane to the outside of the basement walls. After construction this is the preferred method as well but removing the dirt around the walls and preparing the walls can take a fair amount of work. Waterproofing a basement after construction can be expensive and disruptive which tempts many homeowners into applying a quick fix.

35 Program Understanding
Maintenance has the added challenge of understanding the existing system as a whole and the specific parts that will be changed in more detail. About 50% of the total effort spent maintaining software is spent understanding the program to be changed. Strategies for constructing a mental model of a program: Top down – Start by studying top-level details of the program and gradually work down toward an understanding of lower level details. Bottom-up chunking – browse the detailed code looking for patterns or details that can be grouped into high-level, semantically more meaningful structures. Example: might recognize design pattern or programming idioms. Opportunistic – make use of both top-down and bottom-up techniques as the opportunity arrives. All the while you are building up a mental model of the program. Technique: During both strategies the programmer might make general hypothesis based on partial information and then seek information and then seek additional information that confirms or refute the general hypothesis.

36 Factors that affect program understanding
Expertise – The programmer’s knowledge of the domain and implementation technologies has a significant impact on program comprehension. Implementation issues – coding style, quality and quantity of comments, variable names, design. Documentation – is there external documentation? Is it up-to-date? External documentation is especially important when the original author is not available. Availability of program comprehension tools – static and dynamic analysis tools.

37 P 116 from Software Maintenance: Concepts and Practice 2nd ed.

38 Refactoring Code refactoring is the process of changing a computer program's internal structure without modifying its external functional behavior. Refactoring is a preventive change. It doesn’t change the programs functionality but it does make it easier to understand, modify and extend. Refactoring is a prescribed step in some methodologies. With TDD, developers refactor after getting a test to pass. Refactoring is a technique for dealing with software entropy. (Entropy = tendency for the structure or design of a software system to deteriorate over time as it undergoes changes.) Oftentimes refactoring is a better solution than rewriting the software. Refactoring = changing software in a way that doesn't change its functionality but does make it easier to understand, modify and extend. External behavior stays the same internal structure is improved. We have talked a lot about techniques for writing good code. This is a technique to improve existing code

39 Refactoring is more than just “cleaning up code”
The term refactoring may be used to refer to any general cleanup activity. What is being discussed here are systematic changes to code that address reoccurring or identifiable problems. What makes systematic refactoring different from “cleaning up code”? Systematic, disciplined changes. Code transformations that don’t change the functionality of the program. Solutions to reoccurring or identifiable problems in code. There are catalogues of refactorings which serve as handbooks for software engineers. (Engineers always favor routine solutions over original solutions.) Example code smell or pathology: duplicate code. The distinction is sort of like the distinction between design and design patterns. It’s only a design pattern if it is a solution to a reoccurring design problem. It is only a systematic refactoring if it is a transformation for a reoccurring or identifiable problem in code. Books on design patterns are another class of handbooks for routine solutions. Important ways that refactoring is distinguished from “cleaning up code”: Don’t change functionality; look to handbooks for the systematic changes that are needed to perform the refactoring; make changes in small steps; run tests after each step.

40 Many programming devolvement environments offer refactoring tools
Eclipse (right) Visual Studio (below)

41 Example Refactorings Encapsulate field – Make a public field private and add accessors. Extract method – Turn a sequence of statements into a method with a descriptive name. Inline method – (Opposite of extract method.) Hide delegate – Add methods to hide a delegate. Rename method – Change the name of a method to a more descriptive name. Etc. The solution will provide systematic steps for making the change and testing the result. Most break the change down into a series of change/test steps. Solution is designed to avoid introducing a defect. Introducing a defect while refactoring code can frustrating to managers and customers. They only see the negative consequences. Extract method – Maybe during a code inspection there is confusion about what some chunk of code is doing. Some might even sense a defect but the code is so hard to read it is hard to tell if it is or isn’t correct. You could add a comment but these can get out-of-sync with the code and if they do readers aren’t sure when to trust them. A better solution is to add some meaning using code; extract method and give the method a meaningful name. (Extract method example: take the merge code out of the quicksort implementation.)

42 Does the following code violate any principles of design?
It violates the Law of Demeter.

43 Hide Delegate Add a delegating method on the service for each method which the client is calling indirectly. Update client to call new delegating methods. Compile and test after adding each method. If no other clients need to access to the delegate object, remove the accessor method on the service for the delegate object. Compile and test.

44 Refactored Code This examples illustrates how software development can be elevated from ad hoc coding to systematic engineering: Write code Evaluate against known principles of good design If code is found lacking, apply systematic refactorings to improve it.

45 Maintenance Measures Measurement supports decision making.
Example measures: Size (LOC, FP) Complexity McCabe’s Cyclomatic Complexity Halstead’s Measures Understandability Maintainability Certain measures are indicators for other more meaningful attributes. For example, complexity is one indicator of maintainability. Halstead’s Measures = several measures which are functions of operations and operands From page 140 in Making Software: “The results shown in this chapter suggest that for non-header files written in C language, all the complexity metrics are highly correlated with lines of code, and therefore the more complex metrics provide no further information that could not be measured simply with lines of code.” “In our opinion, there is a clear lesson from this study: syntactic complexity metrics cannot capture the whole picture of software complexity. Complexity metrics that are exclusively based on the structure of the program or the properties of the text (for example, redundancy, as Halstead’s metrics do) , do not provide information on the amount of effort that is needed to comprehend a piece of code—or, at least, no more information than lines of code do. This has implications for how these metrics are used. In particular, defect prediction, development and maintenance effort models, and statistical models in general cannot benefit from these metrics, and lines of code should be considered always as the first and only metric for these models.” “cyclomatic complexity is a great indicator for the amount of paths that need to be tested in a program.”

46 Code Metrics in Visual Studio
LOC Class Coupling Depth of Inheritance Cyclomatic Complexity Maintainability Index = MAX(0, ( * ln(Halstead Volume) * Cyclomatic Complexity * ln(Lines of Code) ) * 100 / 171)

47 Cyclomatic Complexity—Defined
Cyclomatic complexity (CC) measures the number of decisions or branch points in a unit of code. Proposed by McCabe in the 1970’s. CC is a complexity metric that gives some idea of the maintainability of a routine. For example, a company might require formal review of all modules with routines that have a cyclomatic complexity > 10. CC is also used during testing. The CC of a routine is also the number of linearly independent paths through the routine’s source code. Visually, CC is the number of regions in the control flow graph. Each branch adds another region. (Add example that shows the regions. See page 131 in Making Software.

48 Calculating Cyclomatic Complexity
One way of calculating the cyclomatic complexity of a routine is to: Create the control flow graph for the routine The cyclomatic complexity of the routine is: V(G) = E – N +2 Where E = the number of edges in the control flow graph N = the number of nodes in the control flow graph

49 Example-1

50 Example-2 Compound conditions. The IF counts as 1 and each AND or OR in the IF statement counts as one. Alternately, you can think of it as each condition in an IF, WHILE, etc statement counts as 1. Notation: 2.1 means first condition in second statement.

51 Assumptions about control flow graph
Single entry and single exit It is a single connected component (i.e. one routine). The generalized formula for multiple connected components is: V(G) = E – N + 2 * P Where E = Edges N = Nodes P = Connected components

52 Cyclomatic Complexity—Example 1
Ref:

53 Cyclomatic Complexity—Example 2


Download ppt "Software Maintenance “Caveat Emptor: The cost of software maintenance increases with the square of the programmer’s creativity.” First Law of Programmer."

Similar presentations


Ads by Google