MasterMind
 
 
 

 Preface

The primary goal that inspired me to create the MasterMind tool set was to provide the PROGRESS developer community the best opportunity (i) to develop self-explanatory projects (ii) to properly structure major applications in order to keep the application logic crystal clear for better understanding (iii) to help maintain a close relationship with the underlying business. This idea came to me from my 12 year work experience, first as a psychologist studying the peculiarities of a programmer's work and the cycles of a "programmer's thought process", then as a systems analyst and a PROGRESS developer.

There are many well known profiler systems for measuring an application's performance. But there is no profiler created yet, which measures/enhances the performance of a programmer's thought process. In my psychological studies I revealed that the way you represent the information (algorithms, data) improves the performance of a programmer's mode of  thinking dramatically. Any type of information can either be provided in a very "digestible" form,  in which case it can be easily used for practical purposes as compared to an obscure presentation which cannot be utilized or understood easily. Both ways might be 100% correct from a formal point of view, but an individual happens to be an informal creature, which means that some specific ways of representing the information are more suitable for better understanding.

In order to structure and manage the project information efficiently, it is very crucial to keep the logic clear. This means that not only the manner of representation but also the availability of the information about the project is very important for its success. The common problem arises when your project starts growing rapidly and you can't correlate the information between the different parts of your application merely using the code and specifications. A simple task of finding the business rules, algorithms, data constraints, etc. pertaining to a specific project turns into a nightmare, because of the vastness of the project. The consistency of the logic in an application tends to degrade for the same reason (i.e., poor availability of useful information) and it cannot make the flow of your thought process contiguous. This results in a loss of control over the application logic and snowballs your project. It further forces you (i) to extract the information from different parts of the code numerous times (ii) to clarify logic repeatedly (iii) to put your explanations in writing or sometimes just remember it if you don't have ample time to document. When you eventually come to a certain conclusion, you may end up forgetting what you started with. Thereby, you end up crawling around your project and lose a lot of precious time. If only you could (i) reorganize your way of thinking (ii) structure your project properly (iii) keep the logic clear and straight, you can save a lot of time and be more productive. This unique opportunity to develop efficient applications in a very short span of time is provided to you by the MasterMind tool kit.
 

The "Achille's heel" of ADE technology

Application Development Environment gave PROGRESS developers a unique opportunity to take advantage of an event driven and object oriented programming technique. Look at Fig.1 to see the key differences in development techniques between V6 and V8 (V7 is an intermediate version, a mix of these two different styles).
 
Fig.1.  Key differences between V6 (procedural) and V8 (object oriented, event driven) programming styles:

Issue

PROGRESS V6

PROGRESS V8 ADE

Application model Application driven, Procedural Event driven, Object Oriented 
Flow of application Algorithm driven Data driven
Coding style  Plain code readable "from beginning to end" A set of relatively independent SmartObjects
Type of relationships between procedures Hierarchial Arbitrary
Mode of application management Running external procedures  Using ADE interaction protocols (Record, State, Dispatch, Notify)
Data exchange Passing runtime parameters 
Using (global) shared variables
Setting and getting Instance Attributes
Code developing method Using plain text editor and 100% manual coding Having an interface layout and a major part of the screen logic is coded by UIB
Factors that impact the application behavior (except the user action and application data) PROGRESS 4GL code developed solely by an application programmer PROGRESS 4GL code; 
ADE Protocols rules; 
Specific data stored in the ADE environment
 

This new programming technology benefits us a lot, but at the same time it forces us to face a new set of challenges in the PROGRESS application development environment . These challenges are not permanent withdrawals but are infact, a growing pain. The flexibility of an application model always facilitates the developer to effectively implement the business logic. In order to maintain the flexibility in an application you need to make some special efforts constantly to keep the logic consistent and clear. Well, what exactly are the possible ways to maintain the clarity of the application logic? Say for example, the PROGRESS V6's plain coding style gave the developer a great opportunity to understand the application logic by simply breezing through the self-explanatory source code. Whereas, the new technique makes the application behaviour depend on special type of data stored in the ADE environment. As a result of which the code ceases to be self-explanatory, and this infact affects the situation significantly. Each SmartObject is like a single note of a song, with the music stored in the ADE, and only when all the notes combine, the song is composed which is like the entire application logic. You can't understand the meaning of that "song" without combining and observing all the data that SmartObjects use to pass each other. Unfortunately, the prinout of the source code is not of much help for a project written in ADE, because you can't read the code and make sense out of it like in V6. You will notice that SmartLinks are created, removed and referenced  in various parts of an application which makes it highly confusing.

