views:

1825

answers:

5

I'm using the following code within the JCProperty class to retrieve data from a DAL:

Dim x As JCProperty
        x = JCPropertyDB.GetProperty(PropertyID)

        If Not x Is Nothing Then
            Me.PropertyID = x.PropertyID
            Me.AddressLine1 = x.AddressLine1
            Me.AddressLine2 = x.AddressLine2
            Me.AddressLine3 = x.AddressLine3
            Me.AddressCity = x.AddressCity
            Me.AddressCounty = x.AddressCounty
            Me.AddressPostcode = x.AddressPostcode
            Me.TelNo = x.TelNo
            Me.UpdatedOn = x.UpdatedOn
            Me.CreatedOn = x.CreatedOn
            Me.Description = x.Description
            Me.GUID = x.GUID
        End If

This works fine but requires that the DAL object (JCPropertyDB) is aware of the business object (JCProperty) and I effectively create and populate the same object twice (once in the DAL to return to the BL and then again within the BL object to populate itself).

I'm missing something here, I know there must be a better way!

Effectively I need to assign 'Me = x' which is not allowed. Can someone put me straight?

+1  A: 

Not sure if this will answer your question, but the important point is that the domain model is independent of display and independent of storage. This is often denoted as separation of concerns. The idea is to get loose couplings and create a simple system where objects do not have several completely different responsibilities.
So what I would do, is to allow the DAL to create business objects directly, but make sure I don't contaminate my business objects with anything related to the DAL. Similarly I don't want to contaminate them with UI-specific things like HTML. In my opinion it's ok that both the business layer, DAL and UI-layer all have dependencies to the domain model, however it's not ok to have dependencies from the domain model and into these other components.
To loosen the couplings, using something Spring or any other Dependency injection container together with interfaces and wiring can help you.
By recreating the same object in every layer you are violating the DRY principle (Don't repeat yourself) and you are introducing boiler plate code and increasing the chance of introducing an error somewhere.

Erlend
+1  A: 

Personally, I'm lazy. I usually do something like:

class JCProperty : inherits JCPropertyDB
   {

   New()
      {
      MyBase.New()

      GetProperty(PropertyID)

      }
   }

Then you're basically done, until you have some additional functionality in the JCProperty class that needs to happen "on top" of the functionality already existing in JCPropertyDB. Then you override the JCPropertyDB methods to call the base method first then add your new functionality.

Ron

Ron Savage
Exactly what I was missing! Cheers.
Simon
+2  A: 

You are on the right lines however missing one point slightly.

Typically, your Data Access Layer (DAL) would return Data Transfer Objects (DTO) from your database. These are Plain Old CLR Objects (POCO) which contain no business logic, simply properties more or less mapping to the database tables.

You would then have code which creates a Domain Model from these DTOs, referred to as a Data Mapper. The classes in the Domain Model might have similar names (i.e. CustomerDTO -> Customer) but in addition to the data, they will contain validation rules and possibly other business logic.

It is this Domain Model that you then use in your business layer, not the actual DTOs. This means that if you change the DTOs returned from the DAL (i.e. by implementing a new ORM tool), you only have to modify your Data Mapper providing the data model stays the same.

I recommend looking at Martin Fowler's Patterns of Enterprise Application Architecture for data access patterns.

Neil Barnwell
A: 

Check out: http://www.icemanind.com/layergen.aspx

icemanind
A: 

I've been taking in BOs and sending back BOs from in the DAL via the bridge pattern and provider model. I can't see the point of DTOs unless I was fearful of heavy serialization (say a web service or JSON). My approach has been to abstract the Data-Layer and Business layer via an interface and provide an anonymous data layer fed into the business object. This means that I can plug in any data-layer, implement an interface that has universal Load and Save methods and which is then accessible via my domain layer. There is no DAL code in the BL - simply a call to a provided and abstracted data-layer. My call to the data layer is managed by a provider pattern (no direct reference) and I simply do:

public class Person : IBusinessObject { protected IDataLayer dataLayer;

Person Load() { this.dataLayer.Load(this); }

}

in the data-layer I have... public class PersonMapper : IDataLayer { Person Load(Person person) { ...get DB stuff...map to person...decorate object... return person; } }

I still don't know if this is good but it works quite well for me. I've managed to get lazy load in as well for nested objects using reflection.

Greg.

blackbean