Slashdot Mirror


When Making a Comprehensive Retrofit of your Code...

chizor asks: "My programming team is considering making some sweeping changes to our code base (150+ perl CGIs, over a meg of code) in the interest of consistency and reducing redundancy. We're going to have to make some hard decisions about code style. What suggestions might readers have about tackling a large-scale retrofit?" Once the decision has been made for a sweeping rewrite of a project, what can you do to make sure things go smoothly and you don't run into any development snags...especially as things progress in the development cycle?

41 of 385 comments (clear)

  1. Use a pretty printer by renehollan · · Score: 2, Insightful
    for consistent style...;


    refactor as a result of learning from your mistakes and redundancies;


    and try to minimize the busy parts (where all developers have a hand) when things change (like lists of unique symbols, numbers, etc.)

    --
    You could've hired me.
  2. Sleeping dogs by Chairboy · · Score: 5, Insightful

    I'm sure a bunch of code nazis will disagree with me (please note the clever way I attempt to pre-emptively undermine their arguments by labeling them as 'nazis') but sometimes massive engineering re-writes are not necessary.

    Your tangled mass of spaghetti code paths are probably full of almost incomprehensible little design decisions and seemingly out of place declarations and functions, but most of those were probably added as specific fixes for bugs encountered under real-world use.

    Most companies that decide to massively re-engineer their code (do a big rewrite) usually end up regretting it because it forces them to re-fix the problems that caused the original strange looking code in the first place.

    Does your CGI nest work? If so, maybe you should leave it alone. If you are fixing specific problems, then go ahead, but if this is a generalized attempt to fix the 'not invented here' syndrome that plagues engineers (who will almost universally agree that it is easier to write code then it is to read it), perhaps you should reconsider.

    1. Re:Sleeping dogs by Nyarly · · Score: 5, Insightful
      Certainly, but if you find yourself trying to make a change to existing code, it will probably not be the last change you need to make. At least refactoring anything your change touches will make future changes easier to make.

      Related note: the original poster doesn't say "refactoring" and he does say "Perl." Informative statements relating to these two facts:

      • Buy and read Martin Fowler's Refactoring. The examples are mostly Java, and he references the Group of Four's Design Patterns. "Retro-fitting," in which you probably plan to rewrite portions of code from scratch will break your app, your mind, and your budget. Learn what refactoring implies and entails.
      • Learn about design patterns in general, and consider how they might apply to your code. One description of a design pattern is "a target for refactoring."
      • (Donning asbestos) You might want to reconsider perl as the language of choice for a large scale application. I realize I'm posting this comment to a Perl system, but Perl hangs together like an immense kludge of a language. That said, you're probably stuck with it, and AFAIK, you may be forging new paths in programming for reusability by applying the above concepts to Perl. Good luck, and be sure you can trust your machete.
      --
      IP is just rude.
      Is there any torture so subl
    2. Re:Sleeping dogs by thogard · · Score: 3, Insightful

      You can't engineer your code from the beginning in the part of the real world where I work. I've got a huge mess of perl that do reports and about one out of ten clients wants something different. These request could have have been predicted since many of them have no business reasons and have no function other that look more like their older system which just happed to have done it that way.

    3. Re:Sleeping dogs by sunking · · Score: 3, Insightful
      So you're saying your problem is too hard to be solved with a clean design? Good software design is all about preparing for the unexpected! In fact, if you ever had a perfect understanding of the problem then it wouldn't be worth designing a solution carefully - you wouldn't need the flexibility!

      Thinking that writing one-off code is giving you flexibility is grave mistake.

      -sam

    4. Re:Sleeping dogs by bmajik · · Score: 3, Insightful

      "Mission Critical" does not imply C. Infact, it points away from C.

      Unless you're writing an operating system, why use C ? What does it buy you ?

      IIRC, the Avionics system of the F-15 is done in Ada, because its "Safer" than C. I'd say thats "Mission Critical".

      I too am weary of perl, but like everything else, its the right tool for _some_ jobs, arguably, some pretty important jobs.

      --
      My opinions are my own, and do not necessarily represent those of my employer.
    5. Re:Sleeping dogs by Anonymous Coward · · Score: 1, Insightful

      This is a very common mistake that I've been seeing lately.

      Frameworks can be used to great effect where each client wants different things out of the same module. Understand the problem at the highest level and create protocols for solutions for the class of problems. Implement common aspects of all solutions as part of the framework. Then each specific solution for a customer can be implemented as a very small add-on module.

      Check out the ideas of framework in OO.

      I've used this pattern successfully in several large-scale systems over the last 8 years. It works whereever there are uncertainties about customer requirements. And, especially, where it is certain different customers will have different requirements.

  3. CYA by The+Gardener · · Score: 5, Insightful

    Don't stop maintaining the old code code until the new code is on solid ground. No matter how sure you are that you can do it, the new code might never come through.

    The Gardener

    --
    --
  4. That there is no such thing... by pyrrho · · Score: 4, Insightful

    You are going to rewrite the system from scratch. Design from scratch. Your new design might be able to use some old code, if the old code is useful.

    A large scale retrofit is really an oxymoron.

    IMHO, but with 15 years experience.

    --

    -pyrrho

  5. Document by Tosta+Dojen · · Score: 5, Insightful
    I suppose what I have to say almost goes without saying, but I know so many programmers who neglect it, I will say it anyway. There are two things you have to know when going back into old code.

    1) Know what you are doing. 2) Know what the code does.

    Both are expedited by good documentation. This is so important, it deserves to be written thusly:

    DOCUMENTATION!

    Write everything down. If the code is not commented, figure out what it does and write it down. When you add a line or a module, write down what it is supposed to do. Declarations? Write those down too. Document everything so that you can figure everything out, both now and down the road when you decide to fix something else.

    This is the voice of experience. I have had to reverse-engineer my own code 6 months after I wrote it because I failed to document anything. Learn from my mistake.

    --

    I have a strong belief in the Second Amendment.

  6. Think again by pkphilip · · Score: 2, Insightful

    From what you say, you are planning on making these changes to clean up the code and make it prettier.

    I would strongly urge you to reconsider this as the probability that you will end up breaking parts of the code while "cleaning" it up is quite high..especially since you seem to have a fairly large code base ~1MB

    Ugly code containing redundant stuff is still better than beautiful code that doesn't work.

  7. Architect it to death by ADRA · · Score: 2, Insightful

    There is no use in doing a rewrite unless you do it right from the beginning. If you can't spend a decent amount of time planning the architecture of the system, then stop now, and quit.

    Also, since you have decided to pour resources into this thing, then my opinion would be to make as much of your code generic so that you don't have to make code changes later. It doesn't matter if there is an initial performance hit with the systems, becuase in the short term, you can convince your boss to get a new leet server, and in the future, hardware needed to run your apps will be trivially cheap anyway.

    If you are going to cut a new release, try to avoid going back and taking snippets of code from your old system. It makes people slide back into the odl paradigm and can cause detrimental effects on the bottom line of your new system. This is new, so the least exposure to the old one, the better.

    --
    Bye!
  8. Agreed by ackthpt · · Score: 1, Insightful
    A large scale retrofit is really an oxymoron.

    Often I've had to modify systems which, once I understand how they work, which parts are actually still used, what's redundant/poorly written, I've usually pulled off changes in 1/2 to 1/5 the amount of code. Nice, neat, clean well documented stuff, too.

    --

    A feeling of having made the same mistake before: Deja Foobar
  9. Don't Listen by augustz · · Score: 5, Insightful

    A ton of people will tell you a ton of things, never having retrofited anything.

    - Do not undervalue the investment you have learning your existing coding language. New challenges await you if you jump on a new language like java. Make the jump if you are excited about learning about the new language.

    - If you use your existing coding language you will literally fly through the retrofit. Do it piece by piece. Make all those changes first, then test app, then make next set of changes then test. The simple fact is, most wasted time is spent on bugs not working on performance, and you've already knocked down a lot of bugs, don't let them pop back up by blowing everything up. There are books on this.

    - Sometimes blowing everything up is worth it. Do it right this time. Realize it won't be as perfect as you might think it will be.

    - Remember there are countless open source and shareware products that tried to create TNG with a total rewrite, got nowhere, and ended up improving their existing product. Remember the lesson, bite off what you can chew.

    - Spend a week poking around researching possibilities. I do this all the time, bookmark things I think are important. Then for the next project you've got all the little things you might forget at your fingertips. Optimzations/Tools/Paradigms. Think you know it all? You'd be suprised at what is out there and what you missed. And what you spent a month in house re-inventing. This one's important.

    - Use open source software. Nothing beats free. Nothing is more fun. Java's ugly standardization history makes me puke... the BS Sun has pulled with Java is staggering. That the Java Lobby swallows it and loves it even more so. This is irrelevant to your question, and not fair to the Lobby, but I like to give them a hard time.

    - Colorary to Java. You need less abstract design then you think. Endless object hierarchies will weigh you and your app down... Their are books on this too.

    - You need more documentation then you think. Ever found code someone ELSE wrote too EASY to follow. I don't think so. Especially if you are using perl and someone is enjoying the line noise capabalities perl allows. Perl has 20 ways to do EVERYTHING, you may not know the latest or twistiest. Document as you WRITE the code. Do not leave at the end of the day without catching up the docs. A week of documenting is the worst form of hell, avoided with a minutes worth of clarification each time you write a function/class.

    - Hardware is cheap.

    Anyways, have fun... and good luck. Be interested to read what others have to say.

  10. KISS by ZaneMcAuley · · Score: 2, Insightful

    Keep It Simple Stupid. Keep code simple, why have funky lines of code that looks awe enspiring. Its pig ugly. I work on the principle of KISS. When I am working on a code area that is being cleaned up or fixed, I try to simplify that area. The simpler it is, the easier and quicker it is to maintain and bug hunt.

    Im a strong believer in managed code (whether its C# or Java, except managed extensions to c++ which are damn pig ugly :) Exception handling for seperating error handling from actual code that performs the actual work).

    Make sure there is GOOD in code documentation (and out of code documentation) to explain the intention of that code. (Intentional programming is a research area btw, to program ones intentions).

    You know when something is bad when you have to maintain that code later on, 6 months down the line or whenever. Thats when it bites you in the buttie.

    --
    ----- Whats wrong with this picture? http://www.revoh.org:1234/whatswrong
  11. Refactoring your project by adamy · · Score: 3, Insightful

    To expand on the concept of Refactoring:

    1. Write a test for a specific block of code.
    2. Appliy the refactoring

    You are going to want a good testing framework.

    To expand on the modules post: Do a dependency analysis. If you are writing DB based code, look at what tables can be logically grouped together.
    We did something like this at my company not too long ago. The basical level package we had was the security package, which identifies users and roles. Most other packages depended on this. All contact management stuff went into a package called Directory. All stuff for the people our system was managing went into Participant etc.

    For each of the packages, split the code out into a set of interfaces, and a set of implementing code for business logic, and the UI required to drive that business logic. This is the standard breakdown for code. You may want to further pull out code into helper packages. Avoid the urge to call these helper or util, and instead try to name them based on what they contain: we have one called format for stuff like phone numbers and social security numbers.

    Don't forget the make scripts. What ever build you use, it should be used to specify which modules you want to compile/deploy

    I recommend a little UML modeling session for the end package structure.

    Go in little pieces. After each refacotring, makes sure stuff still runs.

    Good Luck

    --
    Open Source Identity Management: FreeIPA.org
  12. Playing with fire... by ZaneMcAuley · · Score: 2, Insightful

    Do you have the original engineers for that code?

    Most knowledge is in theyre head, not on paper unfortunately. Theyre experience in that area can never be written down.

    --
    ----- Whats wrong with this picture? http://www.revoh.org:1234/whatswrong
  13. Unexploded bombs, not sleeping dogs by ChaosDiscordSimple · · Score: 5, Insightful

    Your tangled mass of spaghetti code paths are probably full of almost incomprehensible little design decisions and seemingly out of place declarations and functions, but most of those were probably added as specific fixes for bugs encountered under real-world use.

    Yes, and if they're cryptic and uncommented, they are worthless. Eventually one of these incomprehensible, magical fixes will stop working. Perhaps the bug it works around is fixed. Perhaps how the function is being used changes to previously unexpected behavior. Some poor engineer will look at the little big of magic, scratch his head, and be forced make a blind decision about how to fix it. Perhaps he can change the code while leaving the bit of magic in working, but he can't be certain, since he doens't understand it. If the collection of cryptic tweaks becomes dense enough, any attempt to fix a bug or add a feature becomes highly risky.

    On a related note, don't let this happen to you. If you add one of these strange little fixes, for the sake of the programmer that follows you, document them. Just a little "Need to toggle the Foo because Qux 1.4 is correctly fails to do so" will bring tears of joy to the eyes of future programmers.

    1. Re:Unexploded bombs, not sleeping dogs by William+Tanksley · · Score: 3, Insightful

      You're wrong. The comments you recommend will only /add/ to the mass of code to be grokked. Don't forbid commenting; but don't consider them a solution.

      Instead, refactor and unit test. Unlike comments inserted into the middle of the code, unit tests will fail and point you to the reason for the failure. In the above example, when we upgrade to Qux1.5, the unit test which asserts that the Foo is untoggled will fail, and will point right to the function which made the assumption. Bingo -- a quick fix.

      -Billy

    2. Re:Unexploded bombs, not sleeping dogs by William+Tanksley · · Score: 5, Insightful

      Comments used that way are like perfume -- they cover the smell of stinky code. Perfume isn't bad when your code stinks, but better is to make your code not stink.

      A better solution would be to extract the thing you're commenting into a function, and name the function so that the comment is unneeded. Don't forget to write a test which checks the purpose of the function. Then (and only then) delete the comment.

      MakeNotAccidentallyClickable(widget);

      See what I mean? Now it's impossible for your comments to become out of sync with your code -- your code IS your comments.

      -Billy

  14. Small steps by ChaosDiscordSimple · · Score: 5, Insightful

    Large overhauls are usually mistakes. Details in the previous code are lost. If the overhaul takes non-trivial time, people become frustrated that two weeks ago they had a working (if problematic) system and today most of the system doesn't work.

    Instead, make small incremental changes. Pick something lots of code is replicating and attempt to unify it into a shared code base. Spend some time documenting key parts of the code. Pick a particularlly hairy class or function and untangle some of the worst bits. These sorts of changes can reveal minor bugs, build up to significant improvements, and leave you satisfied at the end of the day that you improved things.

    If a signficant overhaul is necessary, try to overhaul portions while maintaining the existing bits.

  15. Regression test suit by angel'o'sphere · · Score: 5, Insightful

    The first thing you definitly have to do is Setting up a test suit for regressoin testing.

    For those not familair with the term 'regression test':

    Program a set of so called "test drivers", programms calling your code: routines/scripts.

    Define test data, either in a DB or in flat files, used by those driver programs.

    The test programs and test data needs to work with the old code, of course.

    As the new code should behave similar you only need to adjust PATH or script names to let the test programs work with the new code.

    Plan your project by defining which test cases(test program plus test data) should work at a planned milestone with the changed code.

    After making changes rerun all tests.

    Well, there is a lot more you could do, but that above is minimum (basic software engineering, sorry no art involved here).

    Regards,
    angel'o'sphere

    --
    Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
  16. It is called Refactoring. by burtonator · · Score: 5, Insightful

    Most of the computer industry now calls this Refactoring.

    I would HIGHLY recommend the book "Refactoring" by Martin Fowler.

    There is a number of things you should do here.

    1. Document your plan and come up with an official PROPOSAL document. Allow others to comment on this document and incorporate fix all relevant issues.

    I started using this under the Apache Jetspeed project and now a lot of other Apache projects are accepting this practice.

    It really allows the community to become involved in your changes and encourages constructive feedback and involvement.

    2. Break this into phases. You should NOT attempt to do this all at once. Each phase should be isolated and should consist of one unit of work.

    Each phase should be branched off of CVS, worked on, stabilized, brought back into HEAD and tagged. You should then RUN this code in a semi-deployment role for a period of time to correct all issues which WILL arise with the updated code.

    After this you can then start your next phase.

    3. UNIT TESTS! If management (assuming you have management) has approved the time for this type of refactor then you need to take the time and write Unit Tests for each major component.

    It is important that Unit Testing can sometimes be just as hard, if not harder, than the actual development itself.

    In some situations you can avoid Unit Testing, some here are going to call me crazy for saying this but it is true. In a lot of high level applications, which are NOT used as libraries by other applications, you can bypass Unit Testing in order to increase development time. This is a dangerous practice but it is often outweighed by the extra functionality you will end up with in your product.

    Anyway. Good luck!

    Kevin

  17. Complete rewrite necessary or a waste of resources by beamz · · Score: 4, Insightful
    Not too long ago a link was posted to an interview with Joel Spolsky who used to work at Microsoft.

    His comments about code reworking and rewriting have a lot of insight in them.

    Here are some quotes from his article:

    SMS: Joel, what, in your opinion, is the single greatest development sin a software company can commit?

    Joel: Deciding to completely rewrite your product from scratch, on the theory that all your code is messy and bug prone and is bloated and needs to be completely rethought and rebuild from ground zero.

    SMS: Uh, what's wrong with that?

    Joel: Because it's almost never true. It's not like code rusts if it's not used. The idea that new code is better than old is patently absurd. Old code has been used. It has been tested. Lots of bugs have been found, and they've been fixed. There's nothing wrong with it.


    The point is this... The benefits of spending time rewriting code completely may be a waste of the companies resources, this is for you to determine.

    His interview is here:
    http://www.softwaremarketsolution.com/index_2.ht m

    and his site has more information about the concepts here:
    http://joel.editthispage.com/articles/fog0000000 06 9.html
  18. Quick suggestions...not so quick solution by runswithd6s · · Score: 4, Insightful
    As everyone else should be telling you, your existing codebase is a very valuable resource. It's been tested and debugged a number of times. It's mature, it's stable, it's there. Don't throw out the baby with the bathwater.

    Now, on coding standards and how to incorporate them into a legacy project. Your concern is NOT format. The format of your code, such as indentation, spacing, etc, should be the least of yoru concerns. Everyone has their own style, but there are wonderful tools that you can use to force everyone to a single style, ident and astyle just to name a couple. Use a wrapper script to the CVS (or similar system) on checkins. Force the code through an automated cleanup. check the code back out and make sure it compiles/runs as expected.

    What you should worry about is how much your design team has embraced the "black box" design principal. Parameters go in, results come out with no "side-effects" that impact the remainder of the code. Make your code re-entry safe, i.e. stay away from globally scoped variables as much as possible.

    Someone's going to give you the whole OO-Design sales pitch. Yes it's nice on paper, but don't sell out because something looks nice on paper. I learned this the hard way. I have a tendency to overdesign things. When OO, this gets to be really scary. I waste my time writing object classes for "everything" instead of simply designing the software to its functionality spec. Make things more "object oriented", "functional", or "blackboxed" when you find yourself repeating code elsewhere in the application.

    Don't spend a lot of time with naming standards such as Hungarian, Modified Hungarian, etc. Find a style that you and your team is comfortable with for the Interface API level. Below the Interface API, be more lenient. It's likely that portion of the code will undergo many changes anyway.

    And most importantly, document! This is the singlemost important issue of any coding project. Either force your developers to write docs as they go, use embedded documentation solutions, or hire a techwriter to follow you and your team around for a few months. Documented API is the quickest way to start someone off in the project, and a great way to keep track of the flow of the program.

    --
    assert(expired(knowledge)); /* core dump */
  19. Can we change the word "Developers"? by IRNI · · Score: 1, Insightful

    Ever since I saw that horrible, nightmarish Steve Ballmer video.... "DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS... DEVELOPERS DEVELOPERS DEVELOPERS!!!!!!!!!!!!" Oh god lets call it anything but Developers! The image of a big, fat, bald, sweaty man keeps entering my head when I hear that word.

  20. Does it work? by litewoheat · · Score: 2, Insightful

    If it works don't break it. Pointless rewrites do nothing but feed the programmers ego and knock the company out of business. Its happened over and over and over and over again. Progress, not regress.

  21. Re:Extremem Programming - Refactor by (H)elix1 · · Score: 2, Insightful
    Yah, I keep hearing this. Read the whole book - it recommends strong test plans, incremental development, pair programming, tons of snacks, and a maximum of a forty-hour work week. In itself, not a bad thing.

    Interpreted by management?
    • They see the part about everything being stuck out in the open, with the computers set up in the center of the room - cubes are overrated, offices are evil
    • half as many boxes are required since you are "coding in tandem". See above for hint on how personal space is valued.
    • Demand complex test plans that will cure everything. These same people never have actual requirement documentation for what the code should do. Classic example? Validation rules for a phone number... gets ugly when someone wants to put in 1 800 FOO-BARR, add an extension, deal with international numbers. Think you can put together a test script? Got to have requirements first, and that is never a hard thing to get from the business (shudder).
    • I'm sure you have had complete management buy in on realistic time estimates now, so I wonder where the rumors come from that development tends to work more than an eight hour day. When they find out how long it will take to refactor the code base with through testing and daily updates, they will tell marketing and adjust the dates accordingly. Heck, I thought the Microsoft Project Plan defaulted to an eight-hour day - must be one of those rare Pentium errata issues that messes things up for me.

    Not that I'm bitter, cause I'm not... but XP takes a handful of generally good practices and assumes perfect management buy-in and team communication. With any management support and teamwork, almost any method works.
  22. Perl is a *tool* by tmoertel · · Score: 3, Insightful
    Perl is for system administrators and system administrators-cum-developers, not real software development.

    Baloney.

    Contrary to what lots of people around here seem to think, especially those who like to make wide-sweeping declarations about what things are and what they are not, Perl is a tool. Nothing less, nothing more. Like all tools, it can be used to create well-engineered systems, and it can be used to create crap.

    The community that grew up around Perl is all-welcoming and generally free of elitism. That's why a lot of newbie programmers and "system administrators-cum-developers" use Perl -- because they can without getting crapped on by others who think they know better. As a result, there is a lot of ametaurish-looking Perl code out there, but that's not a result of the language, that's a result of the all-inclusive set of people who use Perl.

    Let's be clear: If you write code in any language and the code sucks, it's your fault, not the language's -- the language is just a tool.

    Don't blame the problems of programmers on their tools.

  23. Don't rewrite, and don't refactor by splattertrousers · · Score: 2, Insightful
    Don't rewrite your code. That's a waste of time.

    Don't spend a big chunk of time refactoring it either. Waste of time too.

    Instead, make slight refactorings as you go. But make sure you are doing what you are really being paid for: implementing business value.

    And you'll find that you'll have much more courage to refactor if you have a full set of automated tests, so maybe you should work on tests first.

  24. Paradigm Caution by Tablizer · · Score: 2, Insightful

    There is NO decent evidence that OOP factors better, or does *anything* else better than procedural/realational programming (or other non-OO paradigms).

    IOW, don't switch paradigms just because something is in fashion right now.

    Look carefully before leaping into something that may just turn out to be a fad or only shines in specific domains.

  25. Re:See no evil, hear no evil, ...? by khkramer · · Score: 3, Insightful
    > Perl is for system administrators and system > administrators-cum-developers, not real > software development. Look at java. Look at > PHP.

    Mmmm. I write large-scale web applications for a living, and I do it in Perl. By large-scale, I mean sites that are expected to support hundreds of thousands of page-views per day, serve hundreds of thousands of distinct users per month, and collate hundreds of thousands of distinct chunks of content into dynamic pages.

    My company is a high-end development shop. We generally bid on projects that will take six to nine months to complete, and we only do jobs for clients who understand how we work and why. Part of our approach is to use very small teams of extremely experienced web developers. We usually deploy four programmers on a project. Other companies that bid against us sometimes use several times that many people on a single development team. Another part of our approach is to build everything on top of our open-source development framework. That sometimes used to be a tough sell ("what, give software away for free, heaven forfend") but these days, most customers are pretty receptive to the twin "more eyeballs means better code" and "you're not locked into our closed, proprietary product" arguments.

    We also generally build small clusters of dual-processor Athlon or PIII machines, whereas our Java- (Oracle-, IBM -, BEA-, etc) wielding colleagues often specify absurdly-expensive hardware.

    Perl is flexible, complete, performs relatively well and has an extroardinary base of skilled developers and re-usable components (CPAN). We couldn't work as quickly or write code that is as concise and maintainable using any other currently-available language/approach. Most of the lines of code that we write actually go into Perl modules, with HTML::Mason templates handling the dynamic web-page generation. We can push Mason out of the way and use straight mod_perl for small, defined tasks. And we can easily integrate C code into our Perl frameworks in places where performance is really, really critical (though those places are rare, as when push comes to shove, one is almost always waiting on the database).

    There are lots of things that aren't "right" about web development. The package that results from gluing HTML and program logic together in a stateless execution environment is sometimes a little lumpy, and unavoidably so. There's no magic bullet toolkit, and (as with other specialized programming arenas, like graphics or embedded systems) a lot of hard-won, domain-specific knowledge goes into the development of a fast, reliable, maintainable web app.

    The Perl/Apache/Mason combination that we use is far from perfect. But it's better -- for us -- than any of the alternatives.

    I really like Java, and have written big systems in that language, too. If for some reason I had to manage a very large team of programmers, or had to manage a team with a large percentage of less-experienced programmers, I would use a Java-based solution. Java is a more rigid language than Perl, and the structure that the language provides would be a useful management tool in those contexts. But for my small teams of skilled hackers, Perl is more productive. (We have an extensive, evolved, self-imposed "structure," so we don't need the language to impose one on us -- in fact, it gets in the way.)

    I would never use PHP for the kind of work we do. PHP just isn't the kind of powerful, flexible, complete environment that Perl is.

    Zope and Python are really neat. I'm a fan of the work that folks on that side of the fence are doing. But Python+Zope don't offer us anything new that Perl+Mason+Comma don't. I also like Perl more than Python (which is a subjective preference), and think that the Perl development environment is more mature (which is a subjective judgment).

    So don't listen to the folks who tell you to dump Perl. You should certainly consider all of your options and make an informed decision about core tools, but anyone who thinks that Perl is just a "scripting" language, or that it doesn't scale, hasn't been paying attention.

    To finish this up with a little more specific advice to the original poster: You mentioned "150+ perl CGIs" in your question. You should consider moving away from the CGI model, if possible. Take a look at HTML::Mason, which is a very good embedded-perl environment. You can build solid, consistent application layers using Mason as a base. Also, I couldn't agree more with the folks recommending writing perl modules and requiring complete regression tests for each module. There are lots of ways to write tests, but in perl-land one of the easiest is to simply make a t/ directory down your module tree, write a bunch of scripts in that directory named <some-test>.t that print out a series of "ok <n>\n" lines, and use make test or Test::Harness::runtests() to invoke them.

  26. Why are you rewriting? by Anonymous Coward · · Score: 1, Insightful

    You should never do something that will require a long time/resource investment unless you have a good reason. Is this just some clever way for management to justify firing the developers because they won't have accomplished anything at the end of this rewrite?

    If you don't have a reason, you can try to find one. You might identify things that are truly broken about the system, and try to fix them. A typical problem with a lot of code is that its not as general as it could be (not portable, or you can only run one instance at a time because of some common resource or something like that.) By finding a concrete reason you will be able to direct your efforts and have a way of assessing your results when you are done.

  27. Re:object orientation by ergo98 · · Score: 2, Insightful

    ...refactor...

    Just as a point of reference: I've noticed that the term "refactor" has gained popularity with the whole XP push. Of course "refactor" is just a cooler way of saying "rewrite". i.e. It's not "We should rewrite that module", but rather it's now cooler to say "We should refactor that module". Blah.

  28. Unnecessarily long variable names by i_am_nitrogen · · Score: 2, Insightful

    I saw a quote once that said something to the effect of you can always tell a computer scientist's code because he won't have any comments: his variables are his comments (something like that, not sure of the exact words). While descriptive variable naming is important, excessive variable naming is annoying. For one thing, it's a lot easier to type no_acc_click() than it is MakeNotAccidentallyClickable(). Comments are necessary. When code does anything of even a slightly complex nature, there's no such thing as intuitive code. There will always be a need for comments in anything beyond the simplest programs. The best code is properly indented, case is consistent, variables have descriptive but not lenghty names (i is sufficient for an iteration variable, malloc is sufficient for a memory allocation function, etc.), a description at the beginning of the function of all expected uses and known bugs, and last but not least, comments of each change in the code, ChangeLog, and CVS logs.

  29. Ahhh Refactoring the Sport of Kings... by j-jahnke · · Score: 2, Insightful

    I want to start by saying, before you do ANYTHING make it a priority for your team to start writing test cases and implementing them. If you are going to change your system you want your tests to find the problems not your users. Once you have a test suite that effectively tests your system (you will be surpised how quickly these tests will lead to enhancements in your software BTW) then you need to decide if you really want to maintain two seperate teams.

    One team will be doing maintainence on your old system that is in use. You can't not keep this team in place, you have to keep customers happy while you do the new thang. You need the second team developing the new sytem (their job will be difficult with good tests, but impossible with out them.) Without tests they will have something that looks kinda like the old thing, but behave differently in a million small ways, some without a doubt will be better, many will not.

    The other thing, and more sensible IMHO, is to tell pairs of programmars, to spend some hours each week working on the system together. Pairs becuase this is an excellent opportunity for people with deep knowledge of their systems to share it with other memebers of the team as they ferret out ways to refactor the code so more of it can be shared.

    One day a week you can have a team working on some part, documenting spaghetti code, or pulling out examples of where code was cut and pasted and create a function which is called from both places. The stated goal should be fore each team to remove some number of lines of overall code from the project each week.

    Remember the metric is the more lines of code you have the more errors you have, make it a mandate for your team to be removing code as well as adding, actually on our team we don't brag about how many lines we added in a week, we brag about how many we removed.
    Anyway, the idea is by getting teams to do pair programming looking a specfic areas with good tests you can whip your code into shape pretty fast, and spread the knowledge of the system around as well. AND instead of a jarring change when you unveil the new system you can have gradual changes as fixes are tested and added.

    Obviously if your overall architecture is broken and can't move forward this won't work. But it seems to me you are not fully convinced of that fact yet. At the very least by having teams look at code they may not be overaly famililar with you might find that team members can cross pollinate and share good ideas.

    Jer,

  30. Re:object orientation by anacron · · Score: 5, Insightful

    Refactoring is not re-writing. Refactoring is a methodical approach to moving, redesigning, and making the code cleaner. It's not throwing away and starting from scratch. The two words are wholly semantically different.

    In his book, Refactoring, Martin Fowler talks about how code "smells". He identifies a whole slew of reasons why code can "smell" bad, such as having a method that's too long, having a method on the wrong object, incorrect use of polymorphism, etc. He then outlines "Refactoring Patterns" which can be applied to certain "smells" to make the code more managable.

    The last project I managed was a 3 month re-write of over 75,000 lines of code for an auction component that had gotten way out of control. The original component integrated with a very very poorly written (yet still very expensive) auction engine, and our task was to take it out.

    Because there was no time allotted to proper requirements gathering, the powers that be decided that we could use the existing system as a requirements base, and just make the new system "act" like the old one.

    So I was thrown two things: A staff that was inexperienced in design, and a lack of requirements. We were re-writing from scratch -- throwing all of the code away and starting again. I'm one of the only ones on my team that actually knows what refactoring means, let alone how to apply it.

    So we built the new system based on a solid design. We even did the design in UML. But that only goes so far. Given a properly designed system, there is still another lower step -- how to actually implement the code. Invariably, the design doesn't take into account helper methods that are necessary, other objects, etc. Because we were on a tight schedule, I left it up to each developer to design these new tidbits.

    If they had known what they were doing, everything would have been fine, but there are several places where the code is absolutely abysmal. It's not that it will perform poorly or is totally unmanagable, but in some places it's close.

    Granted, the business rules for the system are some of the most complex I've ever seen, but if the developers had known more about refactoring, they might have made better choices.

    There's a whole notion of Quality here that should be discussed as well. Most good has a good enough quality, and though it looks ugly, I'd throw it away. There's an interesting interview by Joel (a former microsoft programmer) which tackles these problems of Quality head on. I also reccommend reading Zen and the Art of Motorcycle Maintenence: An Inqiry into Values for a pretty good discussion of the whole notion of quality.

    I'd say just keep the codebase unless you are totally switching languages (or in our case taking out a 3rd party integration). Otherwise if you re-write you'll wish you hadn't. The new codebase will end up being in the same state as the old codebase, it'll just take a little bit more time to get there.

    I'd also reccommend just doing a performance test of the site, and find out which modules really need to be re-written. The 80/20 rule will invariably apply -- 80% of the execution time will be spent in 20% of the code -- so at a minimum just re-write the 20% of the code that's executed on the most frequent paths. Leave the rest alone. Re-writing it will just be a waste of time, and you have to fix all the old bugs that were re-introduced during the re-write.

  31. Some advice: by Anonymous Coward · · Score: 2, Insightful

    I have been through this before - with a different language, but the same principles apply. Here is some adivce, and some ideas:

    1. Don't do a 'big bang' rewrite. A Big Bang rewrite is one where you totally rewrite all the code, but have no functional - or very little functional difference.

    2. Do refactor or rework small portions of the code. Work on the code as you implement new functionality that the system needs. In other words don't waste time on rewriting working code unless it needs additional features or is broken.

    3. Do Introduce Unit Tests and Acceptance Tests. This means you will know quickly when changes you make break code. Don't do a massive "unit test" building exercise however. Write a Unit Test for every peice of new code you do, and every peice of code that needs fixing.

    4. Identify "Problem Code". Problem code is the bits which seem to take up most of the maintenance time. Identify that code, and try to work out ways to fix it.

    Note : Some people think they are 'clever' by writing complex code which is hard to understand, but may perform better etc. This is the kind of code which usually ends up being a problem. As a professional programmer I try to be clear to understand - not only for the benefit of others, but for my benefit when trying to maintain it.

    5. Read about how to manage projects. Extreme Programming is popular now, and I can say that it has some very good ideas. However don't become religious about it, and take a look at some of the 'classics'. I can recommend:

    - The Mythical Man Month (tad dated, but a classic).
    - Code Complete (also a little dated, but still good advice)
    - Extreme Programming Explained

    To take a look at my Open Source Resource, which has many articles around the subject of project management, take a look at:

    Devcentre

  32. I have to agree with the concensus... by Codifex+Maximus · · Score: 3, Insightful

    if it works... don't fix it.

    If you feel you have to fix it, then prioritise the most problematic parts and fix them according to a set plan/policy. Use a naming and calling convention. Break functions that do more than one thing up into component functions that can be tested, verified and reused by other parts of your program. Fix it incrementally not all at once. Try using an interface contract when you make objects; that way, your new functions can call new methods and the old code can depend on old methods to be there. Deprecate the old methods when there is no code that depends on it. Don't forget to comment - comment the code then come back the next day and read your own comments. Make changes to the comments so they make sense today.

    Blah... blah... blah... Etc... etc... etc...

    --
    Codifex Maximus ~ In search of... a shorter sig.
  33. None of us know your situation by LoveMe2Times · · Score: 4, Insightful

    There's a few things that I'll say. One, not a single person posting here really knows what your situation is (well, unless your coworkers read /. and are posting advice for you...). I don't want to be mean, but most of what's been posted here is likely not applicable to your situation. For starters, ignore all the threads arguing over languages: they'll never agree, and in the meantime you have work to get done. Next, I would suggest ignore all of the posts from people who aren't talking about web sites. There's a lot of methodology recommendations there, and it takes a long time to really understand *any* methodology. So if you don't already know it, it won't help for *this* project. If you're interested in that kind of stuff, read up on it; maybe it'll be useful on a future project.
    Next, no matter what you decide, from your current position, there's substantial risk involved. If you don't have a good way of estimating the costs and benefits of your alternatives, then you will wind up shooting in the dark no matter what you choose. This isn't really unusual, but it can be stressful! Somebody in management has to decide if they want to play high stakes poker with this project. This will establish how many nice risk mitigating activities you can budget (like unit tests, code reviews, documentation, etc). One thing a lot of technology people have difficulty grasping (this isn't directed at anybody in particular), is that if your management decides on a high risk course of action, it's not WRONG because it's technically inferior. Now, if management doesn't understand that it's a high risk proposition, then there's a communication failure somewhere that will screw you no matter what gets chosen.
    Ok, now that you've decided where you're going, I've got 3 pieces of useless advice (all advice is useless advice, btw...)

    1) Know your priorities. This is the most important thing to getting ANY solution.
    2) Understand your requirements(I don't care how you do this). This is the most important thing to getting (close to) a CORRECT solution.
    3) Remember it's only a job. This can be very important for retaining sanity :)

  34. finding and keeping a competant staff by KyleCordes · · Score: 3, Insightful

    [There's only so much a methodology can bring to the table -- after that it's about finding and keeping a competant staff who understand the value of what they're doing.]

    You are so utterly right. The key idea is "people over process". I've rather have 5 great people with any old process, than 25 mediocre people with the perfect process.

    [look at the console gaming industry for tips]

    I have always been impressed with the gaming industry for this reason. Sometime people erroneously think of game programming as being somehow less "heavy duty" than business apps, etc. But games are usually under incredible schedule pressure (for vital marketing reasons) yet also need to ship very few bugs, because buyers are prone to return a game that doesn't work, not become a source of upgrade revenues.