When you use a SmartLink within a SmartObject in order to interact with other SmartObjects, you don't refer the object(s) on the other end of the link by its name, but instead use the pertinent SmartLink. You simply call an appropriate ADE procedure, and then the SmartLink takes care of the rest. Once a SmartLink is defined, it can be used numerous times until it is removed. This mechanism significantly cuts down the length of manually written code, thereby giving the developer an opportunity to write applications faster (which is known as Rapid Application Development). But on the other hand, one has to carefully keep a watch on the SmartLink table in the UIB and/or search the code for all relevant add-link and remove-link statements in order to know the components of a particular SmartObject interaction. You can ofcourse use the display-links IN adm-broker-hdl statement to test the application but it won't be of much help if you create and remove links dynamically during the session, depending on the application flow. The more complicated your business logic, the more number of SmartLinks you will be needing to implement the logic in your application. At times you might want to make some of your SmartLinks dynamical, which means manually adding and removing the links in the code. Additionally, you also need to keep an eye on the Instance Attributes. When a procedure passes the parameters to a subroutine, they are always passed as a set which is constant for each caller within the specific routine, so it is very easy to maintain the logic. Unlike these traditional subroutines, SmartObject's set-attribute-list and modify-attribute-list procedures can arbitrarily create new and modify the existing Instance Attributes contained within, which tends to modify the behavior of the objects. This technique makes the application logic very obscure and proves to be hazardous. At any point of time if you miss or omit one minute detail, it won't take you long to end up with a bowl of sphagetti!

It will be a nightmare trying to remember what you started with after a certain point of time, or even say training a team member if there is no proper documentation and data flow diagrams with specifications. To avoid the consequences of the above situation I have developed the MasterMind tool set. It helps you to easily understand the logic within (i) a particular SmartObject (ii) a large container integrating a group of SmartObjects (iii)and the entire application including the complicated relationships between the SmartObjects. In brief, MasterMind offers a solution to enable you to take the best advantage of the ADE, keeping the application logic clear and easily maintainable.
 
 

MasterMind's main components

The main components of the MasterMind tool kit are:
 
SmartErrand Programmatical Mechanism  A very powerful generic mechanism that provide very clear, understandable and 100% dynamic interface between the procedures in a PROGRESS procedure call stack
Open File Dialog  This Dialog is used to get direct access to the project structure and pick the right program instantly See demo screens 
Repository  The MasterMind's Repository is kept in a PROGRESS database. It holds all the information about the projects you are working at. This information is added by the user (the information about module structure, screen names, the types of the objects admittable for registering in the Repository etc.), the other part of data in the Repository is supplied by the MasterMind's Source Analyzer, which elicits information about the UIB-created compilation units from the source code and especially, from a variety of psewdo-statements that resides within the bounds of regular PROGRESS 4GL comments. 
 
Repository maintenance utility Provides an access to the Mastermind's Repository and allows to keep it up to date See demo screens
MasterMind's Source Code Analyzer An XFTR-based tool which scans PROGRESS 4GL source code, extracts MasterMind's psewdo-statements (actually, some comments with special syntax consideration which hold information about program functionality). This part of MasterMind works together with the SmartErrand Manager, both are launched from the same XFTR See demo screens
Project Viewer Provides a comprehensive view on the project structure, including Modules, Screens, SmartContainers and contained objects, Lookups, Include files and External calls as well as SmartErrand schemas See demo screens
Source Tailor A utility for massive batch-mode source code modifications, provides a powerful set of operations with text See demo screens
Send-Errand procedure Call Wizard An interactive tool that facilitates creation of Send-Errand procedure calling code block alognwith pertinent comments, guiding the user through several steps See demo screens
Glossary An interactive tool for creating multiple dynamical hypertext glossaries and keeping them up to date. Can be accessed from either MasterMind Desktop or from within Project Viewer, to see a keyword in the Container or Object description See demo screens
 
 
 
 

What is a SmartErrand mechanism

SmartErrand mechanism is the key component of MasterMind's core. It contains a set of include files that provide (i) very clear (ii) understandable (iii) and 100% dynamic interface between the procedures in a PROGRESS procedure call stack. This is regardless of it being a SmartObject or a certain procedure being persistent or not. Now, where and how can the SmartErrand mechanism be used?

