Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Help with seeming contradiction of two concepts - oop and n-tier development

Not so Newbie to oop here, but still making the transition from structured programming. I'm trying to reconcile the concept of a self contained object with n-tier programming. Seems to me you can have one or the other but not both.

Please tell me where I am going wrong here with n-tier-architecture. Say I want to work with a bunch of People. I create a 'Person' class in an Entities Tier with FN, LN, BDay, etc. I will use this Person class to represent one person in my all the layers -UI, Business and DataAccess. But I generally can't put any useful methods into 'Person' because then I will be crossing over tier boundries.

So I end up creating a UiPersonClass, a BusinessPersonClass, and a DataAccessPersonClass each with a 'Person' class member. Then I end up creating a constructor for each tier class the accepts a 'Person' class parameter (coming from the other layers) and sets it to this.Person. And I new up a adjacent layer PersonClass with this.Person as a parameter. etc.

This feels really wrong, but how else are you supposed to do this?

If I was using one layer only, I could have a 'Person' class with methods that populate ui controls, process the info, and save and retrieve data from the database, all in one place, all in one "Object" .

like image 936
TheMoot Avatar asked Jan 19 '11 19:01

TheMoot


2 Answers

One of the problems that I had when first learning Object Oriented Programming was that the examples shown to illustrate concepts were so basic that they made no sense.

Why add piles of seemingly needless complexity when there were much easier and more straightforward ways to program solutions? Why code interfaces that didn’t seem to add anything but more programming work and confusion? Why create multiple Layers when all I was doing was passing unchanged values down the chain?

A lot of it started to make sense when I started doing things that were more complicated. In the case that you give here it seems that the data does not change as it is passed from one layer to the next. So having multiple layers doesn’t seem to make sense. However, imagine a more usual scenario where the way your data is stored in the database does not match what is displayed in the UI.

Then the example you give is not so straightforward.

I find it helps to think of it this way: The BusinessLayer translates between the data in the database and the data in the UI.

I usually have a basically one to one correspondence between the data in the database and the objects which are created in the DataLayer and passed back and forth to the BusinessLayer.

I have a basically one to one correspondence between the data that is passed back and from the BusinessLayer to the UI and what is displayed in the UI.

Those objects are usually very different.

The BusinessLayer is where the translation happens. This is whether retrieving data from the database to display in the UI, or collecting data entered in the UI and storing it in the database.

When things start to get complicated, it turns out is is much easier to do things this way. Especially when changes are made to the application

like image 108
Lill Lansey Avatar answered Nov 13 '22 16:11

Lill Lansey


In my opinion your first concept about having a Person class to be shared between layers is correct. You can abstract it a little bit more to, say, add an interface IPerson so that any object representing a Person will implement this interface.

As for the separation in the layers goes, I do not think that you should have a BusinessPersonClass and a DataAccessPersonClass. Instead I believe you should aim for the following: Your business layer will operate on IPerson type: it does not care if the object is of type Person or Salesman for example, it just knows that it expects an IPerson type of object. Moreover, the business layer is where all the business rules go (naturally) - validation, etc. Those business rules I believe should not be a part of the Person object. In fact the Person object should only be concerned with atomic operations and properties of one person - in other words it should not contain any business or data access logic.

Same goes for the data access layer -- it operates on IPerson, returns IPerson(s), modifies IPerson(s). The data access layer is only concerned with CRUD operations, or how does it add,get,update, delete an IPerson from/to the data source.

Now with the UI, I think it is a little bit more different. There normally you would implement your ViewModels (UIModels) and some simple validation rules (not concerning business logic but validity of input). I can think of two approaches here:

1) Every UI view model concerning a Person implements IPerson. In that way you ensure consistency over the tiers and you can easily work with this data.

2) Every UI view model contains a property of type IPerson (as you specified above). This is also a nice approach in my opinion because it makes it easier for communication between the UI and business layer.

In summary, here is what I think:

UI layer Has a reference to a IPerson in some way or the other. Implements basic validation rules -- validity of input (is the inputted Email really an email). Then, the UI passes this IPerson object to the business layer for the business rules and operations.

Business layer Takes an IPerson object, validates it using business rules (does this email already exist in the system). Performs some more business layer operations, may be, and calls the data access layer, for example, to create an entity. In this example the business layer will call a Create function and pass it an object of type IPerson.

Data access layer CRUD operations on atomic entities - IPerson, IProduct, etc.

Hope this helps.

like image 38
sTodorov Avatar answered Nov 13 '22 17:11

sTodorov