Refactoring with an Installed User Base


Refactoring with an Installed User Base

How do you refactor code once the system has an installed user base? Answer: With difficulty (as we explain in this section).

XP makes the correct assumption that we want to get the product into the hands of the users as soon as we possibly can. However, the Extremos idea of as soon as possible is quite different from ours, as this quote from Extreme Programming Explained indicates:

GROUCHO  

Most projects seem to have exactly the opposite strategy. The thinking seems to go, ˜As soon as the system is in production, you can no longer make interesting changes, so keep the system in development as long as possible. This is exactly backwards . . . . [20]

Keeping code in development for as long as possible has its own set of problems (lack of early feedback from the customer and big-bang delivery are two of the worst). However, releasing code to the users as soon as possible is really the other extreme, equally undesirable, and brings with it its own particular set of problems. Yet this is what XP tells us to do:

You are going to have to live with supporting production and developing new functionality simultaneously . Better to get used to juggling production and development sooner rather than later. [21]

All Maintenance, All the Time

The problem with releasing code too early (done the XP way) is that the design is likely to be nowhere near finished. Say the users are given production-ready code after just 3 weeks of the project s inception. On the surface, this seems great: The users can get productive straightaway, even though the initial set of functionality is probably quite small. However, the whole point of XP is that the design gets refactored as you go along. The module that was released after the first 3 weeks was designed purely to facilitate the tiny amount of functionality that gets unleashed along with it.

Consider that the final release, in about a year s time, will be a panther (not literally, of course). The first 3-week release would have been little more than a mouse in comparison. There is clearly still a serious amount of design work to be done. In a year s time, it s probable that none of the first 3 weeks worth of code will still exist in the live system.

FANGS  

Typical problems with refactoring live code are as follows :

  • The product needs to be reinstalled or patched (although a live update mechanism, such as that offered by NetBeans and other application frameworks, makes this less of a problem).

  • The product needs to be regression tested (unit tests should handle this, but the fact that a live system is being regression tested means that the unit tests are being relied upon even more heavily than before ”Fangs, the slippery -slope serpent , just got venomous).

  • The users may need to be retrained if the user interface (UI) has changed (a likely prospect, because the UI design will be evolving equally as much as the code design). See the next section, Annoying the Users: Refactoring a Live User Interface.

  • The database contains live data, therefore any changes to the database structure involve writing an update script that must be fully tested on a development database and then run on the customer installation. We discuss this shortly, in the section Really Annoying the Users: Corrupting Their Live Data.

  • User manuals and/or help screens (if there are any) may need to be updated.

Are the XP practices really sufficient to refactor live production code from a mouse to a panther, without breaking the user experience or corrupting the data? Possibly, with creativity and perspicacity, and lots of unfailing hard work to keep the snakes from unraveling.

But there is a better way. . . .

SOLUTION  

An easier approach is to spend more time up front on the architecture-and design (doing both design modeling and prototyping). Try to stabilize the internal design as much as possible before any production code gets released to the customer, and employ a professional interaction designer to spend time with the users to get the UI right from the start. Even a few extra weeks spent doing this can make all the difference. This doesn t mean that the entire design has to be implemented in code before anything gets released. The code can still be developed and released in small increments of 2 to 3 weeks, but the time spent getting the design right up front stabilizes it considerably, so that much less refactoring needs to be done on installed code.

start example

We discuss this refactored approach in more detail in Chapter 15. Also see Chapter 12 for a discussion of early prototyping versus XP s emergent design approach.

end example
 

The recent industry spotlight on XP and agile methods has created an emphasis-on refactoring existing code: jumping into code without spending enough time getting the design right first, and then fixing it up later. The resultant common wisdom that is beginning to emerge is that it isn t possible to get the design right before you begin writing production code. However, nothing could be more wrong. There are tried and trusted logical design processes that have been around for years and that have been proven to work on countless numbers of successful projects.

Annoying the Users: Refactoring a Live User Interface

FANGS  

Refactoring of the UI isn t something that has really been addressed by the Extremos. In an evolving product, however, the UI design is equally as dynamic and volatile as the code design.

