Looking for best practice advice on data access for SMALL web sites - not enterprise

A

Alan Silver

Hello,

MSDN (amongst other places) is full of helpful advice on ways to do data
access, but they all seem geared to wards enterprise applications. Maybe
I'm in a minority, but I don't have those sorts of clients. Mine are all
small businesses whose sites will never reach those sorts of scales. I
deal with businesses whose sites get maybe a few hundred visitors per
day (some not even that much) and get no more than ten orders per day.
This is not enterprise level and does not require the weight of coding
and layers that enterprise applications need.

I'm looking for a guide to best practices for small sites. I work alone,
and am unlikely to change that, so the weight of extra layers and coding
to protect a database from the person coding the presentation layer
isn't necessary. I am happy to split the application into layers, but
only where there is some real benefit. Most advice I have seen involves
building a data access layer, a business logic layer and a presentation
layer. This seems over the top for a small site maintained by one
person.

Up until now, I have treated the .aspx file as the presentation layer,
the code-behind (and the client-side validation in the .aspx file) as
the business logic layer, and have a generic method in a utilities
function that actually communicates with the database. I want to know if
this is good practice, or if there is a better way.

I have been reading the tutorials at
http://www.asp.net/learn/dataaccess/ and they seem keen on using the
Data Table object in Visual Studio that allows you to create a
connection to a database without writing code. They also build a logic
layer, which seems unnecessary in my case, but I am willing to be
educated!!

Any and all comments welcome. Please remember, I am *not* writing for
the enterprise, I am looking for the best solution for small sites.

TIA
 
S

sloan

The only thing I do different for "small" versus "enterprise", is that I
sometimes create subfolders instead of actual different assemblies.

http://sholliday.spaces.msn.com/PersonalSpace.aspx 6/5/2006
5/24/2006
(here is example of my tier system)

To contrast "Enterprise" vs "Small App"

Enterprise would be: (for a fictional NorthwindManager application)
GranadaCoder.Applications.NorthwindManager.Presentation.Web.1
GranadaCoder.Applications.NorthwindManager.Presentation.Winforms1
GranadaCoder.Applications.NorthwindManager.BusinessLogic
GranadaCoder.Applications.NorthwindManager.Data
(each of the above would be a seperate assembly)

For a small applications.. I'd have 1 application:
GranadaCoder.Applications.NorthwindManager
and then different folders:

GranadaCoder.Applications.NorthwindManager.Web
GranadaCoder.Applications.NorthwindManager.Biz
GranadaCoder.Applications.NorthwindManager.DAL



You''ll notice that a few things:
1: I can't have 2 presentation layers in the small-app method. I can
have 1, because I have to choose Web or Winforms and marry myself to it.
2. Biz contains business objects, logic
3. Data contains objects which return (DataSets, IDataReader's, Scalars,
and voids/nothings)

The deal is that after doing so many Enterprise applications, I know when
I'm violiating the rules.
Its tempting to throw a business object over to the datalayer at times,
which isnt' possible in the enterprise setup, because .Data does not
reference .BusinessLogic

Tiered development is a mindset at times. Not just a "rule1, rule2, etc".

It isn't just about protecting the deep secret code from the presentation
guys. Its organizing code into compartments to help with maintenance and
for your own sanity.

Even the smallest of web project that I do, I do them correctly, using the
"folder system" above. While I ~could remove the business layer object at
times, it just goes so against my grain that I don't do it. And every once
in a while. you have to add something in and you go "ahh, the wisdom of
putting in the good business layer up front".

You can check my blog.

The other hint I can give is that:

strong typed datasets (to me anyways) is the po man's business
object/collection. They are fine for small projects.

Finally, if I know (ever) that I might need 2 presentation layers (a web app
and a winforms app), then I do it all in seperate layers up front.
 
S

sloan

I agree with Darren also. . as in.

The time you pay up front .. always seems to pay off later.

Spaghetti code is always harder to maintain.

I only do the subfolder thing ... knowing I'm not violating the rules.
If I wasn't sure about that, then I'd always stick with the tiers as
seperate layers/assemblies.
 
D

Darren Kopp

I've found that building websites (even small ones) with the 3-tier
approach is more work, but it's a lot easier to maintain as well. Your
code is a lot cleaner and easier to go through when something pop's up
that you didn't expect, which can sometimes help you save time rather
than it taking longer.

I've done both ways, now i do strictly do the 3-tier approach. I'm
typically the only developer as well. That's my 2 cents.

-Darren Kopp
 
A

Alan Silver

I've found that building websites (even small ones) with the 3-tier
approach is more work, but it's a lot easier to maintain as well. Your
code is a lot cleaner and easier to go through when something pop's up
that you didn't expect, which can sometimes help you save time rather
than it taking longer.

I can see the logic in that, but I'm still not really sure why people
advocate a separate business logic layer. In the examples in the
tutorials I linked before, most of the logic was stuff that would be
caught by validation rules anyway, so I'm not sure what the BLL adds,
other than weight.

Please enlighten me ;-)
I've done both ways, now i do strictly do the 3-tier approach. I'm
typically the only developer as well. That's my 2 cents.

OK, good to hear it from someone in a similar position. What do you
think of the Visual Studio DataSet approach? This seems like a neat and
tidy way of building a DAL without coding. Any thoughts?
 
A

Alan Silver

Spaghetti code is always harder to maintain.

Who says that a non-layered approach results in spaghetti code? I have
never really done layered development (partly because I'm self taught,
and never learnt that, which is why I'm asking these questions), but
would modestly claim that I do not write spaghetti code.
 
A

Alan Silver

sloan said:
The only thing I do different for "small" versus "enterprise", is that
I sometimes create subfolders instead of actual different assemblies.
<snip>

OK, I admit it, you lost me ;-)

It's when I read stuff like this that I wonder why I need such
complexity to do simple tasks. Maybe it's my lack of understanding, but
this all looks very weighty for what it does. You end off saying...
strong typed datasets (to me anyways) is the po man's business
object/collection. They are fine for small projects.

Do I take that to mean that the approach shown in those tutorials is OK?
I can see the logic and benefit of those, although I'm still not sure
why I need a BLL. It all looks a whole lot simpler than the stuff you
wrote before!!

Thanks for the reply, any further help appreciated.
 
S

sloan

In my examples, I do not use a strongly typed dataset.

I use objects and collections. (<List> in 2.0)

Instead of a strongly typed dataset, with a Customer (table) and a Orders
(table), I have

public class Customer

public class Order

and Customer has a child collection called
public OrdersCollection AllOrders


I happen to use a DataReader to populate my objects and collections. Since
IDataReader's are better performing than DataSets. (IDataReader's use the
fire_hose model, where you read the records 1 at a time, in a forward only
manner)

Developing those objects and collections takes time. However, for a serious
application, that's probably the way to go.

Using the strongly typed datasets kinda of give you the same functionality.
But its (my take) kind of the po's mans way of doing it.
It works.

For small apps, I use strongly typed datasets. Small, as in, ... I once
wrote an address collector for colleciting addresses after I got engaged.

I used to use strongly typed datasets all the time, but someone showed me
the light on that.
If you download the 1.1 example, you can also check out performance times.


...

//
Who says that a non-layered approach results in spaghetti code?
//

I can't "prove" it to you, I can only tell you thats how I (and alot of
others) feel about it.
Software Engineering is a lifelong process of maturing. When you start
looking at things like Design Patterns (www.dofactory.com), you
realize that what you thought was great 1 year ago, was not really so great.

When you start figuring out things like the Factory Pattern ... and how you
can make your code smarter.... you look back and go "Geeze...that stuff I
wrote before was pretty deficient".

That's my take. I can't prove it. I can only offer advice.

//
but
would modestly claim that I do not write spaghetti code.
//


