Dealing with Object-Oriented Applications

Whether we're in a distributed environment or not, the use of an object-oriented application architecture poses different sets of challenges for reporting and batch processing, which we can take a look at in turn .

Reporting and Objects

Before we get into the details of report generation and objects, we need to divide the idea of report generation into two groups: small reports and large reports .

Many Enterprise resource planning (ERP) and manufacturing resource planning (MRP) systems make exactly this distinction: small reports are often called lists , while large reports are called reports . Lists can be generated at any time and are displayed immediately on the client, while reports are typically generated in the background and are later displayed through a viewer or printed out.

Of course, the exact delineation between a "small" and a "large" report varies. Ultimately, small reports require small enough amounts of data that it's reasonable to transfer that data to the client immediately upon a user request. Large reports require too much data to transfer to the client immediately, or they take too long to generate to have the user 's machine (or browser) tied up waiting for it to complete.

The problem of sheer data volume affects both large reports and batch processing, so we'll discuss it (and a potential solution) in the next section. In this section, we'll deal with a problem that affects large and small reports alike: Report generation tools lack support for objects.

The Windows Forms and Web Forms environments both provide solid support for UI creation when using objects. As we've seen, we can use data binding to bind UI controls to the properties of our objects, just as we can with data sources such as the ADO.NET DataSet . In fact, this support is comprehensive enough that we haven't used a single DataSet object in this entire book ”until now.

The problem we face with reporting is that none of the major report-engine tools support data binding against custom objects. Reports generated with popular tools such as Crystal Reports or Active Reports can only be generated against ADO.NET object such as the DataSet .

Tip  

To be fair, these report engines also work in an " unbound " mode, where we have the opportunity to supply the data to populate the report manually. This technique can certainly be used with business objects. We can write code to pull the data out of our objects, and provide that data to the report engine as it generates the report. The trouble is that this is a lot of work, especially when compared to just binding the report to a DataSet .

Ideally, in the future, one of the major report-engine vendors will support data binding against objects just like Windows Forms and Web Forms do, but that's not the case today. We can either generate the report from a DataSet , or use the engines in unbound mode and provide the data manually.

To help address this for now, we can create a compromise solution: a converter to load a DataSet with data from objects. If we can convert an object into a DataSet , we can then generate reports in standard report engines such as Crystal Reports or Active Reports by using that DataSet .

This last approach is useful for lists, but not reports. By our definition, lists require relatively small amounts of data, so it's acceptable to transfer that data to a client and generate the report there. Reports, on the other hand, require processing large amounts of data, and the closer we can do this to the database the better. In this case, directly using Crystal Reports or some other reporting tool against the database is often the best solution.

Batch Processing and Objects

While the primary problem with reporting and objects is lack of support from the tools, there's another issue. In fact, this issue is the primary problem we face when implementing batch processing with objects: data volume.

If we're interacting with thousands or millions of rows of data to generate a report or to perform a batch process, this could mean creating thousands or millions of objects in memory. There's overhead involved with each object we create. It takes processor power and memory to create an object; memory is consumed as long as the object is alive ; and processor power is consumed to destroy the object. In the case of our CSLA .NET business objects, there's additional overhead in storing IsDirty , IsDeleted , BrokenRules , and other state data for each object.

In most applications, we don't even think about this overhead, because the creation of a few dozen or even a few hundred objects is pretty inconsequential ”the overhead is tiny. This all changes if we're proposing to create a few hundred thousand objects, or a few million. The tiny overhead of each object, multiplied by these huge numbers , becomes a lot of overhead that can be very problematic .

Obviously, there's a certain amount of processing and memory usage that's unavoidable ”we have to at least load the raw data that we're going to work on! The issue here is that wrapping that data in objects increases the overhead ”and with huge data volumes , this is a big issue.

Note  

This isn't a new concept, or one that's unique to .NET, or to our implementation of business objects. This issue has been plaguing object-oriented development since its inception.

The most common solution to this problem is to avoid the use of conventional objects when implementing large data-processing applications. This isn't to say that we don't use object-oriented concepts and techniques, but it's to say that classic, "stateful" objects don't have much application when building large batch processing or reporting systems.

One possible object-oriented solution is described by the Flyweight design pattern, in which a small number of objects are created. Each of these objects points to a particular data element while that element is in use, and then to other elements as they're used. The key is that a Flyweight object contains little or no internal state. Instead, it gets its state data as a parameter to each method, so the state data exists outside the object itself.

Tip  

The Flyweight design pattern is discussed in Design Patterns by Erich Gamma, et al. [1]

Even after considering a technique like this, though, the reality is that large reports and large batch processing is often best done without the use of objects. Instead, large reports are usually best generated by using ADO.NET to retrieve the data, and feeding that data directly into the report engine. Large batch processes are usually best implemented by reading the data directly from a data reader, and doing the updates by calling stored procedures directly through a command object. We can encapsulate this code into a class or object, but ultimately the process is a linear, procedural one.

[1] Erich Gamma, et al., Design Patterns (Reading, MA: Addison-Wesley, 1995).



Expert C# Business Objects
Expert C# 2008 Business Objects
ISBN: 1430210192
EAN: 2147483647
Year: 2006
Pages: 111

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net