Phantom Dialogs: A Sound Programming Practice?



Posted: Wednesday, October 24, 2007

by

Early in my career I wrote mainframe Batch and Online programs for the Massachusetts Office of Management Information Systems (OMIS); it was there that I first encountered a " phantom panel. "

While working on a Welfare "Fraud Squad" application written in DMS (Development Management System, an Online language that runs within IBM's CICS), I discovered a phantom panel written by one of my predecessors, Phil Olander. It was essentially a program piece that would accept data from an input panel, manipulate the data, and relay to a displayable target panel without itself being displayed.

My teammate on the application (and mentor), Larry Foley, hated phantom panels and urged me never to create them myself. I never did ...until recently, when working on an entirely different platform, issues that give rise to that kind of solution came up.

I created the prototype for my dialog-based application that calculates disk space, optimum block sizes, and sort work space for files to be created on IBM mainframes. I wrote the program in Visual C++, to be run locally in Windows; unlike earlier programs in various shops written in CLIST, REXX, or Dialog Manager, it's not necessary to log onto the mainframe to run it.

The application is written in the classic IBM style, including dialog names in the top right corner. The main menu (below) has five options; we'll focus on the first three.


Option 3 displays SPCCLSRT, an input dialog that accepts record length, number of records, etc. for a dataset to be sorted.


After filling in the fields with our choices,


pressing Execute gives us SPCCLC03, a target dialog telling us how many cylinders of a disk drive we'll need to sort the dataset, plus suggested SORTWK parameters to be used when writing our JCL procedure.


The input dialog SPCCLSRT is key here, since elsewhere in the application it serves as our phantom dialog.

Option 1 on the main menu takes us to input dialog SPCCLC,


which accepts the file parameters we provide to calculate the number of tracks or cylinders used for the dataset at various block sizes.


Pressing Execute gives us dialog SPCCLC01


In addition to the desired blocksize info, we're provided an option box to get sort details on the blocksize we select.


After we've filled in the Blocksize field, pressing Exec Sortwork gets us to target dialog SPCCLC03, as though we had gone through option 3 of the main menu.


What we don't see is behind-the-scenes computations, performed by SPCCLSRT, a dialog object which is invoked but never displayed!

A similar path is taken from option 2 of the main menu, used to calculate disk space needed for a dataset using a chosen blocksize. We get dialog SPCCLC06,


which when filled in like so


gives us dialog SPCCLCAL.


Pressing the optional Sortwork Calculation button there gives us dialog SPCCLC03, once again as though we'd chosen the main menu's option 3.


Once again the input dialog object SPCCLSRT operates behind the scenes without displaying its dialog.

Why do things this way? I've found it saves extra work, as I'll explain shortly. But first, bearing in mind that my mentor urged me never to create phantom panels, I contacted my former boss from OMIS, Virginia Perry, and explained this situation.

She didn't agree with Larry; according to her, at IBM the phantom panel was considered a brilliant design concept. It's also disparaged in some circles. People with only a microcomputer background to whom I'd spoken apparently never heard of phantom panels, and it never occurred to them that phantom dialogs could be used in dialog-driven applications.

The phantom dialog as presented here works beautifully. The sort work computations are done in input dialog object SPCCLSRT whether or not its window is displayed, and the target dialog is always the same whether we navigated through option 1, 2, or 3 of the main menu. Since the application is modal, we're always able to backtrack through the dialogs from which we came. The alternative of writing identical code in three different places in the application would have been far less practical -- would we really want to have to update the same instructions in three places?

But is the phantom dialog a wise design feature?

It may depend on how we interpret the object. Is it a displayable screen, with various enhancing capabilities built in, or is it a software module per se with numerous capabilities built in, one of which is an option to display a screen? If it is the former, then it is essentially made for display, and it would make no sense not to display it (to corroborate, why would we create a Print object that does not print?). Some design philosophies (and shop standards) might even consider it a violation of the object's intended purpose not to display the dialog. If the object is the latter, though, then we're free to take advantage of the features we want without incurring the obligation to use it for its ostensible "central" purpose.

A Microsoft frame window may contain objects, including two: a "document," and a "view." There a document serves to contain much of the window's internal computations, and a view contains computations directly related to the application's input and output data. Neither object has inherent display capabilities; they both basically help organize a potentially complex program by grouping related operations and help make the program more intelligible and maintenance-friendly. Should I likewise have written a nondisplay object that computes the needed data and pass the data to the output dialog object for display? Why, when a class already exists with the capabilities I need? Why invent an object with can-opening capabilities when there's already a can opener in the house?

Here's another slant on the issue, if you don't mind my being absurd. In a practical object class hierarchy the most fundamental operations and capabilities common to all objects of the hierarchy are in the base class, and more specialized extended behaviors are built into successive generations. In Microsoft Foundation Class (MFC) a simple window can be created from the class CWnd; a more elaborate window can be made from the class CFrameWnd (actually, in practical programming we design a window by creating a new class derived from one of these classes, and dress it up however we want). But CFrameWnd is derived from CWnd, and is using functions from CWnd. When an object of class CFrameWnd is created, the constructor for CWnd is activated, and also the constructors for ancestor classes CCmdTarget and CObject. In effect, objects of all those classes have been created -- or rather, "partials" of the ultimate derived class CFrameWnd. Since some form of a CWnd object then exists, does that not obligate us to display a CWnd window at some point? Or are we just using its "innards" and not treating it properly as a window in its own right? And are we not obligated to use all of its methods or behaviors including ShowWindow()?

Not really; as I said, I'm being absurd. A stack of partials and an end-derived class object are effectively one object, and inheritance gives our compound object abilities it need not exercise. But invoking and using a compound object is a concurrent deal, while in my dialog program the display and nondisplay objects are run consecutively. Can we not use the same prerogatives with SPCCLSRT as we do with CWnd?

The phantom dialog as implied earlier is reusable code, so it fits an important criterion of object-oriented programming. Not everyone will advocate it, but it appears to work well in this program.

Still, since I'm a team player, I do observe the shop standards in any company for whom I work.

(SPaCeCaLCWiN Space Calculator for IBM MVS, copyright 2003 Wilfred D. DeVoe)

Wilfred D. DeVoe is a software developer/programmer who has worked in both full-time permanent and consulting roles in public and private sectors.  He holds Bachelor's degrees in Computer Science (Boston University) and Psychology (Salem State College).  His education and interests give him a unique perspective he likes to share with colleagues and interested people.
This Article has been viewed 355 times. (Not updated in real-time.)
No comments yet.
We want your comments! If you can read this, you don't have javascript enabled, so you can't use this comment system. Please enable javascript.