Do you ever watch "The Office" on NBC?
There's a guy on there named Jim, (Tim in the British version). Jim is the
cool, does a good job but not too seriously guy... in the office.
Most people .. in their minds .. think "Yeah, I'm like Jim". Because Jim
handles situations with the most coolness and common sense.
And as Jim deals with other people in the office, viewers think "Yeah, I'm
like Jim because I've encountered people like that in my office"

The reality is that there are alot of people watching the The Office, and
they are not and they are really are like:
The insecure, attention needing, boss who thinks he's funnier than sliced
bread.
The butt kissing work nut, always trying to impress the boss.
The no fun anal person, who gets mad everytime somebody tries to have any
fun.
The non vocal good workers, well rounded and pleasant. Not too high above
the radar, not too far below the radar.


3 years ago, I thought I was a really good developer. That I didn't do
stupid stuff. I mean, I could wrap my arms around a business problem and
get it solved.
3 years ago, I could probably see about 1 or 2 levels down the road in my
design process.

Then I worked in a group of very good developers, and realized how deficient
I was. Which got me on the right path toward maturing as a developer.
Now I can see about 3 levels, sometimes, 4 levels down the road. But I am
still deficient.... as I said, its a lifelong process.


My non technical advice is that.. sometimes its hard to be self-aware,
especially in more isolated environments. I'm not trying to attack, I'm
just letting you know as I look back, that's how I feel, mainly because of
the boat I was in myself.

You might want to try looking at the source code of
http://www.eecs.wsu.edu/paint.net/
Paint.NET

That is a pretty well designed application which does some serious stuff.

I'm not omniscient, I'm just offering my advice.

Good luck with your pursuit.
 
A

Alan Silver

sloan said:
In my examples, I do not use a strongly typed dataset.
Developing those objects and collections takes time. However, for a serious
application, that's probably the way to go.

OK, forgive me for flogging this one, but I really want to understand
this properly. Why is this the way to go? What advantage does it have
over a strongly typed dataset?
Using the strongly typed datasets kinda of give you the same functionality.
But its (my take) kind of the po's mans way of doing it.

Again, why? I'm not saying you're wrong, I just want to know why. I'm
really genuinely here to learn best practices, but I want to understand
why something is best, not just do it 'cos someone said that's better
;-)

That's my take. I can't prove it. I can only offer advice.

That's OK, I came here for advice and I'm happy to hear it. I only ask
back on it to try and get it clear. I'm not saying you're wrong.
//
but
would modestly claim that I do not write spaghetti code.
//


Do you ever watch "The Office" on NBC?

Nah, don't have a TV. Can't stand them.

3 years ago, I thought I was a really good developer. That I didn't do
stupid stuff. I mean, I could wrap my arms around a business problem and
get it solved.

OK, right off let me say I don't consider myself "really good." I would
like to consider myself capable and fairly good, but really good? Nah.

My non technical advice is that.. sometimes its hard to be self-aware,
especially in more isolated environments. I'm not trying to attack, I'm
just letting you know as I look back, that's how I feel, mainly because of
the boat I was in myself.

That's fine, I appreciate the feedback ;-)

OK, so having got this far, I could do with some guidance. Looking at
that site, it looks way above my head. I wouldn't know where to start.
Furthermore, the factory method that you mentioned looks like a very
complex way to do a simple job. What's the benefit in doing it this way?
I know I'm asking a big question here, but as a newbie to the idea of
design patterns, I can't see what they offer me. Why would I invest so
much time learning and implementing something so complex for a simple
job like grabbing a datareader full of product names?

Again, not criticising, just trying to understand.
You might want to try looking at the source code of
http://www.eecs.wsu.edu/paint.net/
Paint.NET

That is a pretty well designed application which does some serious stuff.

I'm not omniscient, I'm just offering my advice.

That's what I asked for ;-)
Good luck with your pursuit.

Thanks. Any further advice and comments welcome.
 
S

sloan

This article:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/boagag.asp

