Refactoring code, or the process of rewriting code that
already works, is a vital part of maintaining the long-term health of a
software application. Most business
stakeholders do not wish to pay for this, though. Most objections I’ve heard fall under two
categories:
- Rewriting working code will provide no
- The need for refactoring is a sign that the
developer didn’t get it right the first time, and the budget shouldn’t have to
suffer for a development mistake
Both of these objections show a fundamental lack of
understanding of the software development process. Refactoring code is more of a software
maintenance process; just like getting your oil changed in your car or getting
your air ducts cleaned in your house are necessary maintenance. To see why, take a look at this scenario of
what could happen if you don’t maintain your code. In this example, I'm designing a page that
allows users to enter orders for widgets.
Business Leader: We
need to show this page to two types of users, Sales and Procurement (who fulfills
the order). Sales people will be able to
enter as many orders as they wish, but procurement will only be able to see or
edit orders that have been finalized by the sales person.
Pseudo-code:
If User is
Procurer and Order is Finalized
Show Page
Else If User
is Procurer and Order is Not Finalized
Hide Page
Else if User
is Sales and Order is Finalized
Hide Page
Else if User
is Sales and Order is Not Finalized
Show Page
This code is already pretty complex and is far from ideal, but it's manageable.
But as users see the system, they realize
that they need to make changes:
Business Leader: We
need to make sure that orders are completed on time, so Supervisors need to see
the page too, but they can’t submit orders.
They can send notes to parties involved and override settings,
though. Sales people need to see orders
they’ve sent to procurement.
Pseudo-code:
If User is Procurer and Order is Finalized
Show Page
Else If User
is Procurer and Order is Not Finalized
Hide Page
Else if User
is Sales and Order is Finalized
Show Page
Make page read-only somehow
Else if User
is Sales and Order is Not Finalized
Show Page
Else if User
is Supervisor
Show page
Hide finalization capability
Show supervisor-specific controls
Ok, I’ve seen worse.
Business Leader: Supervisors
talk to our customers, and we realized that they need to enter sales in as
well. But a supervisor can’t supervise
his/her own sale.
Pseudo-code:
If User is
Procurer and Order is Finalized
Show Page
Else If User
is Procurer and Order is Not Finalized
Hide Page
Else if User
is Sales and Order is Finalized
Show Page
Make page read-only somehow
Else if User
is Sales and Order is Not Finalized
Show Page
Else if User
is Supervisor
Show page
If Supervisor did the sale and Order is
Finalized
Make page read-only somehow
Else if Supervisor did the sale and Order
is not finalized
(We already showed the page, so we’re
good)
Else if supervisor did not create the sale
(We already showed the page)
Show supervisor section
Hide finalization capability
That's quite a bit worse.
You can imagine coming to this code as a programmer new to the project
and being confused by this approach. And
keep in mind that the harder the code is to read and understand, the harder it
is to make changes without introducing new bugs. Now, let's refactor:
Get the user that's viewing the page
If user can
read page
Show Page
If user cannot finalize
Hide finalization
If user
cannot edit
Make page read only somehow
If the user
is the order's supervisor
Show supervisor information
In a
separate area of the code, you’ll define the method of getting a user like
this:
If the user
is a supervisor
Get the supervisor information
If the user
is a sales person
Get the sales person information
If the user
is in procurement
Get the procurer information
Finally, we
would define each user separately.
Here’s the supervisor’s pseudo-code as an example:
Can I read
the page?
Yes
Can I edit
the page?
If I’m the salesperson and the order is
finalized
No
If I’m the salesperson and the order is not
finalized
Yes
If I’m not the salesperson
Yes
Can I finalize the page?
Only if I’m the sales person.
Am I the order’s supervisor?
Only if I’m not the sales person.
This code probably looks more complex than the first
example. However, by changing the code
in this way, we are hiding the complexity of the code for any given point in
time and allowing the developer to only see what's needed at any given
moment. Do you need to see a big picture
view of what's happening? Just look at
the top-level code. Do you need to see
what the supervisor can do at a given moment?
That’s pretty easy to do too. This
code is easier to read and edit, making bug fixes and adding new features
significantly easier, lowering the costs of maintaining the software significantly. Also keep in mind
that this is a relatively simple scenario.
Imagine looking at hundreds of thousands of lines of code that looks
like the last pre-refactored example.
Not pretty! So perhaps the next
time you’re faced with paying for refactoring code, try to imagine maintaining
this piece of software for years to come, and think of the long-term health of
your software.