Say for example, you are developing an application for a small distribution center where the sales price for certain items slightly differ based on the item type on a daily basis. When the item prices change, the manager will have to notify the stockman via phone or fax in the middle of a transaction (Like processing a new order (assuming that no EDI link still exists)). In that case the stockman has to suspend processing the order and run the Price maintenance module to make the new prices effective in the database. After that the stockman can proceed with the suspended order and the new prices. You can change this scenario by allowing the application to save the part of the order the stockman initially entered and change only the prices for some items by using an Event driven model. In an application driven model you can run only one module at a time. So you have to (i) Save the partially-entered new order data into a temp-table (ii) Run Price maintenance module (iii) Rerun the Order maintenance module and have it retrieve the previously saved data from the temp-table. This requires a lot of coding. Whereas an Event driven model offers the user more flexibility. The user can simultaneously (i) have more than one instance of the Order maintenance module in the memory (ii) make them active by bringing them in focus (iii) process several orders at the same time (iv) try different allocations of goods (iv) check the stock balance. The user can also run the Price maintenance module while keeping
(i) a few instances of Order maintenance module in memory (ii) each instance attached to an order in process. He can then simply recalculate the prices within each instance once the Price maintenance module updates the prices and exits.

The simplest (but definitely not the smartest!) way to do that is to just provide a user-interface solution for price recalculation. It can be a button, with a trigger behind the button which (i) scans the order item list (ii) retrieves the new prices from the database (iii) and calculates the new subtotals. But then, if the stockman forgets to push the "Recalculate" button in each Order instance after entering new prices it will result in printing out the previous amounts which have become obsolete. To avoid this situation, we should have our recalculation procedure done automatically, without any inter-action from the user/stockman. How do we proceed to do that? A pure ADE solution is to set a State SmartLink from the Price maintenance module to each instance of the Order maintenance module and then run a new-state("recalc-prices") procedure. The "recalc-prices" state will then be trapped and processed by the relevant CASE... WHEN clause of the state-changed procedure in each Order maintenance module instance. This procedure would probably tell the appropriate SmartObject in the Order maintenance module to retrieve the new prices from the database and recalculate the prices in the order(s) that are currently being processed. But then again, you can't take advantage of the UIB to create such a link for your application, because UIB creates only static links for SmartObject instances which are initialized only once and reside permanently in the pertinent temp-table. In our case the application modules are called and removed dynamically, therefore we need to create a set of dynamic links here. To do that we first have to find a procedure handle of the relevant SmartObject for each instance of the Order maintenance module on the procedure call stack. We should provide that facility to the SmartObject within Price maintenance module, which is supposed to notify the reciprocal modules that they have to recalculate the order price. So we have to manually write the 4GL code to create these links. This now forces us to ask the question - when the Price module finds the handle of the relevant procedure inside the Order module, do we really need to set a link to tell it to retrieve new prices from the database? Definitely not. The Price module has already done its work and is going to be removed from the procedure call stack. It just needs to tell its last will to the Order module instances (if there are any in the memory) before exiting. So we don't need a link here, it is more than enough to run the Recalculate internal procedure in the Order module, which takes care of the rest.

The above example does not sound very realistic but its sole purpose was to mainly establish the existence of atleast two types of relationships that tend to exist in a large application's logic. The relationship of the first type operates at the interface level of the application i.e., when one object has to tell the other one to do any of the following: (i) enable a widget  (ii) block user input (iii) select a new page (iv) reopen a query (v) pass a foreign key, etc. This type of  relationship existing within a module comprises of a set of SmartObjects but implements one major business function like a specific inquiry or maintenance. Usually these relationships are established on a regular basis, so the static SmartLinks implement the relationships in a very convenient and efficient way. But there are also relationships of entirely different kind existing between functional units that facilitate the implementation of business rules. Such relationships are more complex, frequent and more conditional. It is clearly established that event driven application can/will give the users an opportunity to run more than one branch of an application at the same instance of time (which is called "multi-window interface", MDI is a good example). When several business modules work concurrently and modify the data in the database, each module can update the database and then trigger the action pertinent to another module. In other words, changes in one working module can impose a set of changes to be made in other modules. It means that (i) every possible influence of one module to another must be foreseen (ii) the application must be written accordingly to trigger a set of actions in every instance when critical updates are made (iii) always maintain the business rule compliance. This scenario is close to the case of a trigger that fires every time a specific event occurs in the database, in order to maintain the data integrity. SmartErrand mechanism is specially designed to facilitate the PROGRESS applications to meet these requirements and to help developers create robust multi-window applications.