When a new version of a system is delivered, end users frequently complain about the changing UI. The problem is multiplied with an incrementally delivered system, simply because there are so many new versions (one every few weeks). Just when the users get used to doing things one way, everything is moved around to accommodate a change or addition in functionality. For example, a Tools drop-down menu might be added to house the increasing number of system tools that until then were located in various ad hoc parts of the system (which made sense at the time for each individual tool). The trouble is, the users will have grown used to going to those ad hoc parts of the system to achieve their tasks . People are creatures of habit. When it comes to such day-to-day routines as using the computer system at work, they resist change.

UI improvement of the type described should not be avoided if there is a chance to improve the user experience; but the same users that you are trying so hard to please will invariably be annoyed when things change. In fact, continually changing the user interface doesn t just annoy the users, it can also be expensive if it involves retraining or a settling-in period as the users grow accustomed to the new layout.

UI refactoring is inevitable and necessary in an evolving system. That s why it pays to at least try to get it right early on, so that the amount of change to the live system s UI is minimal. This means spending a little extra time up-front thinking about the user experience, not just for the tasks that are implemented during the first three weeks, but the sort of tasks they will be performing in six months to a year s time.

We mentioned earlier on (and also revisit in more detail in Chapter 15) that it is well worth employing an experienced interaction designer (i.e., someone who designs user interfaces for a living). Generally, programmers ( myself included) are not the best people to design user interfaces, because they think in terms of the solution, not the user s goals. Similarly, users are not the best people to design user interfaces, because they have neither the experience nor the training. Conversely, an interaction designer ”a good one, of course ”can get the user interface right, because she knows what makes a good user interface, and understands the user s goals probably better than the users. Because the product is essentially driven by its required behavior, getting the interaction design right early on can drastically reduce the amount of internal redesign (hence refactoring of code) needed later.

Really Annoying the Users: Corrupting Their Live Data

Warning: FANGS

Most business applications use a database. However, databases are also a recognized problem area for refactoring. [22] Using emergent design, it s rare that a system will start out with a complete database, with all tables and relationships even identified, let alone fleshed out. The problem is also intensified by XP s emphasis on short (2 to 3 week) iterations.

Refactoring Live Data

As the design evolves, the database design will need to be refactored almost as much as the code design. In XP, the YAGNI principle applies equally to the database design as it does to the code. Therefore, database tables will be added, removed, merged, and separated; relationships will change from one-to-many to one-to-one and back again; constraints will be added and removed; data types will be changed; and enumerated types will be added, extended, and turned into dedicated lookup tables as their complexity increases . It s a process that every database design goes through, until the ideal design for the complete system is reached.

