Operations research

Component based interface to handle tasks during claim processing

7013284

Abstract

A computer program is provided for developing component based software capable of handling insurance-related tasks. The program includes a data component that stores, retrieves and manipulates data utilizing a plurality of functions. Also provided is a client component that includes an adapter component that transmits and receives data to/from the data component. The client component also includes a business component that serves as a data cache and includes logic for manipulating the data. A controller component is also included which is adapted to handle events generated by a user utilizing the business component to cache data and the adapter component to ultimately persist data to a data repository. In use, the client component is suitable for receiving a plurality of tasks that achieve an insurance-related goal upon completion, allowing users to add new tasks that achieve the goal upon completion, allowing the users to edit the tasks, and generating a historical record of the tasks that are completed.


Claims

What is claimed is:

1. A system for generating tasks to be performed in an insurance organization, the system comprising:

an insurance transaction database for storing information related to an insurance transaction, the insurance transaction database comprising a claim folder containing the information related to the insurance transaction decomposed into a plurality of levels from the group comprising a policy level, a claim level, a participant level and a line level, wherein the plurality of levels reflects a policy, the information related to the insurance transaction, claimants and an insured person in a structured format;

a task library database for storing rules for determining tasks to be completed upon an occurrence of an event;

a client component in communication with the insurance transaction database configured for providing information relating to the insurance transaction, said client component enabling access by an assigned claim handler to a plurality of tasks that achieve an insurance related goal upon completion; and

a server component in communication with the client component, the transaction database and the task library database, the server component including an event processor, a task engine and a task assistant;

wherein the event processor is triggered by application events associated with a change in the information, and sends an event trigger to the task engine; wherein in response to the event trigger, the task engine identifies rules in the task library database associated with the event and applies the information to the identified rules to determine the tasks to be completed, and populates on a task assistant the determined tasks to be completed, wherein the task assistant transmits the determined tasks to the client component.

2. The system of claim 1, further comprising a task library administrator interface for adding or editing rules and tasks in the task library.

3. The system of claim 2, wherein the task library includes a list of all standardized tasks.

4. The system of claim 3, wherein the tasks associated with the information relating to the insurance transaction include predetermined due dates.

5. The system of claim 4, wherein the task assistant generates a historical record to document completion of the tasks.

6. The system of claim 1, wherein the characteristics are regulatory compliance requirements, account servicing commitments and best practices for handling all types of claims.

7. The system of claim 1, wherein the information related to the insurance transaction is a claim under an insurance policy.

8. An automated method for generating tasks to be performed in an insurance organization, the method comprising:

transmitting information related to an insurance transaction;

determining characteristics of the information related to the insurance transaction;

applying the characteristics of the information related to the insurance transaction to rules to determine a task to be completed, wherein an event processor interacts with an insurance transaction database containing information related to an insurance transaction decomposed into a plurality of levels from the group comprising a policy level, a claim level, a participant level and a line level, wherein the plurality of levels reflects a policy, the information related to the insurance transaction, claimants and an insured person in a structured format;

transmitting the determined task to a task assistant accessible by an assigned claim handler, wherein said client component displays the determined task;

allowing an authorized user to edit and perform the determined task and to update the information related to the insurance transaction in accordance with the determined task;

storing the updated information related to the insurance transaction; and

generating a historical record of the completed task.

9. The method of claim 8, wherein the characteristics are regulatory compliance requirements, account servicing commitments and best practices for handling all types of claims.

10. The method of claim 8, wherein the information related to the insurance transaction is a claim under an insurance policy.

11. The method of claim 10, wherein the policy level further comprises information related to a covered automobile for automobile claims.

12. The method of claim 10, wherein the policy level further comprises information related to covered property for property claims.

13. The method of claim 10, wherein the policy level further comprises information related to covered yacht for marine claims.

14. The method of claim 8, wherein the claim level further comprises information from the group comprising facts of loss, events and liability.

15. The method of claim 8, wherein the participant level further comprises contact information.

16. The method of claim 15, wherein the participant level further comprises additional sections for claimants.

17. The method of claim 16, wherein the additional sections are shown to display, events, injury and disability management.

18. The method of claim 8, wherein the line level includes information related to details and damaged vehicle for automobile claims.

19. The method of claim 8, wherein the line level further comprises information related to damaged property for property claims.

20. The method of claim 8, wherein the line level further comprises information related to damaged yacht for marine claims.

21. The method of claim 8, wherein the line level further comprises information related to events, damages and negotiation.

22. The method of claim 8, further comprising a task library administrator interface for adding or editing the rules and tasks in the task library.


Description

FIELD OF THE INVENTION

The present invention relates to task management and more particularly to handling task during insurance claim processing utilizing a computer system.

BACKGROUND OF THE INVENTION

Computers have become a necessity in life today. They appear in nearly every office and household worldwide. A representative hardware environment is depicted in prior art FIG. 1, which illustrates a typical hardware configuration of a workstation having a central processing unit 110, such as a microprocessor, and a number of other units interconnected via a system bus 112. The workstation shown in FIG. 1 includes a Random Access Memory (RAM) 114, Read Only Memory (ROM) 116, an I/O adapter 118 for connecting peripheral devices such as disk storage units 120 to the bus 112, a user interface adapter 122 for connecting a keyboard 124, a mouse 126, a speaker 128, a microphone 132, and/or other user interface devices such as a touch screen (not shown) to the bus 112, communication adapter 134 for connecting the workstation to a communication network (e.g., a data processing network) and a display adapter 136 for connecting the bus 112 to a display device 138. The workstation typically has resident thereon an operating system such as the Microsoft Windows NT or Windows/95 Operating System (OS), the IBM OS/2 operating system, the MAC OS, or UNIX operating system.

Object oriented programming (OOP) has become increasingly used to develop complex applications. As OOP moves toward the mainstream of software design and development, various software solutions require adaptation to make use of the benefits of OOP. A need exists for these principles of OOP to be applied to a messaging interface of an electronic messaging system such that a set of OOP classes and objects for the messaging interface can be provided.

OOP is a process of developing computer software using objects, including the steps of analyzing the problem, designing the system, and constructing the program. An object is a software package that contains both data and a collection of related structures and procedures. Since it contains both data and a collection of structures and procedures, it can be visualized as a self-sufficient component that does not require other additional structures, procedures or data to perform its specific task. OOP, therefore, views a computer program as a collection of largely autonomous components, called objects, each of which is responsible for a specific task. This concept of packaging data, structures, and procedures together in one component or module is called encapsulation.

In general, OOP components are reusable software modules which present an interface that conforms to an object model and which are accessed at run-time through a component integration architecture. A component integration architecture is a set of architecture mechanisms which allow software modules in different process spaces to utilize each others capabilities or functions. This is generally done by assuming a common component object model on which to build the architecture. It is worthwhile to differentiate between an object and a class of objects at this point. An object is a single instance of the class of objects, which is often just called a class. A class of objects can be viewed as a blueprint, from which many objects can be formed.

OOP allows the programmer to create an object that is a part of another object. For example, the object representing a piston engine is said to have a composition-relationship with the object representing a piston. In reality, a piston engine comprises a piston, valves and many other components; the fact that a piston is an element of a piston engine can be logically and semantically represented in OOP by two objects.

OOP also allows creation of an object that "depends from" another object. If there are two objects, one representing a piston engine and the other representing a piston engine wherein the piston is made of ceramic, then the relationship between the two objects is not that of composition. A ceramic piston engine does not make up a piston engine. Rather it is merely one kind of piston engine that has one more limitation than the piston engine; its piston is made of ceramic. In this case, the object representing the ceramic piston engine is called a derived object, and it inherits all of the aspects of the object representing the piston engine and adds further limitation or detail to it. The object representing the ceramic piston engine "depends from" the object representing the piston engine. The relationship between these objects is called inheritance.

When the object or class representing the ceramic piston engine inherits all of the aspects of the objects representing the piston engine, it inherits the thermal characteristics of a standard piston defined in the piston engine class. However, the ceramic piston engine object overrides these ceramic specific thermal characteristics, which are typically different from those associated with a metal piston. It skips over the original and uses new functions related to ceramic pistons. Different kinds of piston engines have different characteristics, but may have the same underlying functions associated with it (e.g., how many pistons in the engine, ignition sequences, lubrication, etc.). To access each of these functions in any piston engine object, a programmer would call the same functions with the same names, but each type of piston engine may have different/overriding implementations of functions behind the same name. This ability to hide different implementations of a function behind the same name is called polymorphism and it greatly simplifies communication among objects.

With the concepts of composition-relationship, encapsulation, inheritance and polymorphism, an object can represent just about anything in the real world. In fact, the logical perception of the reality is the only limit on determining the kinds of things that can become objects in object-oriented software. Some typical categories are as follows:

    • Objects can represent physical objects, such as automobiles in a traffic-flow simulation, electrical components in a circuit-design program, countries in an economics model, or aircraft in an air-traffic-control system.
    • Objects can represent elements of the computer-user environment such as windows, menus or graphics objects.
    • An object can represent an inventory, such as a personnel file or a table of the latitudes and longitudes of cities.
    • An object can represent user-defined data types such as time, angles, and complex numbers, or points on the plane.


  • With this enormous capability of an object to represent just about any logically separable matters, OOP allows the software developer to design and implement a computer program that is a model of some aspects of reality, whether that reality is a physical entity, a process, a system, or a composition of matter. Since the object can represent anything, the software developer can create an object which can be used as a component in a larger software project in the future.

    If 90% of a new OOP software program consists of proven, existing components made from preexisting reusable objects, then only the remaining 10% of the new software project has to be written and tested from scratch. Since 90% already came from an inventory of extensively tested reusable objects, the potential domain from which an error could originate is 10% of the program. As a result, OOP enables software developers to build objects out of other, previously built objects.

    This process closely resembles complex machinery being built out of assemblies and sub-assemblies. OOP technology, therefore, makes software engineering more like hardware engineering in that software is built from existing components, which are available to the developer as objects. All this adds up to an improved quality of the software as well as an increased speed of its development.

    SUMMARY OF THE INVENTION

    A computer program is provided for developing component based software capable of handling insurance-related tasks. The program includes a data component that stores, retrieves and manipulates data utilizing a plurality of functions. Also provided is a client component that includes an adapter component that transmits and receives data to/from the data component. The client component also includes a business component that serves as a data cache and includes logic for manipulating the data. A controller component is also included which is adapted to handle events generated by a user utilizing the business component to cache data and the adapter component to ultimately persist data to a data repository. In use, the client component is suitable for receiving a plurality of tasks that achieve an insurance-related goal upon completion, allowing users to add new tasks that achieve the goal upon completion, allowing the users to edit the tasks, and generating a historical record of the tasks that are completed.

    DESCRIPTION OF THE DRAWINGS

    The foregoing and other objects, aspects and advantages are better understood from the following detailed description of a preferred embodiment of the invention with reference to the drawings, in which:

    Prior Art FIG. 1 is a schematic diagram of the present invention; and

    FIG. 2A is block diagram of one embodiment of the present invention.

    FIG. 2B is a flowchart showing how components generally operate in accordance with one embodiment of the present invention.

    FIG. 2C is a flowchart showing how the UI Controller operates in accordance with one embodiment of the present invention.

    FIG. 2D is a flowchart showing the interactions between the CCA, the CCI, and the Server Component in accordance with one embodiment of the present invention.

    FIG. 3 shows the life cycle of a typical User Interface and the standard methods that are part of the Window Processing Framework.

    FIG. 4 is an illustration showing how different languages are repainted and recompiled.

    FIG. 5 is a block diagram of an Architecture Object.

    FIG. 6 is an illustration showing the physical layout of CodeDecode tables according to one embodiment of the present invention.

    FIG. 7 is a logic diagram according to one embodiment of the present invention.

    FIG. 8 is a block diagram of the security framework and its components.

    FIG. 9 is an illustration showing the relationships between the security element and other elements.

    FIG. 10 is an illustration of the Negotiation component of one embodiment of the present invention;

    FIG. 11 is a flow diagram of the operations carried out by the Organization component of one embodiment of the present invention;

    FIG. 12 is an illustration of the Participant component of one embodiment of the present invention;

    FIG. 13 is a flow diagram of the operations carried out by the Task Assistant component of one embodiment of the present invention;

    FIG. 14 is an illustration of the Event Processor in combination with other components of the system in accordance with on embodiment of the present invention; and

    FIG. 15 is an illustration of the Task Engine in accordance with one embodiment of the present invention.

    DISCLOSURE OF THE INVENTION

    Programming languages are beginning to fully support the OOP principles, such as encapsulation, inheritance, polymorphism, and composition-relationship. With the advent of the C++ language, many commercial software developers have embraced OOP. C++ is an OOP language that offers a fast, machine-executable code. Furthermore, C++ is suitable for both commercial-application and systems-programming projects. For now, C++ appears to be the most popular choice among many OOP programmers, but there is a host of other OOP languages, such as Smalltalk, Common Lisp Object System (CLOS), and Eiffel. Additionally, OOP capabilities are being added to more traditional popular computer programming languages such as Pascal.

    The benefits of object classes can be summarized, as follows:
    • Objects and their corresponding classes break down complex programming problems into many smaller, simpler problems.
    • Encapsulation enforces data abstraction through the organization of data into small, independent objects that can communicate with each other. Encapsulation protects the data in an object from accidental damage, but allows other objects to interact with that data by calling the object's member functions and structures.
    • Subclassing and inheritance make it possible to extend and modify objects through deriving new kinds of objects from the standard classes available in the system. Thus, new capabilities are created without having to start from scratch.
    • Polymorphism and multiple inheritance make it possible for different programmers to mix and match characteristics of many different classes and create specialized objects that can still work with related objects in predictable ways.
    • Class hierarchies and containment hierarchies provide a flexible mechanism for modeling real-world objects and the relationships among them.
    • Libraries of reusable classes are useful in many situations, but they also have some limitations. For example:
    • Complexity. In a complex system, the class hierarchies for related classes can become extremely confusing, with many dozens or even hundreds of classes.
    • Flow of control. A program written with the aid of class libraries is still responsible for the flow of control (i.e., it must control the interactions among all the objects created from a particular library). The programmer has to decide which functions to call at what times for which kinds of objects.
    • Duplication of effort. Although class libraries allow programmers to use and reuse many small pieces of code, each programmer puts those pieces together in a different way. Two different programmers can use the same set of class libraries to write two programs that do exactly the same thing but whose internal structure (i.e., design) may be quite different, depending on hundreds of small decisions each programmer makes along the way. Inevitably, similar pieces of code end up doing similar things in slightly different ways and do not work as well together as they should.


  • Class libraries are very flexible. As programs grow more complex, more programmers are forced to reinvent basic solutions to basic problems over and over again. A relatively new extension of the class library concept is to have a framework of class libraries. This framework is more complex and consists of significant collections of collaborating classes that capture both the small scale patterns and major mechanisms that implement the common requirements and design in a specific application domain. They were first developed to free application programmers from the chores involved in displaying menus, windows, dialog boxes, and other standard user interface elements for personal computers.

    Frameworks also represent a change in the way programmers think about the interaction between the code they write and code written by others. In the early days of procedural programming, the programmer called libraries provided by the operating system to perform certain tasks, but basically the program executed down the page from start to finish, and the programmer was solely responsible for the flow of control. This was appropriate for printing out paychecks, calculating a mathematical table, or solving other problems with a program that executed in just one way.

    The development of graphical user interfaces began to turn this procedural programming arrangement inside out. These interfaces allow the user, rather than program logic, to drive the program and decide when certain actions should be performed. Today, most personal computer software accomplishes this by means of an event loop which monitors the mouse, keyboard, and other sources of external events and calls the appropriate parts of the programmer's code according to actions that the user performs. The programmer no longer determines the order in which events occur. Instead, a program is divided into separate pieces that are called at unpredictable times and in an unpredictable order. By relinquishing control in this way to users, the developer creates a program that is much easier to use. Nevertheless, individual pieces of the program written by the developer still call libraries provided by the operating system to accomplish certain tasks, and the programmer must still determine the flow of control within each piece after it's called by the event loop. Application code still "sits on top of" the system.

    Even event loop programs require programmers to write a lot of code that should not need to be written separately for every application. The concept of an application framework carries the event loop concept further. Instead of dealing with all the nuts and bolts of constructing basic menus, windows, and dialog boxes and then making these things all work together, programmers using application frameworks start with working application code and basic user interface elements in place. Subsequently, they build from there by replacing some of the generic capabilities of the framework with the specific capabilities of the intended application.

    Application frameworks reduce the total amount of code that a programmer has to write from scratch. However, because the framework is really a generic application that displays windows, supports copy and paste, and so on, the programmer can also relinquish control to a greater degree than event loop programs permit. The framework code takes care of almost all event handling and flow of control, and the programmer's code is called only when the framework needs it (e.g., to create or manipulate a proprietary data structure).

    A programmer writing a framework program not only relinquishes control to the user (as is also true for event loop programs), but also relinquishes the detailed flow of control within the program to the framework. This approach allows the creation of more complex systems that work together in interesting ways, as opposed to isolated programs, having custom code, being created over and over again for similar problems.

    Thus, as is explained above, a framework basically is a collection of cooperating classes that make up a reusable design solution for a given problem domain. It typically includes objects that provide default behavior (e.g., for menus and windows), and programmers use it by inheriting some of that default behavior and overriding other behavior so that the framework calls application code at the appropriate times.

    There are three main differences between frameworks and class libraries:
    • Behavior versus protocol. Class libraries are essentially collections of behaviors that you can call when you want those individual behaviors in your program. A framework, on the other hand, provides not only behavior but also the protocol or set of rules that govern the ways in which behaviors can be combined, including rules for what a programmer is supposed to provide versus what the framework provides.
    • Call versus override. With a class library, the code the programmer instantiates objects and calls their member functions. It's possible to instantiate and call objects in the same way with a framework (i.e., to treat the framework as a class library), but to take full advantage of a framework's reusable design, a programmer typically writes code that overrides and is called by the framework. The framework manages the flow of control among its objects. Writing a program involves dividing responsibilities among the various pieces of software that are called by the framework rather than specifying how the different pieces should work together.
    • Implementation versus design. With class libraries, programmers reuse only implementations, whereas with frameworks, they reuse design. A framework embodies the way a family of related programs or pieces of software work. It represents a generic design solution that can be adapted to a variety of specific problems in a given domain. For example, a single framework can embody the way a user interface works, even though two different user interfaces created with the same framework might solve quite different interface problems.


  • Thus, through the development of frameworks for solutions to various problems and programming tasks, significant reductions in the design and development effort for software can be achieved. A preferred embodiment of the invention utilizes HyperText Markup Language (HTML) to implement documents on the Internet together with a general-purpose secure communication protocol for a transport medium between the client and the Newco. HTTP or other protocols could be readily substituted for HTML without undue experimentation. Information on these products is available in T. Bemers-Lee, D. Connoly, "RFC 1866: Hypertext Markup Language-2.0" (November 1995); and R. Fielding, H, Frystyk, T. Berners-Lee, J. Gettys and J. C. Mogul, "Hypertext Transfer Protocol—HTTP/1.1: HTTP Working Group Internet Draft" (May 2, 1996). HTML is a simple data format used to create hypertext documents that are portable from one platform to another. HTML documents are SGML documents with generic semantics that are appropriate for representing information from a wide range of domains. HTML has been in use by the World-Wide Web global information initiative since 1990. HTML is an application of ISO Standard 8879; 1986 Information Processing Text and Office Systems; Standard Generalized Markup Language (SGML).

    To date, Web development tools have been limited in their ability to create dynamic Web applications which span from client to server and interoperate with existing computing resources. Until recently, HTML has been the dominant technology used in development of Web-based solutions. However, HTML has proven to be inadequate in the following areas:
    • Poor performance;
    • Restricted user interface capabilities;
    • Can only produce static Web pages;
    • Lack of interoperability with existing applications and data; and
    • Inability to scale.


  • Sun Microsystem's Java language solves many of the client-side problems by:
    • Improving performance on the client side;
    • Enabling the creation of dynamic, real-time Web applications; and
    • Providing the ability to create a wide variety of user interface components.


  • With Java, developers can create robust User Interface (UI) components. Custom "widgets" (e.g., real-time stock tickers, animated icons, etc.) can be created, and client-side performance is improved. Unlike HTML, Java supports the notion of client-side validation, offloading appropriate processing onto the client for improved performance. Dynamic, real-time Web pages can be created. Using the above-mentioned custom UI components, dynamic Web pages can also be created.

    Sun's Java language has emerged as an industry-recognized language for "programming the Internet." Sun defines Java as: "a simple, object-oriented, distributed, interpreted, robust, secure, architecture-neutral, portable, high-performance, multithreaded, dynamic, buzzword-compliant, general-purpose programming language. Java supports programming for the Internet in the form of platform-independent Java applets." Java applets are small, specialized applications that comply with Sun's Java Application Programming Interface (API) allowing developers to add "interactive content" to Web documents (e.g., simple animations, page adornments, basic games, etc.). Applets execute within a Java-compatible browser (e.g., Netscape Navigator) by copying code from the server to client. From a language standpoint, Java's core feature set is based on C++. Sun's Java literature states that Java is basically, "C++ with extensions from Objective C for more dynamic method resolution."

    Another technology that provides similar function to JAVA is provided by Microsoft and ActiveX Technologies, to give developers and Web designers wherewithal to build dynamic content for the Internet and personal computers. ActiveX includes tools for developing animation, 3-D virtual reality, video and other multimedia content. The tools use Internet standards, work on multiple platforms, and are being supported by over 100 companies. The group's building blocks are called ActiveX Controls, small, fast components that enable developers to embed parts of software in hypertext markup language (HTML) pages. ActiveX Controls work with a variety of programming languages including Microsoft Visual C++, Borland Delphi, Microsoft Visual Basic programming system and, in the future, Microsoft's development tool for Java, code named "Jakarta." ActiveX Technologies also includes ActiveX Server Framework, allowing developers to create server applications. One of ordinary skill in the art readily recognizes that ActiveX could be substituted for JAVA without undue experimentation to practice the invention.

    DETAILED DESCRIPTION

    One embodiment of the present invention is a server based framework utilizing component based architecture. Referring to FIG. 2A, one embodiment of the present invention includes an Architecture Object 200, an Application Object 202, a User Interface Form 204, a User Interface Controller 206, a Client Component Adapter 208, a COM Component Interface 210, and a Server Component 222.

    In general, the components of the present invention operate as shown in FIG. 2B. In step 230, data is stored in an object of the component. In step 232, functions which manipulate the object are encapsulated with the object data. Later, in step 234, the stored object data can be manipulated by other components utilizing the functions of step 232.

    Architecture Object

    The Architecture Object 200 provides an easy-to-use object model that masks the complexity of the architecture on the client. The Architecture Object 200 provides purely technical services and does not contain any business logic or functional code. It is used on the client as the single point of access to all architecture services.

    On the server side, the Architecture Object 200 is supplemented by a set of global functions contained in standard VB modules

    The Architecture Object 200 is responsible for providing all client architecture services (i.e., codes table access, error logging, etc.), and a single point of entry for architecture services. The Architecture Object 200 is also responsible for allowing the architecture to exist as an autonomous unit, thus allowing internal changes to be made to the architecture with minimal impact to application.

    The Architecture Object 200 provides a code manager, client profile, text manager, ID manager, registry manager, log manager, error manager, and a security manager. The codes manager reads codes from a local database on the client, marshals the codes into objects, and makes them available to the application. The client profile provides information about the current logged-in user. The text manager provides various text manipulation services such as search and replace. The ID manager generates unique IDs and timestamps. The registry manager encapsulates access to the system registry. The log manager writes error or informational messages to the message log. The error manager provides an easy way to save and re-raise an error. And the security manager determines whether or not the current user is authorized to perform certain actions.

    Application Object

    The Application Object 202 has a method to initiate each business operation in the application. It uses late binding to instantiate target UI controllers in order to provide autonomy between windows. This allows different controllers to use the Application Object 202 without statically linking to each and every UI controller in the application.

    When opening a UI controller, the Application Object 202 calls the architecture initialization, class initialization, and form initialization member functions.

    The Application Object 202 keeps a list of every active window, so that it can shut down the application in the event of an error. When a window closes, it tells the Application Object 202, and is removed from the Application Object's 202 list of active windows.

    The Application Object 202 is responsible for instantiating each UI Controller 206, passing data/business context to the target UI Controller 206, and invoking standard services such as initialize controller, initializing Form and Initialize Architecture. The Application Object 202 also keeps track of which windows are active so that it can coordinate the shutdown process.

    UI Form

    The UI form's 204 primary responsibility is to forward important events to its controller 206. It remains mostly unintelligent and contains as little logic as possible. Most event handlers on the form simply delegate the work by calling methods on the form's controller 206.

    The UI form 204 never enables or disables its own controls, but ask its controller 206 to do it instead. Logic is included on the UI form 204 only when it involves very simple field masking or minor visual details.

    The UI form 204 presents an easy-to-use, graphical interface to the user and informs its controller 206 of important user actions. The UI form 204 may also provide basic data validation (e.g., data type validation) through input masking. In addition, the UI form is responsible for intelligently resizing itself, launching context-sensitive help, and unload itself.

    User Interface Controller

    Every UI Controller 206 includes a set of standard methods for initialization, enabling and disabling controls on its UI form 204, validating data on the form, getting data from the UI form 204, and unloading the UI form 204.

    UI Controllers 206 contain the majority of logic to manipulate Business Objects 207 and manage the appearance of its UI form 204. If its form is not read-only, the UI Controller 206 also tracks whether or not data on the UI form 204 has changed, so as to avoid unnecessary database writes when the user decides to save. In addition, controllers of auxiliary windows (like the File-Save dialog box in Microsoft Word), keep track of their calling UI controller 206 so that they can notify it when they are ready to close.

    FIG. 2C is a flowchart showing how the UI Controller operates in one embodiment of the present invention. In step 236, data is entered in a UI form by a user. In step 238, the UI controller interprets the data entered into the UI form. In step 240, the UI controller places the appropriate data into a Business Object to be utilized and retrieved later.

    A UI Controller 206 defines a Logical Unit of Work (LUW). If an LUW involves more than one UI Controller 206, the LUW is implemented as a separate object.

    The UI Controller 206 is responsible for handling events generated by the user interacting with the UI form 204 and providing complex field validation and cross field validation within a Logical Unit of Work. The UI Controller 206 also contains the logic to interact with business objects 207, and creates new business objects 207 when necessary. Finally, the UI Controller 206 interacts with Client Component Adapters 208 to add, retrieve, modify, or delete business objects 207, and handles all client-side errors.

    Business Objects

    The Business Object's (BO) 207 primary functionality is to act as a data holder, allowing data to be shared across User Interface Controllers 206 using an object-based programming model.

    BOs 207 perform validation on their attributes as they are being set to maintain the integrity of the information they contain. BOs 207 also expose methods other than accessors to manipulate their data, such as methods to change the life cycle state of a BO 207 or to derive the value of a calculated attribute.

    In many cases, a BO 207 will have its own table in the database and its own window for viewing or editing operations.

    Business Objects 207 contain information about a single business entity and maintain the integrity of that information. The BO 207 encapsulates business rules that pertain to that single business entity and maintains relationships with other business objects (e.g., a claim contains a collection of supplements). Finally, the BO 207 provides additional properties relating to the status of the information it contains (such as whether that information has changed or not), provides validation of new data when necessary, and calculates attributes that are derived from other attributes (such as Full Name, which is derived from First Name, Middle Initial, and Last Name).

    Client Component Adapters

    Client Component Adapters (CCAs) 208 are responsible for retrieving, adding, updating, and deleting business objects in the database. CCAs 208 hide the storage format and location of data from the UI controller 206. The UI controller 206 does not care about where or how objects are stored, since this is taken care of by the CCA 208.

    The CCA 208 marshals data contained in recordsets returned by the server into business objects 207. CCAs 208 masks all remote requests from UI Controller 206 to a specific component, and act as a "hook" for services such as data compression, and data encryption.

    COM Component Interface

    A COM Component Interface (CCI) 210 is a "contract" for services provided by a component. By "implementing" an interface (CCI) 210, a component is promising to provide all the services defined by the CCI 20.

    The CCI 210 is not a physical entity (which is why it is depicted with a dotted line). It's only reason for existence is to define the way a component appears to other objects. It includes the signatures or headers of all the public properties or methods that a component will provide.

    To implement a CCI 210, a server component exposes a set of specially named methods, one for each method defined on the interface. These methods should do nothing except delegate the request to a private method on the component which will do the real work.

    The CCI 210 defines a set of related services provided by a component. The CCI allows any component to "hide" behind the interface to perform the services defined by the interface by "implementing" the interface.

    Server Component

    Server components 222 are course grained and transaction oriented. They are designed for maximum efficiency.

    Server Components 222 encapsulate all access to the database, and define business transaction boundaries. In addition, Server Components 222 are responsible for ensuring that business rules are honored during data access operations.

    A Server Component 222 performs data access operations on behalf of CCAs 208 or other components and participates in transactions spanning server components 222 by communicating with other server components 222. The Server Component 222 is accessible by multiple front end personalities (e.g., Active Server Pages), and contains business logic designed to maintain the integrity of data in the database.

    FIG. 2D is a flowchart showing the interactions between the CCA, the CCI, and the Server Component in accordance with one embodiment of the present invention. In step 242, a request is made to place client created data on the server database. In step 244, the data is transferred to the server component 222 utilizing a CCI 210. In step 246, the server component 222 stores the data in the server database.

    Business Rule Placement

    Overview

    The distribution of business rules across tiers of the application directly affects the robustness and performance of the system as a whole. Business rules can be categorized into the following sections: Relationships, Calculations, and Business Events.

    Relationships between Business Objects

    Business Objects 207 are responsible for knowing other business objects 207 with which they are associated.

    Relationships between BOs 207 are built by the CCA 208 during the marshaling process. For example, when a CCA 208 builds a claim BO 207, it will also build the collection of supplements if necessary.

    Calculated Business Data

    Business rules involving calculations based on business object 207 attributes are coded in the business objects 207 themselves. Participant Full Name is a good example of a calculated attribute. Rather than force the controllers to concatenate the first name, middle initial, and last name every time they wanted to display the full name, a calculated attribute that performs this logic is exposed on the business object. In this way, the code to compose the full name only has to be written once and can be used by many controllers 206.

    Another example of a calculated attribute is the display date of a repeating task. When a task with a repeat rule is completed, a new display date must be determined. This display date is calculated based on the date the task was completed, and the frequency of repetition defined by the repeat rule. Putting the logic to compute the new display date into the Task BO 207 ensures that it is coded only once.

    Responses to Business Events

    Business rules that relate to system events and involve no user interaction are enforced on the server components.

    Completion of a task is a major event in the system. When a task is completed, the system first ensures that the performer completing the task is added to the claim. Then, after the task is marked complete in the database, it is checked to see if the task has a repeat rule. If so, another task is created and added to the database. Finally, the event component is notified, because the Task Engine may need to react to the task completion.

    Consider the scenario if the logic to enforce this rule were placed on the UI controller 206.

    The controller 206 calls the Performer Component to see if the performer completing the task has been added to the claim. If the performer has not been added to the claim, then the controller 206 calls the performer component again to add them.

    Next, the controller 206 calls the Task Component to mark the task complete in the database. If the task has a repeat rule, the controller 206 computes the date the task is to be redisplayed and calls the Task Component again to add a new task. Lastly, the controller 206 calls the Event Component to notify the Task Engine of the task completion.

    The above implementation requires five network round trips in its worst case. In addition, any other controller 206 or server component 222 that wants to complete a task must code this logic all over again. Enforcing this rule in the task server component 222 reduces the number of network round trips and eliminates the need to code the logic more than once.

    Responses to User Events

    All responses to user events are coordinated by the controller 206. The controller 206 is responsible for actions such as enabling or disabling controls on its form, requesting authorization from the security component, or making calls to the CCA 208.

    Authorization

    All logic for granting authorization is encapsulated inside the security component. Controllers 206 and components 222 must ask the security component if the current user is authorized to execute certain business operations in the system. The security component will answer yes or no according to some predefined security logic.

    Summary
    Type of Business Rule Example Responsibility
    Maintaining relationships Claim keeps a collection Business Objects
    between BOs of supplements
    Building relationships CCA builds the claim's CCAs
    between BOs collection of supplements
    Calculated Business Data Participant calculates its Business Objects
    full name
    Responses to Business Task Component collab- Components
    Events orates with other
    components
    Requesting Authorization Task Library controller Controllers and
    asks the security compo- Components
    nent if the current user is
    allowed to access Task
    Library
    Granting Authorization Security component Security Component
    determines whether or
    not the current user can
    access Task Library


    Window Processing Framework

    The Default Window Framework provides default window processing for each window contained within the system. This default processing aides the developer in developing robust, maintainable UIs, standardizes common processes (such as form initialization) and facilitates smooth integration with architecture services.

    FIG. 3 shows the life cycle of a typical User Interface and the standard methods that are part of the Window Processing Framework 300.

    The Window Processing Framework 300 encompasses the following:
  • Window Initialization 302;
  • Window Save Processing 304;
  • Window Control State Management 306;
  • Window Data Validation 308;
  • Window Shutdown Processing 310.


  • Window Initialization Processing 302: After creating a controller 206 for the desired window, the App object 202 calls a set of standard initialization functions on the controller 206 before the form 204 is displayed to the user. Standardizing these functions makes the UIs more homogeneous throughout the application, while promoting good functional decomposition.

    Window Save Processing 304: Any time a user updates any form text or adds an item to a ListBox, the UI Controller 206 marks the form as "dirty". This allows the UI controller 206 to determine whether data has changed when the form closes and prompt the user to commit or lose their changes.

    Window Control State Management 306: Enabling and disabling controls and menu options is a very complex part of building a UI. The logic that modifies the state of controls is encapsulated in a single place for maintainability.

    Window Data Validation 308: Whenever data changes on a form, validation rules can be broken. The controller is able to detect those changes, validate the data, and prompt the user to correct invalid entries.

    Window Shutdown Processing 310: The Window Shutdown framework provides a clear termination path for each UI in the event of an error. This reduces the chance of memory leaks, and General Protection failures.

    Benefits

    Standardized Processing: Standardizing the window processing increases the homogeneity of the application. This ensures that all windows within the application behave in a consistent manner for the end users, making the application easier to use. It also shortens the learning curve for developers and increases maintainability, since all windows are coded in a consistent manner.

    Simplified Development: Developers can leverage the best practices documented in the window processing framework to make effective design and coding decisions. In addition, a shell provides some "canned" code that gives developers a head start during the coding effort.

    Layered Architecture: Because several architecture modules provide standardized processing to each application window, the core logic can be changed for every system window by simply making modifications to a single procedure.

    Window Initialization 302

    To open a new window, the App Object 202 creates the target window's controller 206 and calls a series of methods on the controller 206 to initialize it. The calling of these methods, ArchInitClass, InitClass, InitForm, and ShowForm, is illustrated below.

    ArchInitClass

    The main purpose of the ArchInitClass function is to tell the target controller 206 who is calling it. The App Object 202 "does the introductions" by passing the target controller 206 a reference to itself and a reference to the calling controller 206. In addition, it serves as a hook into the controller 206 for adding architecture functionality in the future.

    Public Sub ArchInitClass(objAPP As Object, objCallingCTLR As
    Object)
    ′ remember who called me
    Set m_objApp = objApp
    Set m_objCallingCTLR = objCallingCTLR
    End Sub

    InitClass

    This function provides a way for the App Object 202 to give the target controller 206 any data it needs to do its processing. It is at this point that the target controller 206 can determine what "mode" it is in. Typical form modes include, add mode, edit mode, and view mode. If the window is in add mode, it creates a new BO 207 of the appropriate type in this method.

    Public Sub InitClass(colPrevSelection As CArchCollection)
    If colprevSelection Is Nothing Then
    ′ no accounts were previously selected
    Set m_colPrevSelection = New CArchCollection
    Set m_colNewSelection = New CArchCollection
    Else
    ′ some accounts may have already been selected
    Set m_colPrevSelection = colprevSelection
    Set m_colNewSelection = colPrevSelection.Clone( )
    End If
    Set m_colResults = New CArchCollection
    DetermineFormMode( )
    End Sub

    InitForm

    The InitForm procedure of each controller 206 coordinates any initialization of the form 204 before it is displayed. Because initialization is often a multi-step process, InitForm creates the window and then delegates the majority of the initialization logic to helper methods that each have a single purpose, in order to follow the rules of good functional decomposition. For example, the logic to determine a form's 204 state based on user actions and relevant security restrictions and move to that state is encapsulated in the DetermineFormState method.

    Public Sub InitForm( )
    ′ create my form
    Set m_frmCurrentForm = New frmAccountSearch
    ′ figure out the state of my form based on arguments I
    received in InitClass and
    ′ enable/disable the appropriate controls
    DetermineFormState( )
    ′ fill my form with data
    PopulateForm( )
    End Sub

    PopulateForm

    PopulateForm is a private method responsible for filling the form with data during initialization. It is called exactly once by the InitForm method. PopulateForm is used to fill combo boxes on a form 204, get the details of an object for an editing window, or display objects that have already been selected by the user, as in the following example.

    Private Sub PopulateForm( )
    Dim acct As CAccount
    Dim item As GTListItem
    ′ display any accounts already selected by the user
    ′ create and add a ListItem for every Account in the
    previous selection collection
    With frmCurrentForm.lvwResults.ListItems
    .Clear
    For Each acct In m_colPrevSelection
    Set item = .Add(, acct.Number, acct.Number)
    item.SubItems(1) = acct.Name
    Next
    End With
    End Sub

    ShowForm

    The ShowForm method simply centers and displays the newly initialized form 204.

    Public Sub ShowForm( )
    ′ center my form
    frmCurrentForm.Move(Screen .Width - frmCurrentForm.Width) /
    2,
    (Screen.Height - frmCurrentForm.Height)
    / 2
    ′ display my form
    frmCurrentForm.Show vbModal
    End Sub


    Window Control State Management 306

    It is often necessary to enable or disable controls on a form 204 in response to user actions. This section describes the patterns employed by the Component Based Architecture for MTS (CBAM) to manage this process effectively.

    Form Mode

    It is helpful to distinguish between form mode and form state. Form mode indicates the reason the form 204 has been invoked. Often, forms 204 are used for more than one purpose. A common example is the use of the same form to view, add, and edit a particular type of object, such as a task or an insurance claim. In this case, the form's modes would include View, Add, and Update.

    The modes of a form 204 are also used to comply with security restrictions based on the current user's access level. For example, Task Library is a window that limits access to task templates based on the current user's role. It might have a Librarian mode and a Non-Librarian mode to reflect the fact that a non-librarian user cannot be allowed to edit task templates. In this way, modes help to enforce the requirement that certain controls on the form 204 remain disabled unless the user has a certain access level.

    It is not always necessary for a form 204 to have a mode; a form might be so simple that it would have only one mode—the default mode. In this case, even though it is not immediately necessary, it may be beneficial to make the form "mode-aware" so that it can be easily extended should the need arise.

    Form State

    A form 204 will have a number of different states for each mode, where a state is a unique combination of enabled/disabled, visible/invisible controls. When a form 204 moves to a different state, at least one control is enabled or disabled or modified in some way.

    A key difference between form mode and form state is that mode is determined when the controller 206 is initialized and remains constant until the controller 206 terminates. State is determined when the window initializes, but is constantly being reevaluated in response to user actions.

    Handling UI Events

    When the value of a control on the form 204 changes, it is necessary to reevaluate the state of the controls on the form (whether or not they are enabled/disabled or visible/invisible, etc.). If changing the value of one control could cause the state of a second control to change, an event handler is written for the appropriate event of the first control.

    The following table lists common controls and the events that are triggered when their value changes.

    Control Event
    TextBox Change
    ComboBox Change
    ListBox Click
    CheckBox Click
    Option Button Click


    The event handler calls the DetermineFormState method on the controller 206.

    Setting the State of Controls

    It is essential for maintainability that the process of setting the state of controls be separate from the process for setting the values of those controls. The DetermineFormState method on the controller 206 forces this separation between setting the state of controls and setting their values.

    DetermineFormState is the only method that modifies the state of any of the controls on the form 204. Because control state requirements are so complex and vary so widely, this is the only restriction made by the architecture framework.

    If necessary, parameters are passed to the DetermineFormState function to act as "hints" or "clues" for determining the new state of the form 204. For complex forms, it is helpful to decompose the DetermineFormState function into a number of helper functions, each handling a group of related controls on the form or moving the form 204 to a different state.

    Example

    The Edit/Add/View Task Window has three modes: Edit, Add, and View. In Add mode, everything on the form is editable. Some details will stay disabled when in Edit mode, since they should be set only once when the task is added. In both Add and Edit modes, the repeat rule may be edited. Enabling editing of the repeat rule always disables the manual editing of the task's due and display dates. In View mode, only the Category combo box and Private checkbox are enabled.

    ′ Edit/Add/View Task Form
    Private Sub txtName_Change( )
    myController.DetermineFormState
    End Sub
    ′ Edit/Add/View Task Controller
    Public Sub DetermineFormState( )
    On Error Goto ErrorHandler
    Select Case m_nFormMode
    ′ In Edit Mode, enable only "editable" details and
    Repeat Rule editing if necessary
    Case cmFormModeEdit
    EnableAddDetails False
    EnableEditDetails True
    EnableViewDetails True
    If m_frmCurrentForm.chkRepetetiveTask.Checked Then
    EnableEditRepeatRule True
    EnableEditDisplayDueDates False
    Else
    EnableEditRepeatRule False
    EnableEditDisplayDueDates True
    End If
    If m_nFormDirty Then EnableSave True Else
    EnableSave False
    ′ In Add Mode, enable all details and Repeat Rule
    editing if necessary
    Case cmFormModeAdd
    EnableAddDetails True
    EnableEditDetails True
    EnableViewDetails True
    If m_frmCurrentForm.chkRepetetiveTask.Checked Then
    EnableEditRepeatRule True
    EnableEditDisplayDueDates False
    Else
    EnableEditRepeatRule False
    EnableEditDisplayDueDates True
    End If
    If m_nFormDirty Then EnableSave True Else
    EnableSave False
    ′ In View Mode, disable everything except a few
    details
    Case cmFormModeView
    EnableAddDetails False
    EnableEditDetails False
    EnableViewDetails True
    EnableEditRepeatRule False
    EnableEditDisplayDueDates False
    EnableSave False
    Case Else
    End Select
    Exit Sub
    ErrorHandler:
    ′ error handling
    End Sub
    ′ Edit/Add/View Task Controller
    Private Sub EnableAddDetails(bYesNo As Boolean)
    On Error Goto ErrorHandler
    ′ Enable or disable controls that should be available only
    when the task is being added.
    With frmCurrentForm
    .Name.Enabled = bYesNo
    .Description.Enabled = bYesNo
    .Type.Enabled = bYesNo
    .Level.Enabled = bYesNo
    .Source.Enabled = bYesNo
    End With
    Exit Sub
    ErrorHandler:
    ′ error handling logic
    End Sub


    Window Data Validation 308

    Window data validation is the process by which data on the window is examined for errors, inconsistencies, and proper formatting. It is important, for the sake of consistency, to implement this process similarly or identically in all windows of the application.

    Types of Validation

    Input Masking

    Input masking is the first line of defense. It involves screening the data (usually character by character) as it is entered, to prevent the user from even entering invalid data. Input masking may be done programmatically or via a special masked text box, however the logic is always located on the form, and is invoked whenever a masked field changes.

    Single-field Range Checking

    Single-field range checking determines the validity of the value of one field on the form by comparing it with a set of valid values. Single-field range checking may be done via a combo box, spin button, or programmatically on the form, and is invoked whenever the range-checked field changes.

    Cross-field Validation

    Cross-field validation compares the values of two or more fields to determine if a validation rule is met or broken, and occurs just before saving (or searching). Cross-field validation may be done on the Controller 206 or the Business Object 207, however it is preferable to place the logic on the Business Object 207 when the validation logic can be shared by multiple Controllers 206.

    Invalid data is caught and rejected as early as possible during the input process. Input masking and range checking provide the first line of defense, followed by cross-field validation when the window saves (or searches).

    Single-field Validation

    All single-field validation is accomplished via some sort of input masking. Masks that are attached to textboxes are used to validate the type or format of data being entered. Combo boxes and spin buttons may also be used to limit the user to valid choices. If neither of these are sufficient, a small amount of logic may be placed on the form's event handler to perform the masking functionality, such as keeping a value below a certain threshold or keeping apostrophes out of a textbox.

    Cross-field Validation

    When the user clicks OK or Save, the form calls the IsFormData Valid on the controller to perform cross-field validation (e.g., verifying that a start date is less than an end date). If the business object 207 contains validation rules, the controller 206 may call a method on the business object 207 to make sure those rules are not violated.

    If invalid data is detected by the controller 206, it will notify the user with a message box and, if possible, the indicate which field or fields are in error. Under no circumstances will the window perform validation when the user is trying to cancel.

    Example

    ′ Generic Edit Form
    Private Sub cmdOK_Click( )
    On Error Goto ErrorHandler
    ′ shut down if my data is valid.
    ′ saving/canceling will occur in my controller's
    QueryUnload function
    If IsFormDataValid Then Unload Me
    Exit Sub
    ErrorHandler:
    Err.Raise Err.Number
    End Sub
    Public Function IsFormDataValid( ) As Boolean
    On Error Goto ErrorHandler
    ′ assume success
    IsFormDataValid = True
    ′ evaluate all validation rules
    With frmCurrentForm
    ′ make sure start date is earlier than end date
    If .txtStartDate.Text > .txtEndDate.Text Then
    IsFormDataValid = False
    MsgBox cmMsgInvalidEndDate
    .txtEndDate.SetFocus
    ElseIf ...
    ′ more validation rules
    End If
    End With
    Exit Function
    ErrorHandler:
    ′ error handling logic
    End Function


    Window Save Processing 304

    Window "Save Processing" involves tracking changes to data on a form 204 and responding to save and cancel events initiated by the user.

    Tracking Changes to Form Data

    Each window within the CBAM application contains a field within its corresponding control object known as the dirty flag. The dirty flag is set to True whenever an end user modifies data within the window. This field is interrogated by the UI Controller 206 to determine when a user should be prompted on Cancel or if a remote procedure should be invoked upon window close.

    The application shell provides standard processing for each window containing an OK or Save button.

    Saving

    The default Save processing is implemented within the UI Controller 206 as follows:

    The UI Controller is Notified that the OK button has been clicked. Then the controller 206 checks its Dirty Flag. If flag is dirty, the controller 206 calls the InterrogateForm method to retrieve data from the form 204 and calls a server component 222 to store the business object 207 in the database. If the Dirty Flag is not set, then no save is necessary. The window is then closed.

    Canceling

    When the user cancels a window, the UI Controller 206 immediately examines the Dirty Flag. If the flag is set to true, the user is prompted that their changes will be lost if they decide to close the window.

    Once prompted, the user can elect to continue to close the window and lose their changes or decide not to close and continue working.

    Window Shutdown Processing 310

    In the event of an error, it is sometimes necessary to shutdown a window or to terminate the entire application. It is critical that all windows follow the shutdown process in order to avoid the GPFs commonly associated with terminating incorrectly. Following is how the window/application is shutdown.

    Shutdown Scope

    The scope of the shutdown is as small as possible. If an error occurs in a controller 206 that does not affect the rest of the application, only that window is shut down. If an error occurs that threatens the entire application, there is a way to quickly close every open window in the application. The window shutdown strategy is able to accommodate both types of shutdowns.

    Shutdown

    In order to know what windows must be shut down, the architecture tracks which windows are open. Whenever the App Object 202 creates a controller 206, it calls its RegCTLR function to add the controller 206 to a collection of open controllers. Likewise, whenever a window closes, it tells the App Object 202 that it is closing by calling the App Object's 202 UnRegCTLR function, and the App Object 202 removes the closing controller 206 from its collection. In the case of an error, the App Object 202 loops through its collection of open controllers, telling each controller to "quiesce" or shutdown immediately.

    GeneralErrorHandler

    The GeneralErrorHandler is a method in MArch.bas that acts as the point of entry into the architecture's error handling mechanism. A component or a controller will call the GeneralErrorHandler when they encounter any type of unexpected or unknown error. The general error handler will return a value indicating what the component or controller should do: (1) resume on the line that triggered the error (2) resume on the statement after the line that triggered the error (3) exit the function (4) quiesce (5) shutdown the entire application.

    ErrorHandler:
    Select Case CStr(Err.Number)
    ′ handle a search with no result error
    Case cmErrNoClaimTreeData
    MsgBox cmMsgNoResultsQuery, vbInformation
    frmCurrentForm.StatusBar.Panels(1) =
    cmNoResultsQuery
    ′Sets mouse pointer back to default
    frmCurrentForm.MousePointer = vbDefault
    Case Else
    Dim nResumeCode As Integer
    nResumeCode =
    GeneralErrorHandler(objApp.objArch.AsMsgStruct, cmController,
    cmClassName,
    cmMethodName)
    Select Case CStr(nResumeCode)
    Case cmErrorResume
    Resume
    Case cmErrorResumeNext
    Resume Next
    Case cmErrorExit
    Exit Sub
    Case cmErrorQuiesce
    Quiesce
    Case Else
    objApp.Shutdown
    End Select
    End Select
    End Sub


    In order to prevent recursive calls the GeneralErrorHandler keeps a collection of controllers that are in the process of shutting down. If it is called twice in a row by the same controller 206, it is able to detect and short-circuit the loop. When the controller 206 finally does terminate, it calls the UnRegisterError function to let the GeneralErrorHandler know that it has shut down and removed from the collection of controllers.

    Shutdown Process

    After being told what to do by the GeneralErrorHandler, the controller 206 in error may try to execute the statement that caused the error, proceed as if nothing happened, exit the current function, call its Quiesce function to shut itself down, or call the Shutdown method on the App Object 202 to shut the entire application down.

    Additional Standard Methods

    Searching

    Controllers 206 that manage search windows have a public method named Find<Noun>s where <Noun> is the type of object being searched for. This method is called in the event handler for the Find Now button.

    Saving

    Any controller 206 that manages an edit window has a public method called Save that saves changes the user makes to the data on the form 204. This method is called by the event handlers for both the Save and OK buttons (when/if the OK button needs to save changes before closing).

    Closing

    A VB window is closed by the user in several ways: via the control-box in upper left corner, the X button in upper right corner, or the Close button. When the form closes, the only method that will always be called, regardless of the way in which the close was initiated, is the form's 204 QueryUnload event handler.

    Because of this, there cannot be a standard Close method. Any processing that must occur when a window closes is to be done in the QueryUnload method on the controller 206 (which is called by the form's QueryUnload event handler).

    The VB statement, Unload Me, appears in the Close button's event handler to manually initiate the unloading process. In this way, the Close button mimics the functionality of the control box and the X button, so that the closing process is handled the same way every time, regardless of how the user triggered the close. The OK button's event handler also executes the Unload Me statement, but calls the Save method on the controller first to save any pending changes.

    Business Objects

    Business Objects 207 are responsible for containing data, maintaining the integrity of that data, and exposing functions that make the data easy to manipulate. Whenever logic pertains to a single BO 207 it is a candidate to be placed on that BO. This ensures that it will not be coded once for each controller 206 that needs it. Following are some standard examples of business object logic.

    Business Logic: Managing Life Cycle State

    Overview

    The "state" of a business object 207 is the set of all its attributes. Life cycle state refers only to a single attribute (or a small group of attributes) that determine where the BO 207 is in its life cycle. For example, the life cycle states of a Task are Open, Completed, Cleared, or Error. Business objectives usually involve moving a BO toward its final state (i.e., Completed for a Task, Closed for a Supplement, etc.).

    Often, there are restrictions on a BO's movement through its life cycle. For example, a Task may only move to the Error state after first being Completed or Cleared. BOs provide a mechanism to ensure that they do not violate life cycle restrictions when they move from state to state.

    Approach

    A BO 207 has a method to move to each one of its different life cycle states. Rather than simply exposing a public variable containing the life cycle state of the task, the BO exposes methods, such as Task.Clear( ), Task.Complete( ), and Task.MarkInError( ), that move the task a new state. This approach prevents the task from containing an invalid value for life cycle state, and makes it obvious what the life cycle states of a task are.

    Example

    ′ CTask Business Object
    Public Sub MarkInError( )
    On Error Goto ErrorHandler
    Select Case m_nLifeCycleState
    ′ move to error only if I've already been completed or
    cleared
    Case cmTaskCompleted, cmTaskCleared
    m_nLifeCycleState = cmTaskInError
    ′ otherwise, raise an error
    Case Else
    Err.Raise cmErrInvalidLifeCycleState
    End Select
    Exit Sub
    ErrorHandler:
    Err.Raise Err.Number
    End Sub


    Business Logic: Operating on Groups of Business Objects

    Overview

    Sometimes, a BO 207 acts as a container for a group of other BOs. This happens when performing operations involving multiple BOs. For example, to close, an insurance claim ensures that it has no open supplements or tasks. There might be a method on the insurance claim BO—CanClose( )—that evaluates the business rules restricting the closing of a claim and return true or false. Another situation might involve retrieving the open tasks for a claim. The claim can loop through its collection of tasks, asking each task if it is open and, if so, adding it to a temporary collection which is returned to the caller.

    Example

    ′ Claim Business Object
    ′ Error handling omitted for clarity
    Public Function CanClose( ) As Boolean
    CanClose = HasOpenTasks( ) And HasOpenSupplements( )
    End Function
    Public Function HasOpenTasks( ) As Boolean
    ′ assume that I have open tasks
    HasOpenTasks = True
    ′ loop through all my tasks and exit if I find one that is
    open
    Dim task As CTask
    For Each task In m_colTasks
    If task.IsOpen( ) Then Exit Function
    Next task
    ′ I must not have any open tasks
    HasOpenTasks = False
    End Function
    Public Function HasOpenSupplements( ) As Boolean
    ′ assume that I have open supplements
    HasOpenSupplements = True
    ′ loop through all my supplements and exit if I find one
    that is open
    Dim supp As CSupplement
    For Each supp In m_colSupplements
    If supp.IsOpen( ) Then Exit Function
    Next supp
    HasOpenSupplements = False
    End Function
    Public Function GetOpenTasks( ) As Collection
    Dim task As CTask
    Dim colOpenTasks As Collection
    For Each task In m_colTasks
    If task.IsOpen( ) Then colOpenTasks.Add task, task.Id
    Next task
    Set GetOpenTasks = colOpenTasks
    End Function


    Business Object Structures

    Overview

    When a BO 207 is added or updated, it sends all of its attributes down to a server component 222 to write to the database. Instead of explicitly referring to each attribute in the parameter list of the functions on the CCA 208 and server component 222, all the attributes are sent in a single variant array. This array is also known as a structure.

    Approach

    Each editable BO 207 has a method named AsStruct that takes the object's member variables and puts them in a variant array. The CCA 208 calls this method on a BO 207 before it sends the BO 207 down to the server component 222 to be added or updated. The reason that this is necessary is that, although object references can be passed by value over the network, the objects themselves cannot. Only basic data types like Integer and String can be sent by value to a server component 222. A VB enumeration is used to name the slots of the structure, so that the server component 222 can use a symbolic name to access elements in the array instead of an index. Note that this is generally used only when performing adds or full updates on a business object 207.

    In a few cases, there is a reason to re-instantiate the BO 207 on the server side. The FromStruct method does exactly the opposite of the AsStruct method and initializes the BO 207 from a variant array. The size of the structure passed as a parameter to FromStruct is checked to increase the certainty that it is a valid structure.

    When a BO 207 contains a reference to another BO 207, the AsStruct method stores the primary key of the referenced BO 207. For example, the Task structure contains a PerformerId, not the performer BO 207 that is referenced by the task. When the FromStruct method encounters the PerformerId in the task structure, it instantiates a new performer BO and fills in the ID, leaving the rest of the performer BO empty.

    Example

    ′ CTask Business Object
    ′ enumeration of all task attributes
    Public Enum TaskAttributes
    cmTaskId
    cmTaskName
    :
    cmTaskDescription
    End Enum
    ′ all task attributes declarations here
    ′ all setter and getter functions here
    Public Function AsStruct( ) As CTask
    On Error Goto ErrorHandler
    ′ create and fill structure
    Dim vStruct(cmTaskNumOfAttributes - 1) As Variant
    vStruct(cmTaskId) = m_vId
    vStruct(cmTaskName) = m_sName
    vStruct(cmTaskPerformerId) = m_vPerformerId
    :
    vStruct(cmTaskDescription) = m_sDescription
    AsStruct = vStruct
    Exit Function
    ErrorHandler:
    Err.Raise Err.Number
    End Function
    Public Sub FromStruct(vStruct As Variant)
    On Error Goto ErrorHandler
    ′ check size of vStruct
    If Ubound(vStruct) <> (cmTaskNumOfAttributes - 1) Then
    Err.Raise cmErrInvalidParameters
    ′ update my values from the structure
    m_vId = vStruct(cmTaskId)
    m_sName = vStruct(cmTaskName)
    m_vPerformer.Id = vStruct(cmTaskPerformerId)
    :
    m_sDescription = vStruct(cmTaskDescription)
    Exit Sub
    ErrorHandler:
    Err.Raise Err.Number
    End Sub


    Cloning Business Objects

    Overview

    Often a copy of a business object 207 is made. Cloning is a way to implement this kind of functionality by encapsulating the copying process in the BO 207 itself. Controllers 206 that need to make tentative changes to a business object 207 simply ask the original BO 207 for a clone and make changes to the clone. If the user decides to save the changes, the controller 206 ask the original BO to update itself from the changes made to the clone.

    Approach

    Each BO 207 has a Clone method to return a shallow copy of itself. A shallow copy is a copy that doesn't include copies of the other objects that the BO 207 refers to, but only a copy of a reference to those objects. For example, to clone a task, it does not give the clone a brand new claim object; it gives the clone a new reference to the existing claim object. Collections are the only exception to this rule—they are always copied completely since they contain references to other BOs.

    Each BO 207 also has an UpdateFromClone method to allow it "merge" a clone back in to itself by changing its attributes to match the changes made to the clone.

    Example

    ′ CTask Business Object
    Public Function Clone( ) As CTask
    On Error Goto ErrorHandler
    ′ create clone object
    Dim tskClone As CTask
    Set tskClone = New CTask
    ′ fill clone with my data
    With tskClone
    .Id = m_vId
    .Name = m_sName
    .PerformerId = m_vPerformerId
    Set .Performer = m_prfPerformer
    :
    .Description = m_sDescription
    End With
    Set Clone = tskClone
    Exit Function
    ErrorHandler:
    Err.Raise Err.Number
    End Function
    Public Sub UpdateFromClone(tskClone As CTask)
    On Error Goto ErrorHandler
    ′ set my values equal to the clone's values
    With tskClone
    m_vId = .ID
    m_sName = .Name
    m_vPerformerId = .PerformerId
    Set m_prfPerformer = .Performer
    :
    m_sDescription = .Description
    End With
    Exit Sub
    ErrorHandler:
    Err.Raise Err.Number
    End Sub


    Half-baked Business Objects

    Overview

    BOs 207 occasionally are filled only half-full for performance reasons. This is done for queries involving multiple tables that return large data sets. Using half-baked BOs 207 can be an error prone process, so it is essential that the half-baking of BOs are carefully managed and contained.

    In most applications, there are two kinds of windows—search windows and edit/detail windows. Search windows are the only windows that half-bake BOs 207. Generally, half-baking only is a problem when a detail window expecting a fully-baked BO receives a half-baked BO from a search window.

    Approach

    Detail windows refresh the BOs 207 they are passed by the search windows, regardless of whether or not they were already fully-baked. This addresses the problems associated with passing half-baked BOs and also helps ensure that the BO 207 is up-to-date.

    This approach requires another type of method (besides Get, Add, Update, and Delete) on the CCA 208: a Refresh method. This method is very similar to a Get method (in fact, it calls the same method on the server component) but is unique because it refreshes the data in objects that are already created. The detail window's controller 206 calls the appropriate CCA 208 passing the BO 207 to be refreshed, and may assume that, when control returns from the CCA 208, the BO 207 will be up-to-date and fully-baked.

    This is may not be necessary if two windows are very closely related. If the first window is the only window that ever opens the second, it is necessary for the second window to refresh the BO 207 passed by the first window if it knows that the BO 207 is baked fully enough to be used.

    CCAs

    CCAs 208 are responsible for transforming data from row and columns in a recordset to business objects 207, and for executing calls to server components 222 on behalf of controllers 206.

    Retrieving Business Objects

    Overview

    After asking a component to retrieve data, the CCA 208 marshals the data returned by the component into business objects 207 that are used by the UI Controller 206.

    Approach

    The marshaling process is as follows:

    CCAs 208 call GetRows on the recordset to get a copy of its data in a variant array in order to release the recordset as soon as possible. A method exist to coordinate the marshaling of each recordset returned by the component.

    Only one recordset is coordinated in the marshaling process of a single method. A method exist to build a BO from a single row of a recordset. This method is called once for each row in the recordset by the marshaling coordination method.

    Example

    ′ Task CCA
    Public Function GetAllTasks( ) As Collection
    On Error Goto ErrorHandler
    ′ call a helper method to retrieve tasks
    Dim vRows As Variant
    vRows = RetrieveAllTasks
    Dim i As Integer
    Dim task As CTask
    Dim colTasks As Collection
    Set colTasks = New Collection
    ′ vRows is dimmed as column, row. Loop til I run out of
    rows.
    For i = 0 To Ubound(vRows, 2)
    ′ build BO using helper method
    Set task = BuildTaskFromRow(vRows, i)
    ′ add to collection with ID as the key
    colTasks.Add task, task.Id
    Next i
    Set MarshalTasks = colTasks
    Exit Function
    ErrorHandler:
    Err.Raise Err.Number
    End Function
    Private Function RetrieveAllTasks( ) As Variant
    On Error Goto ErrorHandler
    ′ call my component and get a recordset full of all tasks
    Dim rs As ADOR.Recordset
    Set rs = tskComp.GetAllTasks( )
    ′ get data in variant array from the recordset
    GetAllTasks = rs.GetRows
    ′ release the recordset ASAP
    rs.Close
    Set rs = Nothing
    Exit Function
    ErrorHandler:
    Err.Raise Err.Number
    End Function
    Private Function BuildTaskFromRow(vRows As Variant,
    nCurrentRow As Integer,
    Optional task As CTask) As
    CTask
    On Error Goto ErrorHandler
    ′ create task if it wasn't passed
    If task Is Nothing Then Set task = New CTask
    ′ fill task with data
    With task
    .Id = vRows(0, nCurrentRow)
    .Name = vRows(1, nCurrentRow)
    .PerformerId = vRows(2, nCurrentRow)
    :
    .Description = vRows(32, nCurrentRow)
    End With
    Set BuildTaskFromRow = task
    Exit Function
    ErrorHandler:
    Err.Raise Err.Number
    End Function


    Refreshing Business Objects

    Overview

    The logic to refresh BOs 207 is very similar to the logic to create them in the first place. A "refresh" method is very similar to a "get" method, but must use BOs 207 that already exist when carrying out the marshalling process.

    Example

    ′ Task CCA
    Public Sub RefreshTask(task As CTask)
    On Error Goto ErrorHandler
    ′ call a helper method to retrieve tasks
    Dim vRow As Variant
    vRow = RetrieveTaskWithId(task.Id)
    BuildTaskFromRow vRow, i, task
    Exit Sub
    ErrorHandler:
    Err.Raise Err.Number
    End Sub
    Private Function RetrieveTaskWithId(vId As Variant) As Variant
    On Error Goto ErrorHandler
    ′ call my component and get a recordset full of all tasks
    Dim rs As ADOR.Recordset
    Set rs = tskComp.GetTaskWithId(vId)
    ′ get data in variant array from the recordset
    RetrieveTaskWithId = rs.GetRows
    ′ release the recordset ASAP
    rs.Close
    Set rs = Nothing
    Exit Function
    ErrorHandler:
    Err.Raise Err.Number
    End Function


    Adding Business Objects

    Overview

    Controllers 206 are responsible for creating and populating new BOs 207. To add a BO 207 to the database, the controller 206 must call the CCA 208, passing the business object 207 to be added. The CCA 208 calls the AsStruct method on the BO 207, and pass the BO structure down to the component to be saved. It then updates the BO 207 with the ID and timestamp generated by the server. Note the method on the CCA 208 just updates the BO 207.

    Example

    ′ Task CCA
    Public Sub AddTask (task As CTask)
    On Error Goto ErrorHandler
    ′ call component to add task passing a task structure
    Dim vIdAndTimestamp As Variant
    vIdAndTimestamp = tskComp.AddTask (task.AsStruct())
    ′ update ID and Timestamp on task
    task.Id = vIdAndTimestamp (0)
    task.TimeStamp = vIdAndTimestamp (1)
    Exit Sub
    ErrorHandler:
    Err.Raise Err.Number
    End Sub


    Updating Business Objects

    Overview

    The update process is very similar to the add process. The only difference is that the server component only returns a timestamp, since the BO already has an ID.

    Example

    ′ Task CCA
    Public Sub UpdateTask(task As CTask)
    On Error Goto ErrorHandler
    ′ call component to update task passing a task structure
    Dim lTimeStamp As Long
    lTimeStamp = tskComp.AddTask(task.AsStruct( ))
    ′ update Timestamp on task
    task.TimeStamp = lTimeStamp
    Exit Sub
    ErrorHandler:
    Err.Raise Err.Number
    End Sub


    Deleting Business Objects

    Deleting Overview

    Like the add and the update methods, delete methods take a business object 207 as a parameter and do not have a return value. The delete method does not modify the object 207 it is deleting since that object will soon be discarded.

    Example

    ′ Task CCA
    Public Sub DeleteTask(task As CTask)
    On Error Goto ErrorHandler
    ′ call component to update task passing a the ID and
    Timestamp
    tskComp.DeleteTask task.Id, task.TimeStamp
    Exit Sub
    ErrorHandler:
    Err.Raise Err.Number
    End Sub


    Server Component

    Server components 222 have two purposes: enforcing business rules and carrying out data access operations. They are designed to avoid duplicating logic between functions.

    Designing for Reuse

    Enforcing Encapsulation

    Each server component 222 encapsulates a single database table or a set of closely related database tables. As much as possible, server components 222 select or modify data from a single table. A component occasionally selects from a table that is "owned" or encapsulated by another component in order to use a join (for efficiency reasons). A server component 222 often collaborates with other server components to complete a business transaction.

    Partioning Logic between Multiple Classes

    If the component becomes very large, it is split into more than one class. When this occurs, it is divided into two classes—one for business rules and one for data access. The business rules class implements the component's interface and utilizes the data access class to modify data as needed.

    Example

    Private Function MarkTaskInError(vMsg As Variant,
    vTaskId As Variant,
    lTimestamp As Variant,
    sReason As String) As Long
    On Error GoTo ErrorHandler
    Const cmMethodName = "MarkTaskInError"
    ′ set the SQL statement
    Dim sSQL As String
    sSQL = cmSQLMarkTaskInError
    ′ get a new timestamp
    Dim lNewTimeStamp As Long
    lNewTimeStamp = GetTimeStamp( )
    ′ create and fill a collection of arguments to be merged
    with
    ′ the SQL by the ExecuteQuery method
    Dim colArgs As CCollection
    Set colArgs = New CCollection
    With colArgs
    Add lNewTimeStamp
    Add cmDBBooleanTrue
    .Add sReason
    .Add vTaskId
    .Add lTimestamp
    End With
    ′ run the SQL and set my return value
    ExecuteQuery vMsg, cmUpdate, sSQL, colArguments:=colArgs
    MarkTaskInError = lNewTimeStamp
    ′ tell MTS I'm done
    GetObjectContext.SetComplete
    Exit Function
    ErrorHandler:
    ′ do error handling here
    End Function


    Error Handling

    General Information

    With the exception of "Class_Initialize", "Class_Terminate", and methods called within an error handler, every function or subroutine has a user defined 'On Error GoTo' statement. The first line in each procedure is: On Error GoTo ErrorHandler. A line near the end of the procedure is given a label "ErrorHandler". (Note that because line labels in VB 5.0 have procedure scope, each procedure can have a line labeled "ErrorHandler"). The ErrorHandler label is preceded by a Exit Sub or Exit Function statement to avoid executing the error handling code when there is no error.

    Errors are handled differently based on the module's level within the application (i.e., user interface modules are responsible for displaying error messages to the user).

    All modules take advantage of technical architecture to log messages. Client modules that already have a reference to the architecture call the Log Manager object directly. Because server modules do not usually have a reference to the architecture, they use the LogMessage( ) global function complied into each server component.

    Any errors that are raised within a server component 222 are handled by the calling UI controller 206. This ensures that the user is appropriately notified of the error and that business errors are not translated to unhandled fatal errors.

    All unexpected errors are handled by a general error handler function at the global Architecture module in order to always gracefully shut-down the application.

    Server Component Errors

    The error handler for each service module contains a Case statement to check for all anticipated errors. If the error is not a recoverable error, the logic to handle it is first tell MTS about the error by calling GetObjectContext.SetAbort( ). Next, the global LogMessage( ) function is called to log the short description intended for level one support personnel. Then the LogMessage( ) function is called a second time to log the detailed description of the error for upper level support personnel. Finally, the error is re-raised, so that the calling function will know the operation failed.

    A default Case condition is coded to handle any unexpected errors. This logs the VB generated error then raises it. A code sample is provided below:

    Following is an example of how error handling in the task component is implemented when an attempt is made to reassign a task to a performer that doesn't exist. Executing SQL to reassign a task to a non-existent performer generates a referential integrity violation error, which is trapped in this error handler:

    ′Class Declarations
    Private Const cmClassName = "CTaskComp"
    Public Sub ReassignTask(...)
    On Error GoTo ErrorHandler
    Private Const cmMethodName = "ReassignTask"
    Private Const cmErrReassignTask = "Could not reassign
    task."
    :
    ′ logic to reassign a task
    :
    GetObjectContext.SetComplete
    Exit Sub
    ErrorHandler:
    Dim sShortDescr As String
    sShortDescr = cmErrReassignTask
    ′ log short description as warning
    LogMessage vMsg, Err.Nurnber, cmSeverityWarning,