Added by Ted Husted, last edited by Ted Husted on Nov 19, 2005  (view change)

First Principles

"... as I observed that this truth, I think, therefore I am (COGITO ERGO SUM), was so certain and of such evidence that no ground of doubt, however extravagant, could be alleged by the sceptics capable of shaking it, I concluded that I might, without scruple, accept it as the first principle of the philosophy of which I was in search." – Rene Descartes, Discourse on Method (Part IV).

Let's say we want to create a series of best-practice business applications. Mainly for the web, but maybe for the desktop too. And, let's say we want to create and maintain these applications for multiple development platforms. Say, starting with Java and Mono, and maybe PHP later.

How can we write these applications so that they share as much code as possible?

What do most business applications have in common, regardless of development platform?

The classic stategy for application development is Model View Controller (MVC). In the original MVC pattern, the Model retains the state of the application. The View renders the Model and acquires input. The Controller accepts input from the View, updates the Model, and selects the next View. The selected View renders the updated Model, closing the loop.

In the enterprise version of MVC (aka MVC2 or Model 2), the View acquires input and passes it to the Controller, initiating a request. The Controller uses the input to update the Model, obtains the current Model state as output, and selects the next View. The View renders the output, completing the request.

Like Descartes, let's start with a first principle. The principle may be simplistic, but that's the point.

Our First Principle

A software application turns input into output.

Now we can ask ourselves: How do we get there from here?

First Steps

The first steps are to accept input from the client and verify that the input we need is provided.

Validate Input

A prudent application checks to see that all required input is provided.

If input is missing, an application should fail gracefully and signal that there is an error condition.

Tender Messages

A robust application provides messages to the client, explaining any problems.

Most often, input arrives as text. The input may be coming from a command line program, or a web service, or a UI widget, but most often it arrives as text.

Text is universal, but, internally, most applications need to use date and numeric types too. We need to accept text but convert it to whatever internal representation we need to get the job done.

Convert Data

A cooperative application converts text input to the appropriate data type.

Once we have the input we need, in a datatype we can use, the application can go about creating output. It's time for the rubber to meet the road.

Process Logic

A competent application executes whatever processes are needed, in whatever sequence is required, and fails gracefully should anything go wrong along the way.

Clients often expect output values to be rendered in certain ways. Monetary values may need a currency sign. Dates might need to be in long or short formats. A string of digits, like a social security number, may need hyphens inserted here and there.

Format Output

A considerate application provides output in whatever text format is expected.

The output values are returned to the client, and on the presentation layer, a client will continue to work with the output, turning it into a web page – or a PDF or a graphic display. A client might then acquire new input, and the process would start anew.

So far, the five tasks we outlined

  • Validate Input
  • Tender Messages
  • Convert Data
  • Process Logic
  • Format Output

describe most of the things that a MVC2 Controller is expected do. An application needs to do many more things, but those tasks can be handled by a presentation layer or a persistence layer. For example, a presentation layer dispatcher could select the next View. Data access objects might interact with a database management system.

But, to get there from here, we need a controller to validate input, tender messages, convert data, process logic, and format output.

If we designed an application controller to do these five core tasks, what would it look like?

Validate Input

Expressed as a workflow, we must

  • convert expected values to the expected format
  • note any formatting errors
  • validate that required values converted correctly
  • note any missing values

If any errors are detected, we must report the errors to client, without servicing the request.

To complete the workflow, we will need

  • the input values tendered by client
  • the list of values we expect
  • the target datatype for each value
  • error messages for incorrect input
  • the required values
  • error messages for missing input

If input is both malformed and required, we should report both

  • The ${field} must be a valid date.
  • The ${field} is required.

So that the client knows that the input cannot be omitted.

Given the requirements of our workflow, the controller must provide

  • an input buffer for incoming values
  • a list of expected and required fields
  • an index with the target datatype and error messages
  • a message buffer
  • an internal buffer for validated input

Why validate input?

In an enterprise application, clients are not to be trusted. Clients may omit necessary input, include spurious input, format input incorrectly, or provide inappropriate values. Sometimes input errors are accidental and innocent, sometimes errors are intentional and hostile. In either case, a controller must vet all input, report any errors, and pass through only the input we want in the format we expect.

(To be continued)


Site running on a free Atlassian Confluence Open Source Project License granted to OSS. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.5 Build:#811 Jul 25, 2007) - Bug/feature request - Contact Administrators