In brief the SmartErrand mechanism works as follows:

 
 
 
 

Structuring your project

Why it is so important to properly structure your project

When I came into the United States to work as a PROGRESS developer, a consulting company I worked with assigned me to a large PROGRESS GUI project. A major business-critical application for distribution business was already written just from scratch for a large enterprise. There were more than 3,000 .W  files and hundreds of .P and .I files in that system. Dozens and dozens of them were live with different kinds of bugs which the previous team of developers left as an ambush, to wait for the next shift of developers. That nasty flock of bugs buzzed around the face of the end users, because the system was already brought into production, and the users were irritated pretty much. Because of that situation my first and immediate task was debugging. I worked in St.Louis, MO and my superior would give me alot of printed screen where problems arose, and my mission was to find those bugs and kill them all. When I asked my superior how could I identify the program that produced any particular screen, I was told that it was completely up to me, and that was why the company paid a pretty high rate for me as a consultant. There were no any clues to the project structure as I always had in my own country, such as Project's Screens Diagram, or a program file name displayed on the title bar of the window, or a menu route, or any documentation with file names enlisted - completely nothing. I had only that hard copies of screens, and there were no opportunity to go directly to the users and see what happened there, because they were at different locations, hundred miles away from St.Louis. The only way to find screens in such a mess of a project was to go to the source code directory and use GREP utility or the like, trying to identify the screen by key words shown on the printed copy of the problem screen. That ridiculous digging in a common huge pile of a project, which appeared to be not structured at all, took us the most part of our precious time to find the right screen, while eliminating a bug itself took us much less time. For the first time I was astonished by that illiteral way of maintaining a project, especially when I was told that such a way is very common thing in the US. Eventually, the explanation came, and it was quite simple. As far as PROGRESS consultants are pretty expensive, the MIS superiors usually want them to produce as much code as they can make out during the day, and there is no time left for structuring, planning, establishing robust project standards and other necessary things. The management  usually tries to save as much money as possible, cutting down on everything that is not just coding. But then they have to pay ten times more to the consultants, trying to recover the snowballed project and pull it from the deep Hell back to the Earth. Well, it is obvious that business should save money, but business had better do it very literally and carefully, especially in such a specific area as IT, otherwise they might very easily face the situation when they saved $50,000 and then would have to pay $1,000,000 instead. And the above-mentioned type of a situation, when structuring of the project is neglected, is one of the most frequent and typical for the United States.  Many companies lose a huge amount of money because poor IT solutions impact their business very badly, and very often the ultimate reason is just underestimation by the management of regular work about the project like repository mainenance, producing deliverables, documentation set, flow-chart diagrams etc., in favor of just coding.  MasterMind toolset facilitates considerably this routine work of structuring and managing your project, saving alot of your precious time.
 
 The main ideas

Once upon a time, in my down time between two assignments (so that I had time to think abstract) I realized that, every module in that last project (that eventually snowballed and completely died) had a well-organized system of comments in its program files. There was alot of information in those comments. The tragedy was then, that after the number of programs grew numerously, those comments became useless, because they became almost unavailable, without a smart and flexible searching system. I understood that time that if only we could organize a well-structured search using just the information that contained in those comments, that would be of great help for the project, save our time dramatically, make our thinking process well-organized and contiguous and let us understand the logic of the main application more clearly and distinctively. Thus, I invented the most effective and the least time-consuming way to organize the information about a project. I thought: there should be a two-way road between specially structured comments in PROGRESS 4GL source code and project Repository, with mutual updates through special sort of interface. There should be enough to make an update only once, to spawn it into the whole system. A repository held in the relational database would give a six flex opportunity to structure an information and make various kind of searches with great ease. A bi-directional system of updates (between source code and the Repositary) should make the iterations, which are inevitable for every project, much less painful, because it would be much more easy to keep sources and the Repository in sync. And with this set of ideas, as well as the SmartErrand concept and some others taken as the basement, the MasterMind was built.
 

 How to structure your project written in ADE