looking for a pattern to code logic shared by gui/cli

Chris Rebert clp2 at rebertia.com
Thu Apr 16 15:55:11 EDT 2009


On Thu, Apr 16, 2009 at 12:36 PM, Andreas Balogh <baloand at gmail.com> wrote:
> Only recently I have started developing code for application providing both
> a GUI and a command line interface (CLI). Naturally I want to reuse the
> business logic code for both GUI and CLI interfaces. The problem is to
> provide feedback to the GUI on the one hand, to the CLI on the other hand -
> by the same piece of code. My example shows a find_files() method browsing
> through a directory tree. As this might take a while every directory browsed
> shall be displayed on the terminal or in the GUI (an optimisation is to
> display the current directory only once a second). When a file fitting the
> criteria is found it is shown as well in both terminal and GUI list widget.
>
> I can easily write a piece of code for the CLI for that:
>
>   import logging
>   import os
>
>   LOG = logging.getLogger()
>
>   def find_files(src_dir):
>       for root, dirs, files in os.walk(src_dir):
>           for file in files:
>               # feedback for the CLI
>               LOG.info("scanning %s %s", root, file)
>               # check for file pattern here
>               if os.path.exists(file2):
>                   # feedback for the CLI
>                   LOG.info("found %s", file2)
>                   # retrieve more file_details
>                   files.append((file, file_details))
>               else:
>                   LOG.warn("no file found for %s", file)
>
> and for the GUI version:
>
>   import Queue
>   import os
>
>   class Model:
>       def __init__(self, model):
>           self.model = model
>           self.status_text = ""
>
>       def notify()
>           "send message to Tk root widget to tell GUI thread to
>   synchronise view"
>
>   def find_files(src_dir, model):
>       for root, dirs, files in os.walk(src_dir):
>           for file in files:
>               # feedback for the GUI
>               model.status_text = "scanning %s %s" % (root, file)
>               model.notify()
>               # check for file pattern here
>               if os.path.exists(file2):
>                   # feedback for the GUI
>                   # retrieve more file_details
>                   model.files.append((file, file_details))
>                   model.notify()
>               else:
>                   pass
>
> Now I have duplicated the "business logic" of find_files() for a GUI driven
> application and a CLI application. Using the same code is easy as long as no
> feedback is required during operation. But in this case the os.walk() might
> scan an entire disk taking a minute or two. Here both the terminal or the
> GUI need to provide feedback about the directories being scanned or the user
> might think the application has died (I would certainly).
>
> Solutions with callbacks seem kind of ugly to me as they require "model" to
> be passed through for GUI and LOG for the CLI version.

Really? Seems like quite a simple and elegant solution to me. IMHO, a
mere one extra parameter does not bad code make.

Cheers,
Chris
-- 
I have a blog:
http://blog.rebertia.com



More information about the Python-list mailing list