3
votes

I realize there have already been a number of posts on n-tier design and this could possibly be me over thinking things and going round in circles, but I have myself all confused now and would like to get some clarity from the community please.

I am trying to separate a project I created, (and didn't design architecturally very well to start with), out into different layers (each in their own project):

  • UI
  • Business Objects
  • Logic / Business
  • DAL

The UI should only call the Logic layer to get its stuff

The Business Objects should not call or have references to anything else, just be a way of storing the data

The Logic / BUSINESS layer should hold all of the methods to get, create, update, delete (CRUD) objects in the system and would have references to both the BO and the DAL. It would apply the business logic to the operations then delegate the actual CRUD to the DAL.

The DAL would just do the CRUD operations on the DB. It would have a reference to the BO's as it would return them for the Gets etc.

My question is should the Logic classes only call their equivalent DAL class and just call logic classes instead? In other words, CompanyLogic class should only call CompanyDAL class. So if it wanted to get A Client object by ID it would call ClientLogic.GetClientByID(int) rather than the ClientDAL.GetClientByID(int).

The reason I thought it maybe should stay on the its own layer was that:

  1. It would seem to loosen the coupling between projects

  2. What about the Logic, if getting a client object had some logic validation in it (possibly not the best example, but hope it gets the point across).

EDIT:

I am not sure if it is bad design by me but at the moment the BUSINESS layer has a number of classes including ClientBULL and CompnayBULL, both classes have a call to one another. I use an interface for each class and have a factory to build the objects to try and reduce any coupling but they can not exist without each other now due to calling methods in both classes. Is this a bad idea?

1

1 Answers

4
votes

Well, here's my comments on your design:

  • Logic is a bad name for what essentially is a layer assigned to abstract persistence. I would probably call it "Repository" or "Persistence" or DAO (data access objects) instead of "Logic", which is ambiguous and could absolutely mean anything.

  • If you really want to decouple your business layer from your DAL, your Logic layer should only accept interfaces to the DAL, and not concrete DAL classes.

  • There are two schools of thought as to where validation should reside. Some are completely fine with validation sitting at the UI layer; others would rather throw exceptions or pass messages from the business layer. Whichever way you go, just be consistent, don't duplicate validations in multiple places, and you'll be fine.

  • Go ahead and try coding it would probably be the best piece of advice I could give you. It's well and fine thinking it through, but at one point you'll need to see it while you're coding it and only then will subtle quirks and pitfalls reveal themselves. Whatever prototypes you can come up with will definitely be valuable to the direction your development and design takes you.

Goodluck!

Update

Re your edit: Within the same namespace or assembly, calls to concrete classes are definitely fine. I think it will be overly convoluted for you to need to put up interfaces for business logic -- I mean is there more than one set of rules you should follow?

I'm a believer of keeping things simple and following YAGNI. Don't make an interface until there are more than two classes that are going to implement/already implementing that interface (the DAL is always an exception to this though).