sheds some light. I read the whole thing top to bottom about every 3 or 4
months.

There are pros and cons to each. The article describes them a lot better
than I could.

Whenever I use DataSets', and I have to find 1 employee among N number of
employees (in a strong dataset, in an Employee (table).
I have to use the .Select method. I then have to do some casting.

Type Safety would be the big reason for me. When I defined an Employee
(class) .. with an AllOrders (property), I know exactly what I have.

A small part:
If you do the business objects, then you have alot more options for
remoting, serialization. And scaling your application if you ever need to.
But again, that's "big", and you're interested in "not big".

With 2.0, and <List>'s, .. you don't have to write your own CollectionBase's
(most of the time).
Which makes the use of objects even easier.

...
 
S

sloan

Factories allow you to work with Interfaces or Abstract classes.... instead
of the concrete class.

Here is a very rudamentary example:

http://support.microsoft.com/kb/308046

This would be the "key" method .. as I describe at my blog:

You pass it a key... (radio button value in the KB)
You don't care ~how / who populates the dataAdapter.. You only care that it
gets populated.

If you using oracle or access or sql server on the backend, you don't care.
All you want is a dataadapter.

To critique the article, I wouldn't send back a dataadapter, I'd send back
an IDataReader.

The "factory" says, .. "populate a IDataReader for me". You pass it a key
... and it says "Ill use the key to populate the IDataReader with data from
an oracle database".

The design pattern isn't just for data base stuff. It has many items it can
address.

But its a start.

I'd look up "provider model" "membership provider"

This is an implementation of the Factory Design Pattern. MS has defined an
abstract class. To get users/roles etc. They also provide 1 (one)
implementation.

However, if you'd like to roll your own Membership Provider, you extend the
base/abstract class. and fill in the methods.

Then you set up your web.config file to use your custom implementation.

Behind the scenes, (based on the xml in the web config), Microsoft uses
reflection to instantiate your object. through a factory.
this would related to me example (blog) which uses a config file for the
Simple Factory.

the factory will create either (1) Microsoft's version of the membership
provider OR (2) my custom implementation .. and return it... AS THE
BASE/ABSTRACT class.

the outside world only knows about the base/abstract class.. it doesn't know
specifically about my custom class, or the microsoft default implmentation.
it doesn't care.
it only cares that it has ~something which extended the base class.

...

Ok, I've written a book now. I gotta get back to work.

Good luck.
 
A

Alan Silver

sloan said:
Factories allow you to work with Interfaces or Abstract classes.... instead
of the concrete class.

Here is a very rudamentary example:

http://support.microsoft.com/kb/308046

This would be the "key" method .. as I describe at my blog:

You pass it a key... (radio button value in the KB)
You don't care ~how / who populates the dataAdapter.. You only care that it
gets populated.

If you using oracle or access or sql server on the backend, you don't care.
All you want is a dataadapter.

OK, I see the logic in all this, but this is basically what I already do
with my generic data access method. Granted it's a single method in a
utility DLL, but the principle is the same. Yo pass it a request, and it
passes back a DataReader. The code-behind file that calls it has no idea
how it fills that DataReader, that's decided by the connection string,
which only the method uses.

In what way would I benefit from moving away from this simple method to
a more complex class? It seems that the class does basically the same
thing.
To critique the article, I wouldn't send back a dataadapter, I'd send back
an IDataReader.

OK, well I already do that, so I scored one point ;-)
The "factory" says, .. "populate a IDataReader for me". You pass it a key
.. and it says "Ill use the key to populate the IDataReader with data from
an oracle database".

The design pattern isn't just for data base stuff. It has many items it can
address.

But its a start.

I'd look up "provider model"

110,000,000 results!!
"membership provider"

57,900,000 results!!

This is my problem with this stuff. There's so much written, but little
that I can find that explains the basics in readable English.

Ok, I've written a book now. I gotta get back to work.

