Sunday, July 19, 2009

N-Tier Design Revisit part 2 – Data Entities

Entities are unique in N-Tier, they are the only thing that is used by every level. In my original N-Tier entry I stated that it’s was ok to put your entities in your Data Access Layer (DAL), this is a very common practice with a lot of Object Relational Mappers (ORMs), some will even generate your entities from your data base (subsonic, Entity framework, etc.). The reason I dislike this is you are making your DAL a dependency in every layer of your application, further more if your using something like subsonic to generate your data entities you are tightly coupling your database design to everything. I would strongly encourage you to place your data entities into a separate project, the main focuses here is to decouple your application, the less any one part of your app knows about any other part the better.

It is my firm belief that Data Entities should contain data and have very little too no logic, and what logic they do have should only relate to manipulating themselves they are dumb objects, 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 nothing more! Here is a code sample for a data entity

   1: public class Customer
   2:     {
   3:         public int Id { get; set; }
   4:         public string FirstName{get; set;}
   5:         public string LastName { get; set; }
   6:         public string Company { get; set; }
   7:         public string Email { get; set; }
   8:         public string Phone { get; set; }
   9:     }

It’s really nothing more then a data structure, but what data you put into your entities is also important, if you have a property called company logo, that has a value like “/images/logos/customer12.png” you have a problem, now every layer has information about your UI, a better solution is to only store the “customer12.png” value and let the UI figure out how to display it.

For entities I usually create a collection object named the plural of the class it holds. The code looks something like this.

   1: public class Customers :Collection<Customer> {}
I personally like using generic collections as a base class, it makes a strongly typed, fast, and with only one line of code easy, collection object. I have everything I need baked in, with the possible exception of the ability to add collections, but with a little refactoring this is added

   1: public class Customers :Collection<Customer>
   2: {
   3:     public void Add(IEnumerable<Customer> newCustomers)
   4:     {
   5:         foreach (Customer customer in newCustomers)
   6:         {
   7:             Add(customer);
   8:         }
   9:     }
  10: }

if you noticed I use generic IEnumerable<Customer> this way I can add any collection that implements IEnumerable, this could include: another Customers object, a List<Customer> , etc. As with the single entity the collection should have limited logic and what logic it has should only deal with managing the items it holds.

Technorati Tags: ,,

No comments: