views:

331

answers:

2

I started my website, like stackoverflow, with a little technical debt that I'm trying to pay off. Being a contract developer, I've been in many places and see many different methods of achieving this result, but the way I'm going is..

Presentation (web)

Business Layer (old fashioned entity classes and BL layer)

Data Layer (DA classes to SQL Server via Stored Proc)

My question primarily concerns the Business Layer. Right now I have an Entity namespace and a BusinessLogic namespace.

The BL has a reference to the DA and the Entity. The Entity has a reference to the DA (The DA is "unaware" of the BL or Entity)

I really want all my churning of turning Data into Entities to occur within the BL -- thus the Business Logic. However, I want the Entity to be able to access the BL if need be -- and thus remove the Entity's reference to the DL.

So...

Is is "wrong" to have the BL and Entity objects within the same namespace so they can work together?

Essentially, I'm trying have an entity object like Employee (classic example, eh?) and have the Employee have a

public Hashtable[] SubordinateEmployees

property that returns a Hashtable of other Employee objects that report to this employee. But I don't want to load it until it's needed. So for most employees the property would never get accessed, but when it does, it self-loads with a call to the BL, which calls the DA.

Does the question make sense?

If so, does my solution?

Thanks so much in advance!

+2  A: 

The usual way to deal with the kind of situation your example represents is with facades. Instead of trying to get the subordinate employees from the Employee object, you use a call to the business logic to get it.

hashtable = BL.GetSubordinateEmployees(supervisor);

That way you have a single point of access to the subordinates, and there is only one thing (the BL) accessing the data layer and creating Entities.

Welbog
My concern with this is that I wanted them all bundled together into a single object. This allows for recursion, etc. if needed. Like navigating up and down an org chart. Otherwise I either have to maintain two objects or have my code fetch both and then store the hashtable into a writable prop.
peiklk
You can do it that way, but you'd be exchanging the convenience that recursion brings for a higher degree of coupling. Instead of having the UI depend solely on the BL, now you have the Entity objects encroaching on BL's role. It will make things harder to change in the future. It's a trade off.
Welbog
Ultimately it's up to you, but the majority of the time you're going to want to avoid coupling as much as possible.
Welbog
+2  A: 

Let me see if I can show you a better way to think about this

you have your data access (sql server, mysql, flat xml files, etc.) all of this should be abstracted away nothing else in your application should care or know how you are getting your data, only that it dose, if anything else knows how you are getting your data you have a layer violation. if the DAL dose anything other then get data you have a layer violation. Next you implement a data access interface something like IDAL that your business layer uses, this is very important for making your code testable by forcing you to separate your layers.

Your data entities can be placed in the DAL name space or give them there own, Giving them there own forces separation. Data entities are dumb objects and should contain very little to no logic and are only aware of themselves and the data they have, THEY DO NOT CONTAIN BUSINESS LOGIC!, DATA ACCESS LOCIC, OR UI LOGIC. if they do you have a layer violation. The only function of a data entity is to hold data and be passed from one layer to the next.

Biz layer implements a data access interface like the IDAL we talked about before you can instantiate this with a factory, an IOC container, or all else failing a concrete type, but add a setter property so this can be changed for testing. The Biz Layer Only handles Business logic, it doesn't know or care where the data came from or where it's going, it only cares about manipulating the data to comply with business rules, this would include date validation, filtering (part of this is telling the DAL what data it needs, let the DAL figure out how to get it). Basically the BIZ handles all logic that isn't UI related or Data retrieval related. Just like the DAL the Biz should implement an Interface for the same reason.

The UI layer Accesses the Biz layer the same way the Biz layer accesses the DAL for the same reason. All the UI layer cares about is displaying data and getting data from the user. The IU Layer should not know anything about the business rules, with the possible exception of data validation required to populate the Data Entities.

The advantage of this architecture is it forces separation of concern making it easier to test, more flexible, and easier to maintain. Today you are building a web site but tomorrow you want to allow others to integrate vi a web service, all you have to do is create a web service that implements the IBIZ interface and your done, when you have to fix a bug in the BIZ layer, it's already fixed in both your website and web service.

Taking this to the next level, lets say you are doing a lot of heavy number crunching and you need more powerful servers to handle this so all you have to do is implement an IDal and IBIZ interface that are really wrappers to WCF that handles the communication between your servers, now your application is distributed between multiple server and you didn't have to change your code to do it.

Bob The Janitor
So UI talks to BL which talks to DAL which talks to DA. BL returns Ents to the UI and the Ents contains nothing but data. No logic or anything. But if the UI is populating itself with the data in the Ents, then it seems reasonable that the Ent should do work like LastName + ", " + FirstName, etc
peiklk
Kinda, Entries do work with there Data, for example I have a collection Data Entity with an AddNonDuplicate method that takes the same type of collection checks to see which are unique and only adds the unique items, but they should not do something like create HTML, that's a UI responsibility
Bob The Janitor