At the center of the Web Store application are the Business Objects that handle the data interaction and logic operation of the store. The business objects are used both for the Web application and the offline viewer to provide a layer of abstraction and serve to isolate the business logic away from the user interface implementation (Web or GUI).

As a result you'll find that there is very little business logic in the Web Connection specific portion of the Web application. The offline viewer has a number of features that are specific to West Wind Technology's business needs and thus has a little more code, but even this custom code uses business objects extensively to perform these tasks.

Class Hierarchy


The store business objects are based on the simple Web Connection wwBusiness object class that is based heavily on a data centric design. This simple business object is a single layer business object that combines the business logic and data access layer into a single object manager. This simple design works well for small applications and tend to be more efficient than a more structured n-Tier approach which would break out for an additional data access object. The reason for this design was to keep things simple and performance up as there is significant overhead in another object layer to data access. What you loose in this scenario is more work if you migrate to a different backend than the ones that are already supported (VFP, SQL Server and Web Data).

All of the BOs are derived of the wwBusiness class which provides base functionality for loading, saving, adding of individual records in these business objects. It also supports creating of tables and a number of features related to creating new records and administrating the table(s) the object presides over. By default wwBusiness maps to an underlying table, but this behavior is not required. You can create more abstract and compound objects easily and override the base behaviors for methods such as Load and Save easily.

For example, the cInvoice class is a compound object that manages and handles multiple objects such as Customer, LineItems and Invoice objects. The appropriate methods are overridden to provide this functionality and call these additional business objects to perform their own Save and Load operations and so on.

oData Member holds object data


All wwBusiness objects have an oData member which is typically used to hold the data of the currently active record. For example, to load an item you can use code as the following:
loItem = CREATE("cItem")

loItem.GetItembySku("WCONNECT")
oItem = loItem.oData
? oItem.SKU 
? oItem.Descript
oItem.Descript = "New Value"

oItem.Save()

Sku and Descript are fields in the underlying wws_items table that is controlled by the cItem class. If you add fields to this table these fields automatically show up on the oData member so this design is very extensible.

Most objects are simple like the cItem object which map almost directly to an underlying table. Each business object has an oData member that contains the actual fields of its master table. However, you can extend business objects as you see fit. For example, when you look at the invoice object you'll see that that object has additional references to other business objects like cCustomer and cLineitems providing compound functionality. For example:

loInv = CREATE("cInvoice")
loInv.Load(1000)  && Pk

? loInv.oCustomer.LastName
? loInv.oLineItems.aRows[1].sku

Because data is stored in object properties it's very easy to display that data in template pages without having to write code in those pages. Any code that does need to be written to access the objects is very simple since the objects are self contained.

The business object supports loading objects and querying which is nice for retrieving data without explicitly accessing the underlying tables.The query and find methods can return data either as a table, XML or an ADO recordset. For simple operation the base methods provide a lot of functionality without any new code requirements.

To extend functionality and common operations the business object is extended with custom methods. These methods can be as simple as running a common query (sort of like a view that's not bound to a specific database) , or much more complex operations like for example saving an invoice to disk.

In the wwStore application the master object is an invoice object which provides functionality to load and save all of its related items through its methods. So saving the invoice causes the customer and lineitems also to be saved. The entire operation is atomic and wrapped into a TRANSACTION to allow ROLLBACKs in case something in the middle of this complex update fails.

Custom behaviors


The base business object class is fairly powerful and for simple tables like items which are non-related they can work without hardly any changes. The business object class supports generic query and find methods, but you should be careful with these methods if they cause you to write SQL filters that may not work properly across different SQL platforms. IOW, only simple filters and queries should be passed through these generic methods. Instead, if you have complex queries that need to be configured for an object you should add custom, potentially parameterized methods that can return the data to you. Internally these methods can then call Query() to run these queries and provide the base functionality to return these queries in the several supported data formats (such as XML, ADO and VFP Cursors) or you can call the ConvertData() method directly to it explicitly.

The whole idea is to build objects that expose interfaces that are easy and logical to use from calling code yielding fairly self-describing code. After all you can probably figure out what:

oInv.Load("InvoiceNo")

does.

The benefit of this architecture is that you now have an object that's easy to manipulate without a data dependency, that can be passed around easily and if necessary can be persisted into XML for easy transfer over the wire for example to download orders over the Internet.


Last Updated: 06/02/03 | Send topic feedback