software design question

Uwe Mayer merkosh at hadiko.de
Sun Feb 8 00:15:32 CET 2004


Pierre Rouleau wrote:
>> So the question is rather: how to make a better design?
> 
> Why not look at the GUI as a "presentation layer" that provides access
> to the program functionality, like file I/O, help access, etc.  Then the
> file I/O, help, (etc...) can be written without any knowledge to the GUI
> (and therefore testable from a python shell or a testing script) and the
> Gui code just call the File I/O, help functions or members.  If you need
>   callbacks, then provide callbacks.   This way you would decouple the
> GUI from the system functionality.  Only GUI code would import the other
> modules.  The File I/O, help (etc...) would not know anything about the
> GUI implementation requirements.

I've already got separate modules for non-GUI related functionalities, i.e.
accessing record based file formats, etc. These are imported by the module
that currently covers "Open", "Save", "Save As", "Properties", "New" (in
the File menu).
This alone spans 442 lines (including comments and empty lines), containing
only dialog interaction and calls to the previously mentioned file-module. 

Is 500 lines a good count to start splitting up the code?

Currently the "main" part is just a main widget with all its toolbars, menu-
and status bar. This part imports all other modules that then cover a small
portion of the programs functionality, i.e. one module covers all file
open, save, close related stuff, another may cover all help related
actions, another covers the presentation, modification and propagation of
the rather large collection of preferences, etc.

My current solution is thinking along the line that all these components
usually exist only once in the system, i.e. there's no reason why there
should be two objects covering the same preferences dialog.
So each component implements the list or dictionary interface by which its
data can can be accessed from other components. For example after opening a
file an access to the fileIO component like: fileIO[0:10] 
would return the first 10 records from the file.
Similarly something like preferences['fileIO'] might return all preferences
for the fileIO component, etc.
Of course the component that displays the record (presentation layer) will
need to be notified of a new file that has been loaded. To realise this I
have implemented a "callback" mechanisme similar to the Qt's SIGNAL-SLOT
mechanisme: the fileIO component registers signals "fileNew", "fileOpen",
etc. under the name 'fileIO'. And when a component wants to be notified
when a new file is opened it sort of 'fileIO.registerCallback("fileNew()",
self.fileNew_callback)'.
And then the fileIO module calls all callbacks in the list of "fileNew()"
when a new file has been opened.

Is this approach getting to complicated?

One problem I'm still having with this is: for component B to register a
callback at component A, B still got to have a reference to component A in
order to make a call like "A.registerCallback(...)"
You might not know what B needs to access, so you cannot pass "what is
needed" in the constructor, nor let the code that instanciates B set
attributes. 

Ciao
Uwe



More information about the Python-list mailing list