The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Maintaining old code while adding new features

A bit of background first, I'm a pretty recent engineering graduate. I'm not employed as a programmer or a developer or anything like that, but a large part of my job does involve programming.

Most of my experience is in C, it was the language we were taught at uni and it's what I've written most of my programs for. I'm a pretty big Linux geek and have done a fair bit of 'hacking around' at home writing some (pretty crappy) drivers and messing around with the kernel things like that. I'd say I'm pretty comfortable with the language.

I've been working for the last year or so on some pretty low level stuff at work, interfacing with PLC's that sort of thing. I've recently "inherited" command of an engineering process, modelling and simulation model we have. The model is quite complicated and is written in Fortran, it represents well years of R&D by our company and does a lot of complex stuff (mainly Chemical kinetics and Fluid dynamics). It's now my job to maintain, improve, continue to develop etc. I've spent the last 2 months learning Fortran, familiarising myself with the inner workings of the model.

The model was written by engineers, not programmers, you can tell by looking at the code, it's not pretty at all, it's been upgraded at various points had features "rammed" into etc. A lot of things are hard coded in and it's becoming increasingly more difficult to upgrade it and add "trivial" new feature etc.

I'd really like to redesign the whole architecture of the model, make it more modular, change the way it implements a lot of things and I've been given approval to do this under the condition that it remains backwards compatible.

Also, when the project was handed over to me I received a half completed and pretty buggy "front end" for it, designed to run in Windows and provide a "nice" looking graphical display for the model's output. It's been written in C++. Improving this front end has been on a lot of people’s wishlists for a long time, I'd like to do something with it but C++/ Windows GUI programming is a long way from my area of expertise.

So I have 2 questions, the first is to do with upgrading/changing the models architecture, does anyone have any techniques to help me ensure I maintain compatibility, any advice would be welcome. What I'm afraid of is if it takes me a long time to change the architecture, development on the model will stagnate, is it a good idea to be working on new features while simultaneously re-writing the old model (say devoting half my week to the upgrade and half to further enhancement).

I've debated the merits of re-writing the thing in C, but performance is pretty critical (by performance I mean time it takes to run a simulation). I think a lot of the scientific functions and things it implements are better off being written in Fortran still. Floating point precision is another big thing, it was originally written to run on an IBM RS/6000, The documentation I have seems to indicate there were some decimal precision issues when it was ported to PC's and there’s some ugly hacks in places, I think this is more to do with the IBM Fortran compiler and the switch from Fortran 77 to Fortran 95) then hardware though...

The other question is about the front end, I know the basics of OOP, we were taught a language called Eiffel briefly at uni and I've also used a little bit of GTK stuff in Linux, but that’s the extent of my knowledge of GUI's, the Windows environment is pretty much alien to me, I've spoken to a few guys at work and I've borrowed a few C++ books (namely, Stroustrup), is there any good references specifically on writing Windows apps with C++

Thanks.
Matt
Thursday, March 22, 2007
 
 
Don't perform a total rewrite:
 - You're not very experienced
 - You don't have a deep understanding of the domain
 - You don't have a deep understanding of the design
 - A lot of man-years went into the current code base. (You want to leverage that by making it cleaner, not waste time resolving the same problems)
 - You won't be visibly adding value to the company, which means no one will care. You need to make your boss look good by adding something new.

Being backwards compatable means that the external interfaces won't break (e.g. you can still load from a netlist rather than only from your own XML format), but you are free to change the core. Do what you're leaning towards - continuously improve the architecture as you add new features. Not only will you learn more about the system, but you'll build momentium by solving the problems that you manager is concerned about.
Manes
Friday, March 23, 2007
 
 
> does anyone have any techniques to help me ensure I maintain compatibility

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

http://www.refactoring.com/

http://www.refactoring.com/sources.html#Books

> is there any good references specifically on writing Windows apps with C++

Yes, but if you've never done it before and you're writing a new GUI from scratch, it might be a idea to consider using C# amd the dot-net framework instead of C++ and the Win32 API, because:

* C# is similar to C++ but easier
* The dot-net framework is a more modern API than Win32

If you're not comfortable with C++ (you say that most of experience is with C) and if you don't want to use C# and .NET, note that the Win32 API is in fact a C (not a C++) API; there are (non-O/S) C++ class libraries that various companies (including but not limited to Microsoft) have written to wrap this API.

Introductory books (I haven't read them but I think they're canonical) are http://www.charlespetzold.com/books.html ... the other important source of information is http://msdn.microsoft.com/library/ (goodd news and bad news: it's big).

> provide a "nice" looking graphical display for the model's output

When you say "graphical", do you mean graphs? Or just buttons and edit boxes and things like that?
Christopher Wells Send private email
Friday, March 23, 2007
 
 
> I've debated the merits of re-writing the thing in C, but performance is pretty critical (by performance I mean time it takes to run a simulation). I think a lot of the scientific functions and things it implements are better off being written in Fortran still.

Why is Fortran better?

In any case I'd guess that well-designed, well-written C can be faster than badly-designed Fortran.

Also I've seen Fortran invoke a library written in C http://www.physionet.org/physiotools/ecgpuwave/src/ and no doubt the reverse is also possible, so a mixed-mode program (replacing Fortran routines with C routines, adding new routines in C) might be possible.
Christopher Wells Send private email
Friday, March 23, 2007
 
 
Matt,

You ask a great question. The short answer is, don't go rewriting the existing code - instead learn about the existing code and write lots of automated tests it. The tests will help you make sure you don't break things that used to work, which I expect would make your co-workers and boss very unhappy.

Figure out how the program works piece by piece, and then when you learn something new about its behavior (or think you have), write a test which verifies that. Pretty soon you'll have the justified confidence to make bigger and bigger changes and be less worried about breaking something.

