Wednesday, July 13, 2011

Raising the Visibility of GLOBAL, part 2: Extracting a Facade

Last time we pulled COMMON blocks into single module of their own, hereafter called GLOBAL.

If the code has any Fortran 90 in it, we are likely to find derived types as well. At the very least, we are likely to want to have our specifications of precision (the SELECTED_KIND) available. This is an excellent opportunity to make use of the DRY (Don't Repeat Yourself) principle--every source of information should have one, canonical place that it resides.

For both of these aspects, the next step is to pull the types into a separate file (typically called something intuitive like XXX_TYPES.for). This can be a MODULE, or a simple INCLUDE file. I prefer to use MODULEs; it reflects my intent better. I generally reserve INCLUDE files for interfaces. Separating the types (parameters, derived types, etc.) from the COMMON data allows me to make broad use of the types, without requiring me to drag around the baggage of the global data. GLOBAL then USEs TYPEs, ensuring that I haven't broken anything, and requiring no changes to any other code.

All of this has been preparing for the main step of pulling the routine we care about behind a Facade. To rehash: what I currently have is a SUBROUTINE ABC with a call with few (or no) parameters. BUT, there is a ton of back-channel communication going on via reads and writes of variables in the COMMON structures. I want to make the communication explicit. To do so I follow three steps:
  1. Create a new subroutine with the name SUBROUTINE ABC_FACADE. In this SUBROUTINE, we USE the GLOBAL block. Beyond variable declarations, the only thing in the ABC_FACADE routine is call to ABC.
  2. Change all calls to ABC to calls to ABC_FACADE. I let the compiler do the heavy lifting here. I change the name of ABC to ABCx, compile, and locate all the link errors. At each location, change ABC -> ABC_FACADE. No other modifications.
  3. Change the name of ABCx back to ABC. Compile and run a quick test. No functionality should have been affected. At worst, we have created a slight degradation in performance, due to the intermediate SUBROUTINE call.
So what have we gained? The ability to make changes to the interface of SUBROUTINE ABC without affecting any client code, which we will indeed do, next time.

No comments:

Post a Comment