And all of this will be taking place on live data. This is something that the Extremos expect and in fact encourage (see http://martinfowler.com/articles/evodb.html ).

This means that for every database change, you ll need to write a script that updates the user s database, migrates data between tables, changes data types, introduces new constraints and massages the existing data to fit, and so on. Each script will also need to be thoroughly tested before it s run on the live system. The only way to really prove that the script works is to get hold of a copy of the customer s entire production database, but this isn t always possible (for either technical or political reasons).

And, of course, all users will need to log out while the update script is run. That could mean regular disruption every couple of weeks or so. (Of course, your team could update the system in the middle of the night, but then it breaks the XP rule of going home at 5:00 PM.)

start sidebar
VoXP
Voice of eXPerience: Refactoring the Database

by Robin Sharp

The following is a description of database refactoring hell. Database change was constant. We did releases every week, and for most releases, we had at least one migration script to run. The database was never stable enough to refactor as a whole. The whole thing was aggravated by not having an up-front object/relational design scoped for each major release. It was like being forced to make it up as we went along, even though we were capable of producing a better design.

Relational databases demand conformant relational models, and we couldn t deliver that. The DBAs lost confidence in the developers and spent most of their time tuning queries to get any sort of performance.

We also did evolutionary database design. If you changed the database, you had to write a migration script. We each had our own development database. It worked okay-ish, but I guess you would soon run into license issues (i.e., very expensive). Because we each had our own database, we also had CPU issues, which slowed dev performance.

You could maybe get around this by having many database schemas on one server ”but again, there would be licensing issues, plus some serious admin issues, I would think.

I would also have liked snapshots of old databases for bug hunting and defect tracking (but some databases got very large and we couldn t simply load old databases up).

In many cases, it s hard to see how you can avoid this.

end sidebar
 

Shielding the Code from Change

A common problem is when database access code is tightly coupled to the database design. The result is that making changes to the database means making changes to the source code. This is a highly problematic aspect of refactoring an emergent design.

Normally, the solution is to create a layer of abstraction between the code and the database: business objects. These business objects encapsulate the database design, so that the client code doesn t need to care about the structure of the database or implementation details of the database access code. Instead, it just calls the interface of each business object, which exposes database- agnostic methods such as findCustomersByZipCode .

The code can be further shielded by not basing the object model directly on the database model (as described in the article Why Data Models Shouldn t Drive Object Models [And Vice Versa] [23] by Scott Ambler).

Some database changes are more costly than others. For example, simply adding a column or a new table won t affect existing code. However, changing existing metadata (which Fowler describes as destructive changes [24] ) requires a stringent and time-consuming refactoring process.

Taking the refactoring approach for such a change is definitely less risky than simply making the change without any safety nets , but it s less risky again to concentrate on getting the design right as early as possible ( ideally , by following a logical design methodology that guides the programmer into making good design decisions).

Having said that, XP s approach of planning for change is worth keeping in mind. However, we prefer to manage change rather than embrace change.

start example

We discuss managing change (over embracing change) further in Chapters 13 and 15.

end example
 
start sidebar
How Simple Is Simple Enough?

The problem in XP-land is that adding extra layers of code is considered to be extra complication: We are adding unnecessary code just in case we need to make a change later on. Having an extra layer of code is not the simplest thing that could possibly work, and yet paradoxically it is the simplest solution to the problem (considering that the problem is not just about here and now, but also about how to keep the code simple in the long term ).

Conversely, adding a layer of indirection is sometimes precisely what you don t want to do. A layer of indirection adds value if it ultimately simplifies the code; otherwise , it simply adds complexity without really giving you anything back. One of the keys to effective software design is learning to tell the difference. In this regard, we actually agree with the Extremos: The code should be made as simple as possible and no simpler.

Where we part company, however, is in the Extremo approach of making code as simple as possible for the current 1-week iteration, then redesigning it the following week, and so on.

end sidebar
 
start example

More about this emergent design approach in Chapter 12.

end example
 
FANGS  

Enter the Fang

The constant refactoring snake is driven by these issues:

  • Refactoring is not inexpensive.

  • Refactoring is time consuming.

  • Criteria for when to stop refactoring are not well defined.

  • Releasing code prematurely to the users puts you in all maintenance, all the time mode.

  • If it ain t broke, don t fix it is still good advice.

  • Refactoring of databases is problematic ( especially for live databases that must run 24/7).

  • Refactoring of UIs on live production software is problematic.

Pretending that refactoring is neither expensive nor time consuming, for example, places greater stress on the other XP practices to perform in order to keep the circle of snakes from unraveling.

LackOfUpfrontDesign (LOUD) leads to Constant Refactoring After Programming, which explains why SoftwareIsNeverDone in XP.

Refactoring Defanged

Knowing when to stop refactoring is critical to keeping the software on schedule. XP recommends looking for areas of problem code and refactoring whenever you see such areas. With a detailed architectural model, however, it s possible to be more selective and only refactor the areas that are still being built or have dependent code still to be built. Tracking defects and identifying defect hot spots in the system can also help to identify which areas need the most refactoring.

SOLUTION  
start example

We cover management of refactoring in Embrace Rampant Scope Creep Regularly in Chapter 11.

end example
 

Although refactoring is useful, designing the system up front using proven design techniques massively reduces the amount of refactoring that s needed later. Effective requirements elicitation reduces requirements churn, which in turn reduces the amount of redesign that will be needed.

Hiring a professional interaction designer early in the project can help to reduce the amount of UI refactoring necessary, which in turn reduces the amount of user retraining needed every time a new release goes out the door.

[20] Kent Beck, Extreme Programming Explained: Embrace Change (New York, NY: Addison-Wesley, 2000), p. 32.

[21] Ibid., p. 32. Also see the sheer thrill quote in the section The Perpetual Coding Machine (Embracing Change) in Chapter 13 of this book.

[22] Martin Fowler, op. cit., p. 63.

[23] Scott Ambler, Why Data Models Shouldn t Drive Object Models (And Vice Versa), http://www.agiledata.org/ essays /drivingForces.html, 2003.

[24] Martin Fowler and Pramod Sadalage, Evolutionary Database Design, http://martinfowler.com/articles/evodb.html.




Extreme Programming Refactored
Extreme Programming Refactored: The Case Against XP
ISBN: 1590590961
EAN: 2147483647
Year: 2003
Pages: 156

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net