views:

641

answers:

2

I am a fairly rookie programmer who is trying to learn the basics of n-layered architecture (DAL, BLL, UI). The application I am programming is a single tier, 3-layer application written in VB.NET (.Net 3.5). Layers as follows:

DAL

BLL

UI

COMMON - contains DTO's right now.

I am having trouble determining what to pass between my BLL and UI. My instinct tells me that I should only pass data to the UI, and not the full business object from the BLL. Consider two scenarios:

1) Pass the BO directly from BLL to UI. This exposes BO methods and allows the UI direct access to the BO, which seems bad.

2) Pass only the pertinent data from the BO to the UI. For instance, a customer has a Name and Address. This data is really what we want to show/edit in the UI, so we would only return that data to the UI instead of the full BO. The UI would then call to the BLL to update a specific BO.

I am inclined to use #2, but I don't know the best way to implement it. The way I have it programmed now, if I only return data from the BLL, all references to my BO's will be lost and the GC will claim them. Based on this, I have some questions:

1) Should I keep business objects alive between calls to the BLL? The alternative is to re-create them every time I pass data through the BLL, which seems wrong.

2) What is the best way to keep a BO alive in a single tier architecture (how to hold a reference if we dont pass it to the UI?)

3) How do n-tier applications do this? Do they keep the BO's alive in the BLL and wait for an update from the UI? Doesn't this require a lot of "book keeping" in the BLL to make sure BO's are released when they are no longer needed?

Thanks for any insight, and pardon me if I am asking something stupid. I taught myself the little programming I know, so I may be asking a stupid question and not know it.

A: 

Here is how I have always done it:

UI - ASP.Net or Windows makes call to a web service
SERVICE - This is the service layer that the UI calls
COMMON - DTO - Data Transfer Object the key is in the name
BLL - Contains Business Objects and code to map DTOs to Business Objects and back only DTOs are passed to the service layer
DAL - Data access

Burt
Thanks Burt, this is what I'm trying to achieve. Does the BLL retain BO's between calls? For example, we pull the data for display in the UI which creates BO's in the BLL. Are these BO's kept for use in returning data or do they get trashed and new ones created when data is sent back down to the DAL for storage?
Casey
We work over web services so the business objects are disposed after every request.
Burt
A: 

See Pet Shop as an example of 3 layer architecture. I'll implement both BLL and DAL as service object, which on its own does not hold any states. Since they are stateless, I can use singleton pattern and let a factory hold on to it for easy reference.

Here are some example CRUD methods you could have:

FooInfo DALFactory.FooService.Retrieve(int id);
FooInfo BLLFactory.FooService.Retrieve(int id);

IList<FooInfo> DALFactory.FooService.RetrieveAll;
IList<FooInfo> BLLFactory.FooService.RetrieveAll;

FooInfo DALFactory.FooService.Create(FooInfo entity);
FooInfo BLLFactory.FooService.Create(FooInfo entity);

FooInfo DALFactory.FooService.Edit(FooInfo entity);
FooInfo BLLFactory.FooService.Edit(FooInfo entity);

void DALFactory.FooService.Delete(FooInfo entity);
void BLLFactory.FooService.Delete(FooInfo entity);

As you can see in both cases, you pass the same entity object (aka data transfer object) that has no logic whatsoever. This architecture allows you to disconnect UI layer from BLL down the line to rich client and web services combo.

The intension of the Retrieve and RetrieveAll method is to grab the data from the database and stuff it into entity object. Create method adds a new row to the database based on the given entity. In this architecture, there is no "business object" besides Business Logic Layer's BLLFactory.FooService and the entity FooInfo object.

In terms of the lifetime of these objects, the stateless BLLFactory.FooService is created once, and will be reused as long as the app is alive. FooInfo could be created once per object, and then persisted into the ASP.NET session or something.

eed3si9n
So when you pull data for display to the user, a set of BO's gets created and then trashed. When the user needs to update some data, new BO's are generated on the way back to the DAL, right? You are creating new BO's both ways?
Casey
What's a BO? If you mean the BLLFactory.FooService, it's created once and it's reused many times.
eed3si9n
Sorry, BO = Business Object. If I'm looking at it correctly, your FooService is creating a Business Object from a DTO. Suppose our application simply displays some data, allows a user to edit, and then save it. Do the objects created by FooService remain in scope for the entire duration of editing and saving, or do they get created once when data is displayed and again when data is saved?
Casey
DALFactory.FooService and its wrapper BLLFactory.FooService are completely stateless. All states must be stored in the entity FooInfo. I updated the answer.
eed3si9n
Thanks for the response. I think the architecture I'm attempting to implement differs from what you are showing, but I appreciate the examples.I have seen a lot of people use the same principles you are using here, but I also see people like Martin Fowler who seem to want both data AND logic inside the Business Object. In the example you use, the data is in the FooInfo entity and the BLLFactory and DALFactory contain all the logic. So lets say we want to FooInfo to be able to print. Your architecture would be BLLFactory.FooService.Print(FooInfo) and mine would be FooInfo.Print
Casey
ActiveRecord pattern (object with data and logic) is different from n-layered architecture (DAL, BLL, UI + DTO) that you mentioned in the original question. That's why you're running into problems. Statelessness of the service also helps concurrent usage.
eed3si9n