Properly BL abstration with LLBL

Posts   
 
    
Anderskj1
User
Posts: 33
Joined: 11-Jan-2005
# Posted on: 26-Apr-2005 21:22:14   

[EDIT: I just saw the thread: LLBLGen Examples to include a Business Logic Layer" from a couple of days ago. But actually still wants a little help since i dont think it completly answers how to save entities in a maintainable way]

Hi we are developing an intranet application and choose Self serviceing model since we were convinced that the application would be minimal. But as often seen before its growing and our BL model is slowly falling apart. We need your advice /experience to restructure our code abit.

We are developing in ASP.NET and at the moment we have the Business methods on the entities them self.

Eg. on a OrderEntity we have

public static OrderCollection GetOpenOrders() { ..... OrderCollection col .... return col; }

This worked ok. But then when we eg. wanted to add a user to the database we needed to create a UserEntity (with 20 fields) and a AddressEntity (with 18 fields).

One solution is to add a static method AddUser(string p1, stirng p2,p3......p3sunglasses on eg UserEntity...but of course no. The other solution was to use the UserEntity and AddressEntity as DTO's and send them filled to a BL. But again. The only action in the BL (since selfservicing) was often just to call save();.

So now we are actually creating such entities directly in the events in the codebehind which of course is ugly as hell but no other solutions seemed functional at the end of the day. And things are geting even more horrible when we need to use transactions.

How do you structure a Self servicing architecture which has acceptable abstraction. We dont want to be able to switch O/R by using extensive layering just a maintainable design since we are sure we stick to LLBL.

Looking very much forward to your comments! /Anders Jacobsen

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 26-Apr-2005 23:39:07   

Hi, Anders. There's really two issues apparent in your questions: the first is, "What is the ideal architecture for my project", and truly, the second is, "Which LLBLGen scenario bests fits my chosen architecture".

It's hard to answer your first question without really knowing your project, but the two main approaches mentioned in these forums are the Domain model and the Manager model. Searching either of those two terms will give you a wealth of information.

You need to go with what works for you, but the problem to understand is that the farther up the application you go (in terms of functional layers) the less relevance the entities have to the function at hand. For example, in the GUI, the data you need to display and take in from the user may not map 1:1 to a given entity hierarchy. Using the entities as business objects in the GUI is not always the best solution due to the fact that your business behavior is then intrinsically linked to data objects that may have little relevance to what you're trying to do. These business objects may be formed from the instructions created by the GUI, but aren't always effective directly in the GUI.

While this may not be a possibility for your project at this point, I highly recommend you switch to the Adapter scenario. While the short term impact on productivity can be significant, the long term benefit of good lines of abstraction will be worth the effort.

The "problem" (if you can call it that) with Self Servicing is that the persistence information is built into the entities themselves. Thus, while you may wish to hand off a Save operation to a BL, there would be truly no way to prevent the GUI from calling Save directly on the entity itself, bypassing any business logic you have created in your BL. Using Self Servicing effectively limits your architectural choices but with the benefit of greater short term productivity.

In direct answer to your questions, here's my thoughts:

If you're bound to Self Servicing, then use the entities to pass parameters to the business methods you have located on the entities themselves. Don't use parameters. This is personal preference, but it's what I suggest.

Don't bother with a business logic layer that saves entities. As the Self Servicing entities themselves can be saved directly, it's a waste of time passing the entities to another layer just to save them. The other, more abstract, thought here is that when you are saving entities, you are actually performing a discrete action, "New Order", "Update Order", "Delete Order", etc, which IMO is better served by having those explicit actions available in a business layer somewhere, not wrapped up into a generic "Save" action in the entities themselves. But again, Self Servicing prevents this...

Create a UI services layer that can handle fetches for you. This has three benefits. One is that you can centralize your fetch logic, and the second is that it allows you to use prefetch paths more effectively for group fetches. Yes, you can do this in the entities themselves, but bypassing the UI services for fetches is IMO much more tolerable than bypassing the BL for saves/persistence. The third benefit is that this sets the stage for a move to Adapter, when/if you deem it necessary.

Move to Adapter. simple_smile I honestly think that what you're trying to accomplish is best served by switching to Adapter. I personally found that switching to Adapter resulted in a much cleaner architecture that handled very well the problems you mentioned like persistence, business logic, and abstraction. Again, it is more work up front, but I think you'll be pleased by the resulting code.

Jeff...

Anderskj1
User
Posts: 33
Joined: 11-Jan-2005
# Posted on: 27-Apr-2005 00:29:35   

Good thougts. I would say that it would be a hard if not overwhelming action to switch to adapter. But as you point out there is problably no clean way from here, if we continue witth Self selfservice.

My hope was that you somehow could create a well-designed n-tier with SS. I have realized this doubltly will never happen.

Anyway thanks for you answere. It was helpfull indeed. I will look manager up right away.

Regards Anders.

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 27-Apr-2005 02:18:28   

Anderskj1 wrote:

Good thougts. I would say that it would be a hard if not overwhelming action to switch to adapter. But as you point out there is problably no clean way from here, if we continue witth Self selfservice.

My hope was that you somehow could create a well-designed n-tier with SS. I have realized this doubltly will never happen.

Anyway thanks for you answere. It was helpfull indeed. I will look manager up right away.

Regards Anders.

Hi, Anders. Glad I could help. I do want to stop short of saying you can't build a good layered architecture with Self Servicing, only that Self Servicing limits your choices. There are some things you can't do with SS, such as abstracting the persistence logic away from the entities themselves, but that doesn't have to impact everything.

I invite others to contribute their thoughts on design using Self Servicing here... simple_smile

Jeff...

Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 27-Apr-2005 03:11:49   

jeffreygg wrote:

I invite others to contribute their thoughts on design using Self Servicing here...

I created one project using self servicing, and its been adapter ever since.

I have never worked on a project where requirements didnt change. Everytime I turn around I hear, "do you think we can .... do this...", or "wouldnt it be cool if....", so I basically decided that adapter gives the most robust feature set, abstraction, and flexibility, and that it would be the way to go from here on out.

IMO, 98% of the time you should opt to isolate definition from implementation, and thats what the adapter does.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39750
Joined: 17-Aug-2003
# Posted on: 27-Apr-2005 10:58:47   

jeffreygg wrote:

Anderskj1 wrote:

Good thougts. I would say that it would be a hard if not overwhelming action to switch to adapter. But as you point out there is problably no clean way from here, if we continue witth Self selfservice.

My hope was that you somehow could create a well-designed n-tier with SS. I have realized this doubltly will never happen.

Anyway thanks for you answere. It was helpfull indeed. I will look manager up right away.

Regards Anders.

Hi, Anders. Glad I could help. I do want to stop short of saying you can't build a good layered architecture with Self Servicing, only that Self Servicing limits your choices. There are some things you can't do with SS, such as abstracting the persistence logic away from the entities themselves, but that doesn't have to impact everything.

I invite others to contribute their thoughts on design using Self Servicing here... simple_smile Jeff...

It's easier to write code for selfservicing stuck_out_tongue_winking_eye

Both have their place, sometimes selfservicing is easier, as a full 3-tier layered application isn't that required, for example when you decide it's ok to fetch data in a code behind file (don't say that's bad, if you're calling a BL method just to do that and it's never re-used, you created extra code for no reason. Sometimes it's not that required to add an additional BL tier).

When I have to write an app which simply talks to a db and does some simple stuff, I always pick selfservicing. But when I need a 3-tiered approach, I mostly pick adapter, as the abstraction in the PL is there out of the box: I don't have any Save etc. logic available in the PL, I can only call down to the BL, which is preferable in these scenarios.

Frans Bouma | Lead developer LLBLGen Pro