Design – Business Logic vs Presentation/View Logic

designlayers

I often question myself of where to put the logic that organize the data to a view that is not necessarily a business logic in a 3-layered architecture (DAO, Business, View).

I'll put an example to be clearer:

I have a UI in my aplication that shows pending tickets and answered tickets in two different tabs. To get the data from the database, I make a single query. Since there is no business logic, I'm returning the whole list to the Controller (View) and separating it in two lists to pass to the view template.

Should I be separating this in the business layer? Or is it correct to separate in the controller, since the logic is attached to that single UI?

Best Answer

I like where you are going with this curiosity, so I'm going to bring up something else I see.

To follow not only "Separation of Concerns", but also "Persistence Ignorance", it is almost always a Very Bad Idea to allow your UI layer to call into your business/data side with a "Get All" (Or even close) method. I realize there may be a constraint or two like Where UserId == LoggedInUser, but that is still too close.

The reason being, suddenly you have clever UI Developers using the "Get All" method, and performing business/Data-Access logic on the UI to separate out information, pick and filter through, etc.

Even if you tell yourself that will never happen, or that you're the only one in the next 100 years that will touch this code and you Promise yourself you'll never do that, you still shouldn't open the UI up to such power.

Now imagine some time in the future a single UI Control needs to display JUST the Answered (or pending) tickets. What do you do now? You have to "Get All" and perform your filtering logic on the UI side?

I wouldn't even put that into the Business Logic. This is about data separation. You should have as finite queries as possible in your Data-Access layer, and expose only those required results to your Business Logic. Your Business Logic in this case may just be a wrapper to return a Data-Access result, but that's okay. That's the BLL's responsibility to determine the Persistence object and route calls.

Now, if you need a list on your UI side that shows "All" Tickets for a user, it may be prudent to have that "Get All" method where the only filter is the UserId. However, it may be more prudent to combine the Pending and Answered Queries. Why?

What if in the future you add a "Deleted", "Removed", "In-Flux", "New" or any other kind of status? Now you have to re-write code because all you wanted to do is show a Combined List of Pending and Answered questions.

So give your UI less control over massive lists, and instead allow it to pull back only the limited information it needs, and alter/combine from there.