I know how you feel. That's one reason why I have stuck with my current
method for so long. It works, and I don't have time to read the vast
amounts of info required to learn these sorts of patterns.
Good luck.

Thanks, I'll need it!!
 
A

Alan Silver

sloan said:
This article:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/h
tml/boagag.asp

sheds some light. I read the whole thing top to bottom about every 3
or 4 months.

Wow, that's some reading!! I just had a skim through it, and it looks
like it's going to take some digesting. I'm currently printing it out
for bedtime reading.

My brief impression is that it assumes you already understand and desire
multi-tiered design. I could be wrong, having only glanced through it,
but it does seem to jump straight in with the layers. I'm still not
clear what benefit I have in doing it this way, rather than having the
code-behind file just pull data out of the database (via a central
method) and binding it to a control. I would appreciate some explanation
of this.
There are pros and cons to each. The article describes them a lot
better than I could.

Whenever I use DataSets', and I have to find 1 employee among N number
of employees (in a strong dataset, in an Employee (table). I have to
use the .Select method. I then have to do some casting.

Type Safety would be the big reason for me. When I defined an Employee
(class) .. with an AllOrders (property), I know exactly what I have.

OK, that's a reasonable point, but I'm wondering how much of an issue
it's going to be. For example, in an e-commerce site (which is what I do
most), the majority of data stuff involves pulling out a list of
products in a category, or details of one single product, then binding
that info to controls for display. The casting issue doesn't really come
up as the framework handles it all for you.

Similarly, adding a product to a basket is merely a case of one database
call to add an entry to the baskets table, then displaying the current
basket (which is basically the same operation as above). This is all
such simple stuff that I'm still wondering why it needs layers and so
on.
A small part:
If you do the business objects, then you have alot more options for
remoting, serialization. And scaling your application if you ever need
to. But again, that's "big", and you're interested in "not big".

Not a case of interested, more a case of where my life seems to be now,
and where it seems to be going. I am quite happy working with small
businesses, you get chance to build a relationship with them and feel
like part of the business, but it does mean that these sorts of issues
are rarely relevant.

Thanks for the reply. Any further comments welcome.
 
A

Alan Silver

sloan said:

OK, I read it right through last night and it was very informative. A
lot of what it suggested isn't that different from the way I do it, but
it was a lot more formal with separate objects for each layer. However,
it concentrated on the how and not on the why. I am still left with two
basic questions. Maybe you can shed some light on them...

Imagine you have an e-commerce site. Someone browses the products,
adding to their basket. They get to the checkout. Now, if the site was
written properly, the checkout page has a clean set of data for the
items to be purchased. The customer has to enter their name, address and
credit card details. Any validation required is done right here, using
the ASP.NET validation controls. Thus, by the time the data gets to the
business logic layer, there's no logic left to be applied. The
validation takes care of the logic. So, what's the point of the BLL? All
of the required logic is already in the coding in the actual page
itself.

Second, once you have the data, you want to store it in a database and
get an order number. This is where the DAL comes in. The data is passed
into the DAL, and that handles inserting the order and returning the
order number. My question is, why do you need a DAL for this? Why not
just have the calling code (in this case, the code-behind of the page)
insert the info directly? Now, I should point out that I have a generic
method called ExecSql() that takes either an SQL string, or an SQL
string and an array of parameters. This method provides the actual
database manipulation, meaning that the calling code doesn't have to
know anything about the actual database or the connection string. It
seems to me that this achieves pretty much the same as a DAL, except
that the SQL is in the page's code instead of being in a separate class
(the DAL). I can't see the benefit of adding an extra layer for this.
The way I do it, all the relevant code is in one place, so debugging is
easier, and I still have the benefit of having the database-specific
bits in a generic method that is used everywhere. So, why do I need a
DAL at all?

Thanks again for the help. I'm a bit clearer on how these things work,
but I still can't see the necessity for the extra weight of a DAL and
BLL. Why not just do it all in the code-behind?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,810
Latest member
Kassie0918

Latest Threads

Top