[ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ]

Describe a disconnected data access structure

The problem described above leads us to the realization that we need to somehow have a disconnected access to our data if we are to have an architecture that will scale to web based applications.  Now we could design a connected data architecture for our internal applications and use a different architecture for any web-based components that may arise in the future, but that would cause us to be using two differing application architectures and would totally prevent use from leveraging any work we did on the internal applications for our web requirements.

Instead we could design a disconnected data access mechanism that can be used in both the web-based environments and in our internal VFP applications.  What we need is a data access mechanism that is disconnected and stateless.  The diagram below shows the design we need to achieve.

In this design the business logic layer and the data access layer are not always connected.  The presentation layer will request data from the business logic layer.   Then the business logic layer will determine if it has the data necessary to comply with the request, if it does not it will make a connection to the data access layer and request the required data.  The data access layer will then submit a request to the data storage layer for the necessary data and return it to the business logic layer.  Once the data access layer has returned the data it then forgets everything it knew about that data and is prepared for a new request.  The business logic layer will then supply the requested data to the presentation layer.

In the reverse, that is updating data, the sequence is similar.  The presentation submits some data top the business logic layer for updating.  The business logic layer applies whatever business rules there may be and, given that the rules are passed, it establishes a connection to the data access layer and submits a request to update the data.  The data access layer then submits the request to the data storage layer and returns a status value indicating whether the update was successful or not.  The business logic layer will then return that same status to the presentation layer.

So why do we need all of this complexity?  If you examine the architecture carefully you can see that the only layer that needs any knowledge of how the data is displayed or manipulated by the user is the presentation layer.  This means that our business logic classes can support multiple differing user presentation without needing to be changed internally.

The business logic layer has no knowledge of exactly where the data resides or how the data is accessed.  These technologies are isolated to the data access layer.  This means that we can easily move the data storage from VFP tables to SQL Server without making any changes to the internals of the business logic layer.  We can also change our data access methodology from SQL Passthrough to ADO+, or any other data access technology, by making changes in the data access layer alone.

Programming to Interface not implementation

What, exactly, makes all of this possible?  It is a simple but pervasive concept called “programming to interface not implementation”.  Refer to the diagram below for the next discussion.

In the diagram you see that the only communication between the business logic object and the data access object is through their respective interfaces.  This gives us an architecture where the only dependencies are between the interfaces and not the specific code used within an object.

An object’s, or class’s, interface is comprised of the public methods, their arguments and return values and the public properties of the class or object.  The implementation is the specific code inside of the methods.

Design classes to support a disconnected data access design

So in our diagrams above we can see that we will need two sets of classes to access and write data in our architecture.  We will design these classes in separate class libraries so that they can be used independently in the future.

The first class library we will create will hold our data access classes.  The design of our data access base class is shown below.

Let’s look at some documentation of what these classes do for us.

Data Access

The data access class is a composite and abstract class.  It is composite in that it contains an XMLHandler class and it is abstract in that it is not used directly to create objects.

The data access class has two subclasses named VFPDataAccess and ADODataAccess.  The intention of these two subclasses is to allow for the implementation of two different methods of accessing the data storage, one using Visual FoxPro data and VFP access methods and the other using other data sources and ADO methodologies to access that data.

Each of these subclasses has a subclass for each “entity” that needs to allow data access.  In the diagram we show the Customer and the Order entities.

The XMLHandler is used to produce and interpret XML streams that move between the data access and the business logic layers.

XMLHandler

The XMLHandler class is also an abstract class used to introduce the interface for all XML handlers in the design.  Our diagram shows two concrete subclasses, VFP6XLMHandler which is coded to work under Visual FoxPro 6.0 and VFP7XMLHandler which is coded to work in Visual FoxPro 7.0.

We need to two subclasses because VFP 6 and VFP 7 have different capabilities when dealing with XML.  VFP 7.0 has many built in functions that can be used whereas VFP 6.0 does not have these functions available.

You will see, later, that we reuse these XMLHandler classes in our business logic layer classes.  Let’s look deeper into the XMLHandler class design for VFP 6.0.

Internal Design of XML Handler class

We will start our in depth discussion of these classes with the XMLHandler class.  First let’s mention why we have an XML handler at all.  Since we are designing a disconnected data access system we need a way to move data between the data access layer and the business logic layer.

There are many ways we could move the data.  We could use VFP cursors or we could use a text stream, however XML provides a standard structure for moving data around that allows us to make our system versatile and robust.  By using XML we are not “married” to Visual FoxPro for both layers since other tools can assimilate XML as well.  We are also not making ourselves proprietary by using some structure that is private to our design; instead we are using an industry standard.

