SitePoint Sponsor

User Tag List

Results 1 to 16 of 16
  1. #1
    SitePoint Addict been's Avatar
    Join Date
    May 2002
    Location
    Gent, Belgium
    Posts
    284
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Refactoring strategies ?

    I was hoping I could get some input on the following issue:

    Last month I switched jobs, no need to go into the details here, first of all, I don't want to bore you people to death, second of all, my post might end up as nothing more than a bunch of not-so-nice-four-letter-word-paragraphs towards my former employer

    I was handed over a php/mysql-driven website, that was in desperate need of some modifications. After initial talks about what the website should be doing, what the direction of the company was, etc. I took a look at the source code of the current website...

    The CEO told me the site was done in about 2 months, and the guy that did it, I consider him a close friend of mine. But I have to get this of my chest: For me, going through the code is a major drag, and I mean major drag. Now, I'm fully aware that my friend is not a real developer at all, but it seemed he was so much stressed, that he didn't care about any development issues, as long as the thing was up & running asap, all was ok.

    Now of course, when fundamental changes are to be made, the excrements hit the ventilator, and they basically asked me to sort things out...
    I'm somewhat offended by the code: it's a multilangual site, there is nothing that would resemble anything of a configuration, there's no layering at all, there's code duplication all over the place, there's no documentation, etc, etc...
    There aren't any comments in the code either, and if they are, they go something like this:
    PHP Code:
    // connect to the database
     
    $link mysql_connect(...); 
    And I'm like: "Aha, so that is what it is doing"

    To give you an example: 2 weeks ago, I was asked to put up some banners (same banner, but 1 for every language) that would stay there for a month (normally the system just displays random banners...). I told them that that shouldn't be a problem, but that I had to check first...
    Luckily I told 'em that I'd check first: The original system had the banners hardcoded as jpg's, and these banners were gif's. The banner system didn't implement multiple languages, so I couldn't even just put the banner in the db (at least it's id or something) and so on.
    Eventually, it took me almost 6 hours to put those damn banners up! Of course, implementing the possibility to go back to the previous 'random banner system' in a blink of an eye.
    I seperated the top banner code into a seperate file, and included that in the page scripts... all 182 of them! Search and replacing everything was not really an option; because of the copypasting programming and the modifications made to 1 script, not all code in all scripts was alike, and I couldn't come up with a 'catch-all' search pattern...
    Yes that's right: there's 91 pages for the site, and 2 languages, the files reside each in their own directory (one for every language) and the code is duplicated (html and all) in every page!

    This makes handling modifications like a walk in a mine field, so I wanted to put the site up on my testserver to be sure everything worked, before I loaded it up to the public server.

    Horror: also the db connection was hardcoded in every script file! I seperated the db-connection in a global function, so at least I could change the connection easily between my test server and the public server.

    Well well, here I am telling you I don't want to bore you, I've written like 5-10 paragraphs, and I've still haven't posed my question .

    Basically, my question is simple: How do I go about this??
    Of course the CEO knows nothing about development and is surprised when I tell him "It'll take a couple of weeks" (mind you, I'm working part time, ca. 20hours/week) to implement this or that and integrate it into the site. But I think I'm slowly getting through to him.
    My main concern however is how to go about it design-wise?
    I have a schematic view of the system in my head, I am starting to lay it out on paper, but It's impossible to go from the current site to what I've got in my head in 1 step.

    O, btw, this is just the application itself, I'm too scared to start about the 'design' of the database (basically the strategy behind that was: "oh, we need that, let's create another table").

    So what I'm thinking:
    First: seperate-out all common code into global functions:
    db connection, global site navigation menu, language selection, etc...
    second: putting layout in a header and footer, the "ol'" include-header, include-footer approach...
    Then start putting everything in components and work towards a more modular, oo-approach?

    It's that I don't believe in writing the thing from scratch, it would take too much time, what's there seems to work, so I'm thinking "let's go from what's already available"?

    Maybe some of you have already been in this situation?
    I'd greatly appriciate it if you'd share (some of) your experiences.
    Per
    Everything
    works on a PowerPoint slide

  2. #2
    SitePoint Zealot
    Join Date
    Jul 2003
    Location
    Palo Alto
    Posts
    179
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I just got turned on to joelonsoftware, and I highly recommend it. You'll definitely want to read Rub a dub dub, Joel's article about refactoring some old code. As for your CEO, just don't compromise. Estimates are not negotiable. If you know it's going to take two weeks, then that's what it takes. I've found that (a) if you try to compromise, you stress yourself out and make lots of mistakes, and you also set a very unhealthy precedent; and (b) if you stand your ground, they tend to think you actually know what you're talking about. I'd also tell him the reason it's going to take longer than either of you would like is precisely because the original was done in only two months when it probably should have taken 4-6. You probably know all this, but that's my two cents.
    I think there is a world market for maybe five computers.
    - Thomas Watson, chairman of IBM, 1943.

  3. #3
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Bizarrely I actually enjoy these kind of problems. You get big kudos points with your peers when you can manage these kinds of issues.

    Quote Originally Posted by been
    Basically, my question is simple: How do I go about this??
    Have a look at the essay "The big ball of mud". The main link is down right now, but while it comes up you can read some comments here...
    http://c2.com/cgi/wiki?BigBallOfMud

    You are already going it about the right way. Small improvements whilst keeping it working. One thing to get it under control is to get an automated test around it. You are going to do a lot of small edits and you cannot look at every page after each edit as it will be too slow.

    How about this for a plan...

    Write a script that grabs every page into a "snapshot" folder. Write another that copies the snapshot contents into a "baseline" folder. Write a third that does a diff of the two folders printing any filenames, and so scripts, that are different and "Ok" otherwise. Prepend the snapshot script to it.

    Now run the snapshot script (it will list all files), then the baseline script, then the snapshot script again (you should get "Ok").

    Now make a change and run the snapshot script. Were there any changes? Did they matter? If either is no, then run the baseline script again. You now have a new baseline and are ready for the next edit. If you get errors then you either fix the errors until you get "Ok" or roll back. Each cycle should be less than a minute or two including the edit.

    With this set-up in place you should be able to move quite quickly .

    For the classes and other tests you will be introducing, you will probably have to write proper unit tests. You don't want to leave behind a mess for the person who has to take over from you after all .

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  4. #4
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What a nightmare.

    It's probably a good thing for the learning process if script kiddies can hack together workable spaghetti code before getting to grips with OOP but it would be nice if there were one or two standard frameworks which were widely used.

  5. #5
    SitePoint Zealot ZangBunny's Avatar
    Join Date
    Jul 2003
    Location
    Mainz, Germany
    Posts
    119
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I just stumbled upon an excellent book that addresses just this subject: "Object-Oriented Reengineering Patterns" by Demayer et. al. is all about turning a legacy system into something useful. It even includes short versions of the most important refactorings and design patterns. 250 pages make it a relatively quick read, and it's really worth buying if you want to tackle the problem systematically.
    Things that try to look like Things, sometimes
    look more like Things than Things. - Granny Weatherwax

  6. #6
    SitePoint Evangelist
    Join Date
    Jul 2001
    Location
    Michigan, USA
    Posts
    414
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That Joel on Software is an excellent site. I'd never stumbled across it before. I galnced through some of the topics and read an article and his stuff is pretty sweet. I'm going to spending a lot of time over the next few days there

  7. #7
    Mal Reynolds Mandibal's Avatar
    Join Date
    Aug 2003
    Location
    Columbus
    Posts
    718
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    First thanks to Been for starting this thread cause I'm in the same position. I started my current job about 5 months ago. We currently have 3 legacy sites getting constant use and we're currently developing a new site. Whats nice about the new site is that it works on similar modes to the others so everything I create for the new site can be used in the old ones eventually.

    Secondly thanks to Marcus for his great idea about snapshot/baseline scripts. This will work great in my situation as well. Course now I have to figure out how to write scripts for doing this...my experience is more limited in this area....any suggestions in the right direction would be greatly appreciated.

    Lastly thanks to Zang for the book suggestion. Of course its just one more book I'll have to get through along with PoEAA and Refactoring wich just came UPS to my door.
    Erh

  8. #8
    Wanna-be Apple nut silver trophy M. Johansson's Avatar
    Join Date
    Sep 2000
    Location
    Halmstad, Sweden
    Posts
    7,400
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    I would probably just recode the thing from scratch, and use code from the project where applicable. If it was done in two months by a "not-real" developer, you'll probably save much more time that way.
    Mattias Johansson
    Short, Swedish, Web Developer

    Buttons and Dog Tags with your custom design:
    FatStatement.com

  9. #9
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by Mandibal
    any suggestions in the right direction would be greatly appreciated.
    If you are using Windows you will need the Cygwin toolset, on LInux you have everything you need. It basically boils down to diff.

    You can write the URL grabber using the PHP file() command by just putting in a URL instead of a filename. Just use fwrite() to stash it.

    The baseline script can just be a list of copy commands.

    For the comparison use the "diff" tool. Just go "diff file1 file2". Play with it and you will see what I mean. Have a look at the output and just do a regex match for whatever gets dumped out when a file difference occours.

    The main thing is that it shouldn't take more than 30secs to run and it gives a very visible yes or no answer.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  10. #10
    SitePoint Addict been's Avatar
    Join Date
    May 2002
    Location
    Gent, Belgium
    Posts
    284
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by brainpipe
    As for your CEO, just don't compromise. Estimates are not negotiable. If you know it's going to take two weeks, then that's what it takes.
    As silly as this may sound, I find this to be an excellent piece of advice!
    I know that compromising in the time estimates should be a big no no, but often I find myself cutting down on it and just working too much hours. (Mind you, I don't mind putting in over time at all, if something has to be done, it has to be done, but I don't wanna catch myself working 30-35hours every week, when I'm supposed to be doing 20. Time is money? Forget it! Time's waaay more important than money.

    I just got turned on to joelonsoftware, and I highly recommend it. You'll definitely want to read Rub a dub dub.
    Discovered it too, not so long ago.
    Since then, I've spend hours and hours on it, reading and enjoying every line of it, truly recommended indeed! And yes, that article is sooo what I'm going through, but there's a difference:
    I can't 'freeze' the functionality of the current site, it has to be expanded, and it has to be done rather quick. As Spolsky (in my experience correctly) said in another of his articles: people (clients/your boss) want to see results.

    And then there's the business: For example, in the banner example I posted; There are people paying money for that banner to be up on that day until that day, I cannot say It'll take two weeks to a month for me to clean up the code and html first, before I put in the banner (of course then it would take 5 minutes instead of 6 hours )

    It is therefor I think my first priority should be to factor out all code duplication and centralize common code. Only then will I be able to integrate the new functionality. Nothing fancy, just put it in a global function or a class, or even just a seperate file that gets include()d where necessary.

    To give you (another) small example: the global navigation menu is copypasted in ALL script files that produce output, I've found 2 files where it is even trippled (just a big if-elseif-else-block with the html copied in every block ), and need I remind you, that's 2 files for every of both languages...
    So my quick fix goes something like: put the common code in a PREFIX_Menu class, put the data for the menu (urls, gif-names, rollover-gifs name, captions, tooltips) in an ini file or seperate php array file, make the menu class take the path to the ini file and the current language as parameters, have a method render() which returns all the html for the meny as a string. Then go through every file seperately, replacing the whole block with a method call.
    Then I can add a page with new functionality easily: My reasoning being, if I have to go through every file every time I want to add or edit a menu option, I'm better of going through them once and put a little extra time coding a class or global function.
    As said, just a small example, I have found that line (to go from A to B) not always to be that clear.

    You probably know all this, but that's my two cents.
    Yes and no, and I'll gladly take any penny you throw at me


    Quote Originally Posted by lastcraft
    You are already going it about the right way. Small improvements whilst keeping it working.
    Again, this may sound silly, but you have no idea how much more confident that makes me feel (don't worry, I'll refrain myself from bursting into tears of pure hapiness ).
    I'm (mainly) self-educated, and it's difficult sometimes to make sure you're going about things right. (sidenote: I've taken up a higher education (night-classes) in computer science (programming), that'll help a bit I hope, yet for the moment, I'm just designing Vehicles and Cars in VB.NET )

    How about this for a plan...
    Marcus, that sounds like an excellent plan indeed! Any tips on where I should put the uploading of the scripts to the public webserver into the cycles?

    With this set-up in place you should be able to move quite quickly
    That's what I'm looking for: a way to eliminate the unnecessary extra pressure created by the fact I have to keep walking on my toes all the time.

    For the classes and other tests you will be introducing, you will probably have to write proper unit tests. You don't want to leave behind a mess for the person who has to take over from you after all
    Well I've documented the code I've written so far (for the 'quick&dirty'-in-between-code), used simple typing conventions, used sensible variable names, and added a little explanation as to why I did this or that, I'm thinking; suppose something happened to me, that would leave the site in a very weird state, the least I can do is make sure people can make some sense about the things that I did...

    For the 'new' code I'm writing now, I've written tests, simple, but tests: take all kinds of test values, check the classes' responses, then print out some simple html block with 'ok' or some info if a test went wrong.
    I then have a controlling script, that just outputs a complete html header, includes all the testfiles, and the outputs the html footer.
    All very basic, but it works for now, still I'm finding myself duplicating a lot of code, and sometimes having a little wrestle with variable-name-collision. I'm guessing it won't be long until I'll find myself exploring the many-acclaimed SimpleTest


    Quote Originally Posted by McGruff
    What a nightmare.
    Luckily, I don't see it that way, I really see this as a challenge. I would take great pride in accomplishing the task ahead. Also, the company is very well known in it's market, it would be a very nice reference to add to my list
    That said, there are some stressy moments, I'm also the webmaster for the site, meaning (amongst others) I have to update it every month with new content (there's daily content too, but that's provided by users), there's no cms, so I find myself dumping complete html pages in a database via phpmyadmin (because that's the way the system works now), it's no use I start whining about the fact that I'm storing a lot more then data, and that that shouldn't be stored there, that the database is badly organised, etc... because that content has to get online every month, basically, "it's that simple".


    Quote Originally Posted by ZangBunny
    250 pages make it a relatively quick read, and it's really worth buying if you want to tackle the problem systematically.
    250pages? Then that was even a better booktip then it already was
    Argh, so many things to read, to learn, so little time...


    Quote Originally Posted by M.Johansson
    I would probably just recode the thing from scratch, and use code from the project where applicable. If it was done in two months by a "not-real" developer, you'll probably save much more time that way.
    Well, under different circumstances I think I'd probably agree with you (but only because it's a "2-month-not-real-developer" website indeed).
    However, this is not realy an option: The site -as is- must be online, it runs, it's 'out' there, and it must be kept out there. I could start writing from scratch, but then the site in it's current state would not evolve, sure there would be new content every month, but there has to be functionality added and part of it has to be online before I could possibly come up with the complete site written from scratch with the added functionality.
    So no matter how I look at it, I'm in the middle of: making the current code manageable, writing new code from scratch for new functionality and making sure both can be integrated and put online, bit by bit, step by step, without too many problems.


    Anyways, I should really be getting to bed now.
    Since the rating system doesn't seem to be online anymore: Thanks all for the tips, help and advice, it's deeply appreciated.
    for Marcus: + now the system can't tell me "I'll have to spread some around before I can give it to lastcraft again"
    Per
    Everything
    works on a PowerPoint slide

  11. #11
    SitePoint Addict been's Avatar
    Join Date
    May 2002
    Location
    Gent, Belgium
    Posts
    284
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok, I have got a specific issue:

    - As I posted, the menu for the site is copypasted (hardcoded html) in all the pages.
    - The site is bi-langual (?): nl & fr
    - The site runs in a sub directory under the webroot.
    And this directory is further split up in a subdir for the nl site, and a subdir for the fr site, there all the scripts reside.

    So, I refactored the menu in a seperate class that parses a specific text-file (ini for now) based on the language code passed during construction time, and it returns the menu as a string containing the html.

    This works, but it's far from ideal:

    I want to follow a physical resource mapping strategy for the site, no front controller, no mod_rewrite, just subdirs with some common code in a common.inc.php file.
    This would allow for easy urls: for example:
    www.example.com/news
    instead of
    www.example.com/subdir/LANGUAGECODE/news.php

    But, I do want to take out the language code, since it's my believe it should not be part of the url: sticking with the example above: a user should be able to type in www.example.com/news and arrive at the correct page. If the user's language cannot be defined (via cookie, session, GET variable or browser check) the news will be shown in the default language.
    Of course, on top would be a link that would allow the user to click on another language and the page will be 'translated on the fly'...

    Also the subdir under the webroot is not necessary at all, in time, it should dissapear...

    But all this has led to a problem in my menu class, in that I still cannot add other menu options in a different dir than the subdir.

    A solution could be I use place holders in the ini files for the menu, but that seems like too much of hassle...
    somthing like
    Code:
     [news]
     url = "subdir/%s/news.php"
     tooltip = "Read the latest news"
     
     ; ...
     
     [newMenuOption]
     url = "newMenuOption/"
     tooltip = "..."
    Or I could add another parameter to the menuoption definitions, indicating the use of the unnecessary subdir and have the code of the menu class sort it out?

    Anybody has other ideas how I should take this little hurdle with a swift and elegant jump?


    PS: In my post above, I wrote "Silly as it may sounds..." or something similar a few times.
    I just want to make clear that the 'silly' was in regard to my typings, not in regard to the posts I quoted
    Per
    Everything
    works on a PowerPoint slide

  12. #12
    SitePoint Addict
    Join Date
    Aug 2002
    Location
    Ottawa, Ontario, Canada
    Posts
    214
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    But, I do want to take out the language code, since it's my believe it should not be part of the url:
    Interesting, I like to (in a way), do the opposite. We divide the languages into two distinct directories based on acronyms.

    For example, ABCD might be the english subdirectory, and DCBA might be the french. I can then use PHP to determine the language that should be displayed based on the path in the URL. If you are on a *nix system you can even keep all the code for both languages in one directory, and use a symbolic link to point the other directory to the one where all the code is. In the URL it will look like two different paths, but in reality they point to the same place.

    I guess there are a million ways to approach multi-lingual sites.

    I want to add that I too, don't like language indicators being what I call "over the top" in a URL. I don't mind language detection based on directory like I outlined above, but I really don't like seeing stuff like news_e.php and news_f.php. The latter seems much more blatent than the former to me.

    Cheers,
    Keith.

  13. #13
    SitePoint Enthusiast BDKR's Avatar
    Join Date
    Sep 2002
    Location
    Clearwater, Florida
    Posts
    69
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, I know I'm coming to this late, but I figured I'd thrown in some noise.

    In the last two months, I started a job where I was the most junior member in a team of three. However, in the span of two weeks, I became THE ENTIRE IT Dept.!

    AAARRRRRGGGHHH!!!!!

    Now while the existing coding projects are not bad in regards to architecture, the practices of the dept as a whole were in the gutter. No CVS, documentation, and no bug database (other than 'Oh, that doesn't work').

    I feel your pain. Reading through code that is not well documented and not really your writing style is a bummer. Then there's that boss that isn't about to understand.

    !

    I really need to get something of my own going....

    Cheers,
    BDKR
    If you're not on the gas, you're off the gas!

  14. #14
    SitePoint Zealot
    Join Date
    Jul 2003
    Location
    Palo Alto
    Posts
    179
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by BDKR
    No CVS, documentation, and no bug database (other than 'Oh, that doesn't work').
    I went through almost the exact same thing on my last job, only it took a few months for them to turn me into a team of one (and frankly, I was not unhappy about it). My best advice:
    1. Install CVS for yourself, and do daily builds if at all possible. When someone else hoses the codebase, you'll be the answer to their prayers.
    2. Document everything you can, as much as you can, even if only for your own sanity.
    3. Install bugzilla immediately and use it religiously. When people report problems, tell them to use bugzilla because you are so busy you "won't be able to remember it for more than five minutes."
    4. Go read Painless Bug Tracking and everything else on that site. I did not know about this one until a few days ago, and it would have been a big help.


    The good news: at my last job, bugzilla started with just me, and soon after I had my whole team (they hired more people) using it to track bugs and feature requests. Then the entire web team started using it. Finally, a very smart and hard-working QA guy gave a presentation to the whole development department on how to use bugzilla, and managed to turn its use into SOP. I think the time from my initial install to department-wide implementation was about three months.

    More good news: you'll probably learn more at this job than you ever imagined. The hardest projects are always the best skill-builders. Best of luck....
    I think there is a world market for maybe five computers.
    - Thomas Watson, chairman of IBM, 1943.

  15. #15
    SitePoint Evangelist
    Join Date
    Jul 2001
    Location
    Michigan, USA
    Posts
    414
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I like listening to the development experiences others go through in the real world. There isn't much of the real world going on at school. I've gone through my first three semesters and have only taken three CSE courses. One was a freshmen seminar and one was a math class. I've learned a ton more about development right in here.

    I just hope my Software Design and Engineering class offers half of what the potential for learning here is!

  16. #16
    SitePoint Wizard gold trophysilver trophy
    Join Date
    Nov 2000
    Location
    Switzerland
    Posts
    2,479
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Late to the fray...

    As BDKR points mentions - CVS is a big one - if it's not under CVS and there's a server, that should be a top priority. If there's no server, raise it at the next meeting and perhaps set one up for yourself if it doesn't take long - an quick to install alternative is Subversion BTW.

    Otherwise, as Markus says, many small steps - avoid big ones and watch out for things from which it's not easy to go back.

    One other note is "vanilla PHP", no matter how bad it looks, can often be "added to" (i.e. new seperate functionality added) without needing to interfere with what's already there. At the same time its still possible to give the end user the impression that things are well integrated.

    If this project has a tight deadline, I'd concentrate purely on adding your bit, following your own design practices and worry about the rest some other time. You'd could raise with your managers your opinions of the overall design as tasks for later improvement but if you get sidetracked by fixing other issues, it may end up making you look bad as your failed to "deliver".

    At to the menu system, it may be worth breaking it into a class which analyses the URL (and later becomes the only point for modification for "translating out" that subdir) then the menu class which communicates with it. The menu can be taught to expect the URLs like you eventually want them to be while the URL analysis class can work on translating what is now to what the menu expects. Just a guess.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •