views:

61

answers:

2

Hi,

Consider that you have "System_A" which is a web application. And System_A has simply 3 layers: UI, BusinessLayer and Data-Layer.

And now you want to make a widespread refactoring of System_A (the UI and BusinessLayer only) meanwhile that is working as a live product.

What should be the safest strategy of refactoring System_A and release the refactored product after a good testing -let's call it "RF_SystemA"- in a way that it can be reversed to System_A even in case of an unexpected bug (without forcing the users to change their URLs)?

Thanks, burak ozdogan

+5  A: 

First of all, you should have enough unit tests to cover the critical parts of the code. (If the UI and business logic is not separated well, making the logic difficult to test, you may need to lean more on functional/integration tests until you separate the layers enough to make the business logic unit testable.)

You should also have test/staging server(s) apart from the production one(s), where testers and users can verify that the new code is working well.

Then you can make small changes in the code, step by step, verifying after each step that all unit tests still pass.

After major milestones, you deploy the refactored app to the test/staging servers and run larger scale integration/functional/performance/whatever else you have tests.

If after all tests, you are happy and confident that the code still works as expected, you may deploy it in production.

Should a bug pop up after all this, you can easily return to the latest safe version in production. (And after that, you can start investigating how the bug slipped through and how to avoid this happening again...)

Péter Török
Thanks PEter. Question: Do you think it is a good idea to have a copy of the System_A's parts and do all the changes on it. So you keep both refactored and old system's code for some time and it gives you an advantage of seeing what was changed more easily? And after some time you can delete the old system's code completely.
burak ozdogan
@burak, this is what SCM is for. I assumed you are using source control - if you don't, start with that. There are several excellent open source solutions like Subversion, Git or Mercurial - pick one. These also make it possible to use a separate _branch_ for the refactoring while adding new features on the main branch - although I don't recommend this in the longer term. But when used with specific short term goals, it can be a good solution.
Péter Török
@Peter: Peter, I am familiar with svn. But I think I could not express my need clearly. Nonetheless, B3ret's answer was what I was looking for to hear. Thank you for your recommendations as well.
burak ozdogan
+1  A: 

I haven't much to do with Web-Development, but just an idea:

You could write/generate a redirect-Layer first like so:

Let's say you had three functions in System_A like this:

System_A.Call1(...)
System_A.Call2(...)
System_A.Call3(...)

Then you could rename the calls like this...

System_A.Call1(...) -> Old_System_A.Call1(...)
System_A.Call1(...) -> Old_System_A.Call2(...)
System_A.Call1(...) -> Old_System_A.Call3(...)

...and create a temporary redirect system like this:

System_A:Call1(...) { Old_System_A.Call1(...); }
System_A:Call2(...) { Old_System_A.Call2(...); }
System_A:Call3(...) { Old_System_A.Call3(...); }

This system could go live immediatly.

Then you could create your Refactoring classes bit by bit, test them and just change the redirection calls. After refactoring is complete, you remove the redirection calls and just use the reafactored system.

The granularity of your redirection should correspond to the granularity of your refactoring. So if you refactor individual functions and the function signatures stay the same, you can use the approach as stated above. If you completely redesign whole parts of your system, you could redirect the whole parts.

Example for web: You have index.php which mainly calls 3 functions: header(), body() and footer().

You could either redirect the calls to header, body and footer (if the signatures stay the same), or you could redirect the whole thing and call only one function from your index.php like "currentIndexPhp()";

currentIndexPhp() would then initially call header, body and footer.

If you organize your folders and files accordingly, you should be able to control the refactoring quite nicely.

B3ret
Ok the above answer is definitely the better one. Mine is like for the poor man's small webproject ;-)
B3ret
@B3ret, the potential problem with this is that it lends itself very easily to "patching" by changing redirections on the fly back and forth. This can lead to chaos, when noone anymore can remember for sure whether a specific functionality of the system is using the old or new implementation in production. Also, this can lead to a combinatorial explosion of system versions to test. So it requires _very_ disciplined developers to do it right. Or, as you say, a small project. Btw thanks for the compliment :-)
Péter Török