views:

86

answers:

5

I am developing on a system that is a bit difficult to work with. It is 99% undocumented, does not follow best practices and is fairly difficult to understand (globals galore, methods spanning 50 lines, eval abuse, etc.). Unfortunately, I am fairly new to the code base and I need to add functionality.

I am sure there is code in there that I could reuse, but I have to meet a deadline and am afraid that the time spent salvaging will end up with me rushing at the end. What is better in the long run? Part of me wants wants to reuse as much as possible, but another part says I should focus on writing the new functionality from scratch, at the risk of duplication (with a plan to refactor when I have more time to spend with the existing code)? I'm leaning towards the latter but wanted to hear some opinions.

Thanks!

+4  A: 

http://www.joelonsoftware.com/articles/fog0000000069.html

http://discuss.joelonsoftware.com/default.asp?design.4.469415.13

http://www.joelonsoftware.com/articles/fog0000000007.html

http://www.paulgraham.com/hp.html

That being said, if there are small sections to clean up, that's usually fine. Once you have been working on it for a while, you'll have a better idea of where a strategic, localized rewrite will be most effective and least dangerous.

In a production code base, remember that keeping things status quo for the client is more important than getting new stuff out the door. It won't stop your boss from yelling at you. But ask yourself how many times you've switched to an alternate product because of bugs, versus how many times you've done so because the enhancement you wanted wasn't fast enough in an otherwise workable product.

eruciform
Yea, I've read a bit on the rewrite vs refactor debate...in this case though it's not really a rewrite. I'm actually adding features and am pondering whether I should bother spending a lot of time looking for existing code that I could reuse to avoid duplication...or just write everything for the new features and be comfortable in my time budget, then refactor the duplicate code at a later time. No old code would be touched.
rr
the best i could offer without looking at the code base is to learn from the old code base. the first article i like a lot because it reminds me how much time and effort of bug-fixing went into legacy stuff. why is this-or-that odd case in there? probably because someone spent a week factoring out an obscure bug. don't overuse global variables unless you need to - and sometimes legacy is so replete with them, that you have to because the globals are now part of the "interface". bringing back lots of memories of 20-year-old fortran 2 jobs ago. :-)
eruciform
I agree, I realize there's quite a few variables going on and it's not so cut and dry, I suppose that's why I pose the question. I think I might try and get the best from both worlds - give myself x amount of time to find code to reuse and then go from there.
rr
i think that's wise. especially in a new code base. learn the lay of the land before you plan your conquest of it. sun tzu would be proud. :-)
eruciform
+2  A: 

I'd go with your instinct: write it the way you know how. TDD, if that's your approach; at any rate try to make sure your new stuff is reasonably well test-covered (and, of course, less of a mess than what's in there now).

Down the road, you might indeed get the chance to refactor, to find duplicated functionality, and choose which methods & classes to keep; it's likely that in those cases you'll find your own are the keepers.

And, of course, it's entirely possible that "down the road" will never come. At least your new stuff is working, readable, and reusable - and that's a better situation than if you took the time to track down a function in the existing code base (as you have described it) and reuse it.

Carl Manaster
+1  A: 

Everything you are experiencing can be overcome by reading Working Effectively With Legacy Code. I know you said you were on a tight deadline but rushing and not fully understanding the core code base could (and probably) have some negative side effects.

Also, you mention planning to refactor once time permits. I've said that many times and let me tell you that almost always that time never comes. Do it right the first time and do yourself a favor for the next developer or when you add new features later on.

Mike
Thanks for the book recommendation. I do realize that the "I'll do it later" attitude is dangerous, I think that's a big reason I'm hesitant to just go with it.
rr
A: 

We're in this same boat at my business: Phase one went a direction that worked, but was not ideal. Phase two changed the business model and logic.....this phase was offshored, which itself wouldn't have been a problem if the company had actually understood the framework they chose to build on. So, here we are trying to finish phase 3 (undoing the mess of phase 2, properly using the framework as it was intended) while lamenting having to work on such a poorly written codebase. There were significant challenges--the use of two javascript frameworks, clunky legacy UI, junk code, and a major update to the framework that makes the version we're on obsolete and near impossible to migrate to a new version.

Here's what we've chosen to do....it may not be ideal for your situation. First, our VP of product development took two weeks and completely re factored the database structure. He re purposed our programming staff to modify existing code as necessary to accommodate the proper, efficient DB structures. Once that (painful) step was done, we took a two week break to make progress on new features. Then, I took a break from my duties to completely refactor the UI, un-doing the use of one Javascript framework so that we're on one common platform (what a concept, hint-hint awful offshore company...) and making effective use of modern, efficient, current UI elements. We'll be following an 80%-20% mix of tasking until the product is out of beta--80% achieving finalized requirements, 20% refactoring code and cleaning up the legacy mess. Each employee has been given an area that they are responsible for "cleaning up" or making more efficient. Documentation of the processes is also a task that's been delegated and is a required percentage of each employee's work week.

I think the key to the success of our process is an eye toward phase 4 even before phase 3 has been completed. New code is being built with maximum efficiency and interchangeability, so if and when we move off this outdated platform, minimum changes will be required. I'm experimenting with a way to compartmentalize our processes (not just the code) so they could theoretically be individually moved to a new framework when the time is right. Our future plans are on paper, with a requirements list evolving and research in progress for finding the best tools. Most importantly, the team leader is a stickler for doing things correctly and efficiently, so nothing current or future will go forward that's not done right.

It's tough to justify to management that you need to go backward to go forward. It's even more difficult when your company's entire future is dependent on a product that's stuck in beta as we were. I compare it to spending more for a fuel efficient appliance....it's going to cost more now, but ultimately it's going to reap huge financial rewards. I think the trick to being successful in this situation is finding the median for your product where it's "good enough" to stand alone while you spend time to make the product great. Developing a strategy to meet that median will challenge the business unit to be patient, and ultimately will make you the hero when it succeeds. Develop a strong plan, communicate that plan, play well with others, and work your tail off. In no time, you'll be enjoying life again!

bpeterson76
A: 

Don't worry about this small piece of functionality you are adding. Do it quick and dirty.

If your team is planning a refactoring of the source code, make sure you have the support of your management. Let your management know about the issue you are now facing: the current codebase is not following best practices. The more unstructured the application becomes, the more time it will take to add functionality. Building the new functionality will not cost the most time, but making sure it will behave as expected in every situation will, and fixing the problems when something goes foobar will also cost valuable time.

If you were to refactor the application, think about the gains you would have if you would choose some readily available solutions to better implement parts of your application:

  • An MVC framework like Zend Framework
  • The Zend Framework Class library for often-used components like Auth/ACL/OAuth/etc.
  • A database abstraction layer or ORM like Doctrine or Propel
  • Just one javascript library: JQuery (perhaps combined with JQuery UI)
  • Automatic deploy systems like Phing and Ant
  • Unit testing for your classes
  • Acceptance testing based on Use Cases using Selenium
  • A well though-out version-control system and strategy

I could go on for a while. Sometimes a complete rebuild of an application is two steps back, but four or five steps forward.

Symen Timmermans