I recently started working on a PHP application that was built many years ago before the advent of objects and namespaces in PHP. The code is procedural, does not separate presentation logic from business logic, lacks a front end point (front controller), and has files everywhere with a seemingly random folder heirarchy.
However, it works great for customers and despite the code mess it’s actually pretty fast.
I’d like to slowly move the codebase into something more maintainable and organized. I put MVC in this title, but truthfully all I really mean is an organized and maintainable.
Key objectives of this effort are:
- Not degrade the customer experience in any sort of way while this overhaul takes place (a rewrite is not an option)
- Fully separate views from logic
- At least have a “best practice” or method for implementing new application end points (routes)
- Have a consistent method or layer for persisting data
- Begin encapsulating as much code as possible in objects so that unit testing is feasible at some point in time.
7
OK, I am gonna make the foolish assumption that that by “without rewriting” you mean “without starting over”. Because once your project would qualify as MVC, you will have rewrote a significant portion of it.
I am not gonna lie to you, its gonna be hard. But it is doable.
Literature
The first thing I would suggest you would be to grab a copy of Michael Feather Working with Legacy Code. Its full of great advice on how to handle and work with the kind of code you describe. You should also grab Martin Fowler Refactoring and Joshua Kerievsky Refactoring to Pattern. Those techniques will very useful for changing your code.
How to work on the problem
Some important point as you work on your code are
- Avoid biting more than you can chew
- Always keep your code working
To handle the first point, make sure that you always change a little portion of your code at a time. For the second, make sure that you have acceptance test in place that will make sure that you don’t break the code as you change it.
The procedure I used myself when reworking old JSP file like your code was the following
- Isolate a specific functionality to rewrite
- Write a few Acceptance test that check the behavior (Selenium will be a very good tool)
- Now the fun part. Create a new empty class and a UnitTest Suite
- Read the code, find the simplest part of code you can put in your class
- Test the small statement
- Put the code of the statement in your class
- Replace the statement with a call to your class
- Refactor your class to make it readable, not being afraid to create new classes if you see multiple concern emerge. Don’t forget to refactor your test too!
- Go to 4, and continue until all the code is in your tested classes
Now, as you extract the procedural code in your class, you will start to see pattern emerge. Duplication will become obvious (old code like this tend to be pretty copy and paste). Reengineer your class to reflect your new comprehension of the problem.
One thing you may notice is that as you go, you will start to go quite faster, because the copy pasted code so prevalent in those application will already be in one of your refactored class. Then you will encounter code written by another person and you be slow again. Its normal.
Don’t hesitate to stop from time to time and move code around in your refactored class to create a nicer architecture. As you go, you may end up with an MVCish framework. Or you may have sometime that fit your problem in its own way. The nice thing is that you will a nice suite of test to cover you as you do.
Now of course, the problem is that you will want to add feature to the application sooner than later. You can use that. When you need to add something to a part of code, do the refactoring first for that part of code. That way, you will slowly improve the design as you add feature. Its gonna be slower but in the long run you will go faster because the code will be easier to maintain.
I wish you luck!
1
Any change you make to a software project involves reconfiguring (i.e. changing the data that the code uses) or rewriting (i.e. changing the code itself). Migrating from one style (procedural) to another (object oriented) is a significant change that will necessarily entail a lot of rewriting. Object oriented design isn’t something that you can bolt on as an afterthought. Adopting a paradigm like model-view-controller means rethinking and redesigning the project.
Donald Rumsfeld famously said:
…you go to war with the army you have, not the army you might want or wish to have at a later time.
It sounds like you need to figure out what army you have (how much can you reasonably change, and what tools and knowledge do you have at your disposal) and what battle you’re trying to fight (what do you really need to accomplish?). I really don’t think you can get to MVC without a lot of rewriting, but you might well be able to reorganize the code to make it easier to understand and maintain.
As far as you describe your project, i do not think it is possible to migrate this, without many, many changes to your existing code-base. You have to re-think every function of your program to convert it into this “new” paradigm (at least for your application)