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.

The polymorphic program

It has been decided by PHBs that our product is to be split into separate apps to target different industries.
So cue a hole bunch of 'ifdefs' to slightly change the gui for each release.

But the data files for all these different versions have to have the same extention and I have to read old files.
Fortunately the data file is XML so I can tag which app at the start.

At the moment I read the file and then at runtime flip the program into which ever version is needed for that file!
So if the customer installs eg. myWord, myExcel, myPowerpoint and clicks on .mydoc it starts whichever as installed last and converts it into the correct app on startup.

This strikes me as basically insane - I was wondering if a better option was a mini launcher app that would parse the file and then exec() the correct app - this is on MFC/Win32.
Martin Send private email
Wednesday, May 14, 2008
 
 
Any solution is a little "insane" because you (or your boss I guess) is violating the concept of associating a file type to an app... that's why it's separate .ppt .xls and .doc and not .mso (microsoft office?).

A small "launcher" that parses it and loads the correct app sounds about the cleanest you can get though.
Bill
Thursday, May 15, 2008
 
 
"violating the concept of associating a file type to an app"

This is a uniquely dos/windows concept I think, this concept "violates" the concept of keeping a data stream and the stream type together.  I think in unix/linux the data stream itself defines what type it is and there is no external metadata (like a filename extension) needed to type the stream.  Or am I incorrect?
dd
Saturday, May 17, 2008
 
 
True, although desktop systems like Gnome/KDE do use extentions.
Perhaps the best system was on the Acorn Risc-OS, there was a 32bit int associated with each file, the top 16bits were assigned to the software publisher and the bottom set to associate it with whichever app you wanted.
A bit like MAC addresses, you could apply for a free block from Acorn.
Martin Send private email
Saturday, May 17, 2008
 
 
"This is a uniquely dos/windows concept I think, this concept "violates" the concept of keeping a data stream and the stream type together.  I think in unix/linux the data stream itself defines what type it is and there is no external metadata (like a filename extension) needed to type the stream.  Or am I incorrect?"

You are correct, but this is good only in theory. In practice, users want to use filename extensions anyway, so that a quick look at the filename will give them a hint on what's inside.

Somehow, every Unix programmer stores his C code in .c files, Fortran code in .f or .for files, etc.
quant dev Send private email
Sunday, May 18, 2008
 
 
Your current approach is not too insane at all - provided you package it properly. To me it sounds absolutely preferable to the #ifdefs.

How to package it? I'd suggest you use dynamic link libraries (or their equivalent in whatever you're using), and load them at runtime. (LoadLibrary / GetProcAddress for the old-fashioned type of dll - you can do all this in .Net too).

The bootstrapping technique is generally.

a) Look for a dll of name X, where you could specify X however you like.
b) Look up a specific function in that dll - usually always the same name.
c) Use that function to get a factory class from the dll, which follows the same interface in every case, but can have a different implementation, as needed.
d) Use the factory to make other top level objects for each version of the program.
e) You can have other dll's with standard compile time linkage that contain all the content that's shared between the programs.

I think this gives you everything you're after.
a) You don't have to load code that you never use.
b) You don't have to give every user every dll.
c) It organises the bits that are common in each program, and the bits that are not.
Duncan Sharpe
Tuesday, May 20, 2008
 
 
Clarification of point c)...

You should have one single abstract base class which defines the interface to any of the dll's. This should be known to the .exe, so it can call the functions in it.

In each dll, you can safely inherit from this abstract base class. The virtual function calls propagate beautifully across the dll boundary. So implement an interface something like this

class PHBSplitterBase
{
  virtual OpenFile(const stream &File) = 0;
  virtual StartNewSession() = 0;
  ...
};

and in each dll, have

class ExpensivePHBsplit : public PHBSplitterBase
{
  implementations of base methods
};
Duncan Sharpe
Tuesday, May 20, 2008
 
 

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

Other recent topics Other recent topics
 
Powered by FogBugz