Also, a great piece of advice I heard is that when you're trying to add a feature and it's hard to do in the existing structure, first restructure things so adding the feature will be easy, and then add the feature. Over time this will make your code much nicer.

p.s. I agree with all the preceding advice. "Refactoring" is a great book, and even if the specifics don't all apply to your language the philosophy is still great.
Andrew Monat Send private email
Friday, March 23, 2007
 
 
Thanks for the speedy replies,

As far as adding value goes, that’s a very good argument, one that I hadn't considered, being a research oriented department, my boss will not be riding me too hard about immediate results, but it will be useful for downstream, production.



>"Yes, but if you've never done it before and you're
 >writing a new GUI from scratch, it might be a idea to
 >consider using C# and the dot-net framework instead of
 >C++ and the Win32 API, because:"

My intention wasn't to write from scratch but continue with the existing C++ application, My understanding of dot net was it's pretty tied to the specific version of windows your using, this app will likely be around for a number of years and I'd like it to be version independent if possible.

>When you say "graphical", do you mean graphs? Or just
>buttons and edit boxes and things like that?

Both, at the moment the inputs for the model are configured to run by editing a text file, these inputs define a number of constants/constraints etc that feed into the algorithms (most of these are of no use unless you want to debug the model or run a very specific sort of simulation), the front end attempts to let the user easily configure these constraints, by having drop down boxes, where the user can select the more common cases and have the files auto-generated. The front-end is several versions out of date now, so manual manipulation of the files is still required. We are under a bit of pressure to roll out a release with a polished interface, because the model is of little practical use if the "Average Joe" guys in a control room, can't easily run a simulation.

There has been some recent additions to the model and it now uses an open source Visualisation toolkit (called VTK) to generate some 3d thermal images etc as output, a simple viewer has been written to display these images and the GUI links into this, it's not perfect though and has a tendency to crash occasionally. Which also makes it frustrating for control room use.

Basically the model is off the most interest to my department (my boss etc) but the GUI is probably more valuable for the company as a whole. By redesigning the model I think I can make the front end less version depend, goal would be to have a front end that works with all versions of the model.
Matt
Friday, March 23, 2007
 
 
> My intention was ... to continue with the existing C++ application

If you've already decided that, the existing C++ application probably uses a C++ class library (a.k.a. "framework") which wraps the Windows API: that class library might be "MFC", "ATL", or a library from a 3rd party.

If that's the case, then "good references specifically on writing Windows apps with C++" is, more specifically:

1) good references on C++
2) good references on whichever specific class library it is (e.g. MFC)

> the front end attempts to let the user easily configure these constraints, by having drop down boxes

There might be an easier/better way to write this kind of form than by using C++ ... I don't know ... how about HTML forms instead?
Christopher Wells Send private email
Friday, March 23, 2007
 
 
"Refactoring" is good for writing clean code, but it doesn't help for larger structural changes. "Refactoring to Patterns" did a good job on that front and I've heard good things about "Working Effectively with Legacy Code".
Manes
Friday, March 23, 2007
 
 
Hmm by using html are you suggesting something like writing a web app, i.e

user loads form in browser,
submits info to some sought of server,
server processes input,
server runs fortran,
browser serves up a page with the output from the model,

Thats a pretty good idea actually.

Could probably knock something quick and nasty up in a week or two, it's a good "stop gap" soloution anyway. Theres a few "web guys" around here who could probably help me.
Matt
Friday, March 23, 2007
 
 
This is the book to read:
Working Effectively with Legacy Code by Michael Feathers

It describes a practical approach to take a mess of code and slowly refactor it when and where it makes sense. He describes solutions to different common problem with legacy code. Seriously read it, he makes the boring subject of legacy code interesting.

My old company used his ideas on a large C code project. Many of our files were 10K LOC so it was a mess and lots of it still is but the most often changed modules got cleaned up and are easier to work with now.

Check the reviews on Amazon, all very positive:
http://www.amazon.com/Working-Effectively-Legacy-Robert-Martin/dp/0131177052
Mellowman
Friday, March 23, 2007
 
 
+1 Working Effectively with Legacy Code by Michael Feathers
Mike S Send private email
Friday, March 23, 2007
 
 
+lots for the Michael Feathers book.

Fortran can actually be faster than the equivalent C in scientific computation. The semantics of Fortran allow for additional optimizations that C cannot. One of the biggest categories of these has to do with aliasing. Fortran lacks pointers, so can never have aliasing (two variables pointing to the same area of memory). As a result, the Fortran compiler can do stuff like store globals in registers.

Aggressive use of C++ template metaprogramming can be faster, because it does a lot of the work at compile time. The resulting code is often far less comprehensible than the Fortran.

My point is: don't be too fast to throw out the Fortran. It's probably carefully hand tuned using a compiler that's been designed to optimize exactly that kind of code. In your line of work, this kind of performance is *very* important.

So your approach should be to go read Michael Feather's book, build unit tests, and refactor to an architecture you can maintain.
Chris Tavares Send private email
Sunday, March 25, 2007
 
 
I would say the most important thing is not to make it worse while you are making it better.  Since you don't know the details of the system yet (and probably won't for years), I would write a few big-honkin' system tests of the main process model.  Take an existing complex initial state, stipulate a specific life cycle of specific inputs/sensor readings or whatever else the process simulation feeds on, and run it through the well-tested legacy code and record the results.  Then, as you move it to a new architecture, you can do a whole-system test.  When it fails, track down the bugs and write smaller unit tests for each problem situation.
JSmith Send private email
Sunday, March 25, 2007
 
 
+1 Working Effectively with Legacy Code by Michael Feathers

I'd weigh in on that too - definitely the one to go for, read it as soon as you can.
Arkestra
Tuesday, March 27, 2007
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz