| Return to Kinexis Home Page |
|
|
| Intermediary
Objects for Transactional Systems: Introducing "Proposals"
by John Tibbetts and Barbara Bernstein Object Magazine, November 1997
With Proposals as mediators between front-end consumers and back-end domain objects, the possibilities for reuse improve dramatically
|
| Of
the many benefits of an object approach, probably none has been more attractive
to developers of commercial applications than reuse. Clearly, the more
code that can be recycled, the more development time can be saved, the
more risks avoided, and the more efficient the whole application-writing
process becomes.
Object insights have made significant inroads into the world of commercial applications in the last 5 or 7 years, often with very beneficial results. And yet, we have been puzzled to observe that the record on reuse has been spotty at best. The massive, end-to-end automation of business application development that we expected has not materialized. Where’s The Reuse? There is reasonable reuse of domain objects
in the back and of UI gadgets at the front. Yet at the heart of the development
job, at that stage devoted to creating the so-called application itself,
reusable objects are virtually non-existent. These application middles
are written as they always have been—on a case-by-case basis, almost entirely
from scratch. Even a commonplace activity like relating master records
to their detail records gets programmed anew for every new application.
No wonder these middle regions have resisted
abstraction and re-use. Object modeling done here has missed the mark because
it has tried to model a misconception, or at least a serious imprecision.We
introduce here a more promising way of thinking in object terms about the
central portions of transactional applications, and discuss our experiences
in implementing an architecture based on this insight.
Object technology teaches the importance of
accurate names that reflect clearly-delimited responsibilities, and this
is what we have come up with: The application middle is the region
where proposed changes to enterprise resources are assembled. It is
where transactional requests take shape, in a tentative and provisional
form, before they are finally submitted to the back-end database manager
or TP monitor.
Proposals opens up a space between UI and database manager where reusable infrastructure, generic navigational intelligence, and flexible interfaces to both back and front can live. Proposal Objects vs. Domain Objects In the human world, a proposal—to buy a house,
get married, do a certain job for a certain fee—is a necessary step between
mulling something over and signing an iron-clad contract. Proposals
are how deals gets shaped. They tend to be tentative, negotiable, and probably
not perfect right off the bat. They may go through multiple versions.
And every proposal eventually reaches a point where it either turns into
a contract or is abandoned.
Proposals revolutionize both the building and
the use of transactional applications. On the building side, they provide
developers with a great deal of reusable infrastructure. Much of
the code that now has to be done from scratch for every new type of application
comes built in to the Proposal framework, ready to be picked up and used.
Where Does a Proposal Live? Proposals are not tied to any specific platform,
tier, or machine. They move freely; in fact, they can change location on
a moment-to-moment basis. Proposals add a mobile element to systems
where every other process is fixed in place. The front end has to be near
the user, the back end has to be near the data, but a Proposal can be placed
sometimes close to the front, sometimes close to the back, or anywhere
in between.
To accomplish its job, a Proposal object must assume responsibility for keeping its own metadata and data, and for many navigational, organizational, and interfacing chores. We have come up with the following:
2. Acting as a container for proposal data 3. Keeping versions of itself 4. Retaining and tracking errors 5. Holding annotations 6. Protecting against stale data 7. Interacting with the back-end server 8. Interacting with consumers 1. Know Its Own SpecificationThe first responsibility of a Proposal is to hold developer-supplied metadata that makes it a NewHire Proposal, a ShipProduct Proposal, a DebitAccount Proposal, or whatever.Metadata resides in what we call the PropSpec (short for Proposal Specification), the developer-customized template for a specific Proposal type (there is a NewHire PropSpec, a ShipProduct PropSpec, etc.). The PropSpec contains:
Behavior: Create builds PropSpec metadata from adapter input Access allows outside objects access to internal metadata 2. Act as a Container for Proposal DataOnce a PropSpec has been created, it becomes possible to instantiate Proposals based on that pattern. Each of these Proposals can be used as a container for specific data related to a particular new hire (John Smith, born 6/9/64, attended Rutgers), a particular shipment (Shipment # 37702, leaving 3/3/97 from Long Beach pier 73), etc.Data can be saved in any partially-completed form. Hierarchic navigation through the data, a sort of “page-turning” through a complex document, comes built in, thanks to the hierarchic “map” contained within the PropSpec. Users move through and interact with the data in standardized ways. State: Proposal Data, the hierarchic collection of end-user
supplied data
3. Keep Versions of ItselfThe Proposal maintains a record of every change made to it, down to field-level granularity. With this Version list in place, a Proposal can undo actions that have already been accepted, then redo previously-undone actions. Combining undo and redo operations, a user can scroll back and forth through previous versions of the Proposal to check something in an earlier version, to recover from a mistake, or to return to the most productive point from which to continue.Versioning also enables auditing. Since a Proposal may pass among numerous parties during its life span, it is useful to be able to review exactly what changes were made when and by whom. All versions are retained for the life of the Proposal, or until explicitly disposed of. State: Versions, each containing a summary of changed
data, time of change, person making change, etc.
4. Retain and Track ErrorsIn a conventional transactional system, incorrect or incomplete data will usually not even make it through the user interface, and may terminate the transactional conversation. But a Proposal, being provisional, can accept erroneous or incomplete data, flag it as such, and monitor it for fix-up at a later time All errors must be eliminated before the Proposal turns into a formal transactional submission.Any number of error-messages can be associated with any Proposal element down to field level. Error notices persist across sessions and across locales; they travel with the Proposal.Our Proposal infrastructure includes an error-search mechanism that makes sure all errors are resolved prior to submission. Error messages are most often added at data entry, but they can also be set by an external “review agent” or by the back-end process when a commit fails. State: Error Messages and what parts of the Proposal
they are associated with
5. Hold AnnotationsUser-written notations can be “stuck” to any field or fieldGroup. Annotations signal work to be performed, ask questions, note problems, give instructions, provide explanations, make comments, etc. They are an important facilitator of collaborative Proposal preparation.Any number of Annotations can be associated with any Proposal element. As with Errors, Annotations can be externally manipulated and scanned for summary review. Annotations are versioned, and are thus undo/redo-able. State: Annotations: text of annotation, source,
time, field attached to
6. Protect Against Stale DataProposals allows users to work with their own copy of enterprise data, so that back-end resources are not tied up during the life of the Proposal. Since a Proposal can “live” anywhere from a few milliseconds to several months, there is a significant risk that the original data back on the server might change out from under it, causing data corruption when the Proposal is eventually submitted and the data rewritten.Proposal-based architecture resolves this problem via optimistic concurrency control, known less formally as optimistic locking. A record is kept of data values as they were copied at “check-out” time, and at submission time these values are checked against their back-end equivalents to make sure there has been no “data interference” by another user in the interim. Although it is a sound strategy, optimistic locking is infrequently used because it places so many demands on the programmer, who must specify in detail what data should be rechecked and what should happen if interference is detected. Under Proposal-based architecture, however, optimistic locking becomes simple. Built into the infrastructure are mechanisms that:
Assumed Values, a snapshot of the original values of candidate fields as replicated Behavior: Stale-data handling A Proposal has to both extract data from and submit data to a back-end
data store. It must be able to translate between its own hierarchic
structure and a back end that could be either relational, function-oriented,
or object-oriented.
A Proposal is able to perform populates and submits between each of these three back ends and four distinct Proposal types: New, Exists, Update, and Delete. State: Interaction Mode defines various Proposal
interaction patterns with the back end
8. Interface with ConsumerThe final Proposal responsibility is to interface with the front-end consumer. The Proposal object itself presents a complete public programming interface that enables any consumer object to communicate with a Proposal. In addition, it provides a standard Observer object (Publish-and-Subscribe pattern) that will notify interested consumers of various changes to the state of the Proposal.State: Observer Registry of interested consumers
Proposals Simplify Domain Objects Once a Proposal object joins the design scene, it acts as a natural
“attractor” for task-specific application behaviors that would otherwise
be dumped into domain objects.
Most object designers use some form of Model/View separation (e.g. Smalltalk’s
widely-copied MVC paradigm) to maximize understandability and reuse. This
is a powerful design construct that we highly recommend. However, designers
familiar with this notion sometimes shy away from Proposal-based architecture
because it introduces a third entity that doesn’t seem to fit into the
model/view dyad.
Once Proposals get designers thinking in terms of long-running, malleable,
pendable business functions, it’s a short jump to thinking about controlling
the definition and maintenance of the outer business process itself. This
is workflow territory. Workflow and Proposals are strongly compatible.
Workflow is the train; the Proposal is the container that the train transports.
New component-oriented visual construction techniques use some form
of “data-aware control.” Think of those demos where a developer drags a
bunch of GUI or Web components onto a blank window and builds an application
that magically knows how to make all the connections to the database.
We usually think of Proposals as preceding Domain objects in the application
lifecycle. But sometimes it’s useful for Domain objects to spawn
Proposals.
Even after a Proposal has been submitted to domain space and resulted
in a successfully committed transaction, it can be archived and continue
to perform posthumous service.
Proposals concretize the problem, so that design becomes easier to think about. They model a familiar piece of the real world, so that a complex technical process becomes easier to explain and intuitive to use. They abstract common behaviors, so that re-use becomes not just possible but natural. |
| Return to Kinexis Home Page |