Back
Draft
Is
There Business Logic in Your Middle Tier?
By Jonathan Goodyear
Most Web
developers are familiar with the concept of an n-tier application.
Although "n" implies three or more tiers, three is the standard: user
interface, business logic, and data. In Classic ASP, the user interface tier
consisted of HTML tags interspersed with VBScript to build the page layout. The
data tier was a database such as SQL Server. The business logic tier sandwiched
in the middle, however, was often horribly underused.
In most
Classic ASP Web applications I've seen, the business logic tier really didn't
have any "business logic" in it. It merely consisted of stored procedure (or
embedded SQL) calls wrapped inside Visual Basic pass-through components. In
fact, the only reason Classic ASP developers used VB components at all was
because of the performance advantage of leveraging compiled code. It's quite
obvious that the term "object-oriented" was merely paid lip service during the
Classic ASP era.
But
let's jump ahead to the wonderful world of ASP.NET. In ASP.NET, every page is
inherently an object, so you can't help but develop object-oriented code,
right? Unfortunately, this has not been the case for many Classic ASP
developers making the switch to ASP.NET. They are still mired in the old way of
thinking when it comes to the business logic tier of their applications. Most
ASP.NET applications I see today have ever fattening user interface tiers (in
code-behind logic), and the thinnest business logic tier imaginable.
This
time around, the performance-advantage argument no longer applies. All the code
in ASP.NET is compiled, so that benefit went right out the window. The only
slight advantage that remains is that you're encapsulating your stored
procedure calls - hardly the vision that our object-oriented forefathers had in
mind.
So
what's missing? The logic of course. To effectively leverage object-oriented
concepts in your development, you need to change the way you think about your
business logic tier. Instead of thinking of it as nothing more than a means to
extract data from your database, think of and build your business logic
components as an SDK (Software Development Kit), not unlike the .NET Framework
itself. Inheritance, polymorphism, and all the other object-oriented goodies
that .NET provides for you make this process a snap.
I wrote
an article on organizing your .NET namespace structure (http://www.fawcette.com/vsm/2003_04/online/goodyear/default_pf.aspx),
so I won't go into that too much here. Suffice it to say that in your company's
.NET object hierarchy, your company name becomes the top-level namespace
(similar to the System namespace in the .NET Framework) and application
and functional sub-systems make up the rest of the namespace hierarchy, staying
as close as possible to the standard namespaces implemented in the .NET
Framework.
Even the
most organized .NET namespace hierarchy doesn't solve the problem, however, if your
business logic components don't have the right logic in them. There are a few
fundamental things that all your business logic components should contain.
First, they should be self-validating. When you build your business logic
components into an SDK, you are effectively disconnecting it from your Web
application, and any input validation that it performs. Therefore, your
business logic components are the last line of defense to make sure that only
valid values make it into your database. Even if you have field value
constraints implemented in your database, you'll still want to validate your
input data so you can throw more informative custom exceptions to the consumers
of the component, whatever that consumer may be.
Speaking
of database connectivity, each of your business logic components that talks to
a database should inherit from a base class that implements a property for a
database connection string. Because your components can now be used by multiple
consumers, you can't have any connection string retrieval logic baked into
them. It is much better to have the consumer provide that information at run
time.
I'm a
firm believer that the user interface tier of any application (including
ASP.NET Web applications) should be ADO.NET-free. ADO.NET is a great technology
for retrieving and manipulating data, but it isn't very well suited to
representing the logical entities in your application. Typed DataSets
are about as close as you can come, and those are an absolute nightmare to
manage (Whidbey will go a long way toward fixing this).
Instead,
your business logic components should distill your ADO.NET objects into objects
that represent the entities in your system. For instance, if you're retrieving
a list of customers from your database, don't return a DataSet with
customer information in it. Instead, create a typed collection of Customer
objects and pass that back. While you're building that typed collection, you'll
also have the opportunity to perform any other necessary logic that wasn't
performed by the stored procedure.
As long
as your typed collection implements the IEnumerable interface, you'll
still be able to bind it to all the server controls that you know and love.
You'll also be able to take advantage of all the custom properties, methods, and
sub-objects that you've implemented in your objects. IntelliSense alone will be
enough to sell you on that feature.
The
bottom line is that the code-behind class for each of your ASP.NET pages should
only contain the glue that binds your company's business logic SDK with the
elements of the page, and the elements of the page to each other via event
wire-ups (where applicable). Put all the real logic that makes up your Web
application into a framework of business logic components that can be re-used
by any number of different consumers: Windows Forms applications, Web services,
mobile devices, etc. Moving to ASP.NET requires more than just changing the
technology or platform you're using. It means finally changing your mindset
about the way an application is built, and where its constituent pieces go.
Hopefully,
the ideas I've presented here will get you started in the right direction.
You'll definitely find that your applications come into focus much more quickly
and easily using this approach.
Jonathan Goodyear is president
of ASPSoft (http://www.aspsoft.com), an
Internet consulting firm based in Orlando, FL. He's a Microsoft Certified
Solution Developer (MCSD) and author of Debugging ASP.NET (New Riders). Jonathan
also is a contributing editor for asp.netPRO. E-mail him at mailto:jon@aspsoft.com
or through his angryCoder eZine at http://www.angryCoder.com.