Below are listed the methods in our XMLHandler class along with a description of what each method does.
Method Name Visibility Description
CreateCursor Protected Creates a cursor structure to hold the data in the XML stream.  Actually creates two matching cursors, one that will be edited and one that will remain exactly as originally populated by this object.
CreateEmptyXML Protected Creates and XML stream that contains only a schema with no data.
CreateSchema Protected Creates the schema description for the XML stream
CreateXML Public Creates the XML stream for sending out.
GetNumSize Protected Determines the size of a numeric field within an XML stream when parsing the stream.
ParseXML Public Takes an XML stream and creates the two cursors described above.
PopulateCursor Protected Puts data into the cursors created by the CreateCursor method.
VerifyXMLStream Protected Verifies that an XML stream is one that this object can read.

Below is a listing of the properties of the XMLHandler class along with a description of their purpose.
Property Name Visibility Description
cLastError Public Holds a description of the most recent error that occurred in this object.
cXMLStream Protected Holds the XML stream being processed.
FieldList(1,5) Protected Holds a list of the fields that are included in the data being processed.

The job of the XMLHandler object is to take a cursor and produce an XML stream containing the data within the cursor and to take an XMNL stream and produce a cursor with the data contained in the XML stream.

Both the data access class and the business logic class must do these two processes in order to exchange data between themselves.  They both will use this XMLHandler class to accomplish these tasks.  Since they both use the same XML handler class any changes we make to the XML or the processing of the XML will be incorporated in both sides of the data access operations.

Internal Design of Data Access class

This object provides services to the business logic layer and consumes the services of the data storage layer.  It is the bridge between the business objects and the database system used to store the data.

Below are listed the methods of this class along with a description of their functionality.
Method Name Visibility Description
DoDelete Protected Deletes an existing record from the data source.
DoInsert Protected Inserts a new record into the data source.
DoUpdate Protected Updates an existing record in the data source.
FetchData Public Gets data and returns that data based on a request from the business logic layer.
WriteData Public Writes data to the data source based on a request from the business logic layer.

Now the properties are described.
Property Name Visibility Description
cAliasName Public The alias name to be used for the cursor that temporarily holds the data.
cDatabase Public The name of the database that is the data source
cFields Public A delimited list of field names within the data source.
cLastError Public Description of the last error that occurred in this object.
cTable Public The name of the table that is the data source.
cWhere Public The where clause that will be used in the SELECT command that gets the data or does the updates.
cXMLHandler Public The class name for the XML Handler that this object should use.
cXMLHandlerClassLib Public The name of the class library that the XML Handler class resides in.
FetchType Public The types of fetch data operation for this object.  Designates whether this object does a SELECT, uses a remote view, uses ADO, uses SQL Passthrough, or fires stored procedures in the data storage system.
nConnection Public The connection handler for this object if it is using a connection.
pkFieldName Public The name of the primary key field for the table that this object gets and writes data from and to.

Internal Design of Business Logic class

The following tables show you the methods and properties of the business logic object design.
Method Name Visibility Description
AddRecord Public Adds a new record to the cursor.
CheckFieldName Protected Checks for a valid field name.
DeleteRecord Public Marks a record for deletion.
FetchData Public Gets data from the data access object.
GetField Public Returns the current value for a field.
GetFirst Public Moves to the first record in the cursor.
GetLast Public Moves to the last record in the cursor.
GetNext Public Moves to the next record in the cursor.
GetPrevious Public Moves to the previous record in the cursor.
IsDeleted Public Returns a logical value indicating whether the current record in the cursor is marked for deletion.
NextAvailable Public Returns logical value indicating whether there are any other records further in the cursor.  Sort of a logical end of file.
PreviousAvailable Public Sane as NextAvailable except it is checking for beginning of file.
PutField Public Updates a field in the cursor with a new value.
RecallRecord Public Unmarks a record fro deletion.
RemoveUnchanged Protected Removes all records in the cursor that have no changes to them since they were obtained from the data access layer.
RevertRecord Public Reverts any changes that have been made.
ValidateData Public Method to be used by developers to do any data validation that may need to be done.
WriteData Public Writes the data within the cursor back to the data access object.

The properties are listed below.
Property Name Visibility Description
cAliasName Public Alias name for the cursor.
cXMLHandlerClass Public The name of the XML handler class to be used.
cXMLHandlerClassLib Public The class library for the XML handler.
DataAccessClass Protected The data access class to be used.
DataAccessClassLib Protected The class library for the data access object.
FieldList Protected A list of valid field names.

As you have seen in the previous diagrams these two objects (the business logic object and the data access object) work together to provide access to data with both read and write operations.  These objects could reside on the server moving data to and from the presentation layer using XML, or they could reside on different machines.  That is, the data access object residing on the server and the business object on the client.

In our sample application we will be creating the data access object external to the presentation layer through the technique called aggregation.  The business logic object will be created internal to the presentation layer using composition.  Let’s take a moment and

understand the difference between aggregation and composition.

Aggregation versus Composition

Examine the diagram below as we discuss the difference between these two approaches of combining multiple objects.

Aggregation is seen in the lower diagram.  Here Object A refers to Object B through aggregation, Object A holds a reference to Object B which exists completely external to Object A.

Create application components using the data access classes

We will now spend some time looking at a number of presentation layer components that have been designed specifically to work within our architecture.

Open discussion, questions, and individual issues

[ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ]