For a variety of reasons, an application's graphical
interface tends to be an exceptionally volatile and
ever-changing piece of software. It's the focus of most
user requests for change. It is difficult to plan and
execute well the first time around---often you will
discover that some aspect of it is unpleasant to use
only after you have written it. Making things worse,
graphical interfaces are not portable across machines;
Gnome works on X windows, but if your application is
useful, it won't be long before someone wants to run
your application on another system, or have a
command-line version, or have a web-based interface.
You might even want to have two interfaces in the same
version---perhaps the GUI, and a scripting language
such as Guile.
In practical terms, this means that any large
application should have a radical separation between
its various frontends, or
interfaces, and the backend.
The backend should contain all the ``hard parts'': your
algorithms and data structures, the real work done by
the application. Think of it as an abstract ``model''
being displayed to and manipulated by the user.
Each frontend should be a ``view'' and a
``controller.'' As a ``view,'' the frontend must note
any changes in the backend, and change the display
accordingly. As a ``controller,'' the frontend must
allow the user to relay requests for change to the
backend (it defines how manipulations of the frontend
translate into changes in the model).
There are many ways to discipline yourself to keep your
application separated. A couple of useful ideas:
-
Write the backend as a library; if this becomes
undesirable for any reason, you can always
statically link.
-
Write at least two frontends from the start; one or
both can be ugly prototypes, you just want to get
an idea how to structure the backend. Remember,
frontends should be easy; the backend has the hard
parts.
If one of your frontends is Gnome- or GTK+- based, an
excellent choice for the other is an interactive Guile
terminal. Your non-expert end users probably won't use
it, but it's a great debugging tool; you can prototype
and test the backend using easy-to-write Guile
bindings, and add the graphical controls only when
things are working. When you're done, you'll have a
scriptable application almost for free.
If your application can potentially be run in batch
mode, command line and web interfaces are also
relatively easy to write, useful for debugging, and
will keep you disciplined.
Finally, if your project is large enough to justify the
bother and complexity, consider using a cross-platform
frontend layer to share code between GUI frontends on
different platforms. This approach is taken by Mozilla
(https://www.mozilla.org), and the AbiSource
office suite (https://www.abisource.com). It might
be interesting to have a look at their code.