locked
Best Design approach for Business Logic Layer Classes in an N Tier Architecture RRS feed

  • Question

  •  

    Hi All,

     

    I have few questions here related to classes design. I am in fix what method we should keep in Business entity/Factory/DAL  classes.

     

    1) We have a customer class. Should we define Save method in Customer class or we should create a CustomerFactory Class to define all methods related to customer or it should be placed in DAL.

     

    2) Customer can have multiple bank accounts and credit cards.

       Do we need to create classes for bank account and credit cards. If this is the case then how these classes would be related to customer classes. How credit cards and bank accounts records would be saved with help of these classes. What would be the ideal flow.

     

    Would appreciate if could suggest us best approach to tackle these OOPS concepts.

     

    Thanks & Regards,

    S.Gautam

     

     

     

    Friday, April 25, 2008 10:28 AM

Answers

  • I would say there are a couple obvious ways you can save a Customer, whether it is through a DAL (as you mention) that accepts a customer object to operate on, or customer itself has a save method, and using strategy pattern with dependency injection, the customer knows at runtime how to save itself. 

    For accounts and cards, I would suggest you  flesh out your business domain and then the class hierarchy. Most likely you would suggest separate classes, most likely even class hierarchies for each. For example, there is baseaccount which may have just an identifier, and that account could be a checking account or a savings, and could allow certain privileges related to demanding deposits, etc. You need to flesh these out in case your system needs to change in the future. Same goes for cards, at the base there is a card with some basic characteristics, and then different varieties, debit, credit which may be related to which accounnt types can have those cards. I would suggest using interfaces so you can clear up the distinction from how these entitites are used versus how they are implemented.
    Friday, April 25, 2008 2:55 PM
  • Hi

     

    Personally I facor the DD aproach over the Active Record stuff..
    so I would go for a CustomerRepository that allows you to save, load a customer

    this repository belongs in the DAL (or rather is the public interface of the DAL)

     

    If you have some logic regarding the Bank account and credit card (such as validity of bank account number, expiration dates and so on) you should definitly create  custom classes for those items.

     

    Next up you need to tackle the subject of ownership.  The question here becomes: can you save a bank account or a credit card itself, or do you need to go via the customer.  If an object can be saved by itself, it basically needs a repository.

     

    Hope this helps you out

    Saturday, April 26, 2008 6:25 AM
  • Hi Sameer,

    I'll tell you my thoughts based on my personal experience. Take those at your own discression

     

    1. I wouldn't put the Save() method on Customer class itself. I see domain entities better playing the role of data transfer objects (across layers) with very little behavior (mostly to update internal data, will talk more about this later)
      So to save a customer instance (same for retrieving it and any other CRUD operation) what I'd do is having a Data Access Object (DAO) in the Data Access Layer to close the CRUD gap (just in case, CRUD stands for Create-Retrieve-Update-Delete or their associated SQL commands, respectively INSERT-SELECT-UPDATE-DELETE, apparently CRUD sounded better than ISUD )
    2. About relationships between classes, if Customer has Accounts or CreditCards, I'd still delegate to the Customer DAO (which possibly may delegate to an Account DAO or a CreditCard DAO, don't want to answer here whether should or shouldn't be the case) storing that info
      What is likely to happen, depending on business rules, is that if invalidating a customer (i.e. the customer stops being so) implies invalidating all his/her accounts, credit cards, I still wouldn't change accounts/credit cards state thru the customer objetct but actually a business-layer level object reflecting the use case of invalidating a customer should -in my opinion- take over the situation, by getting all customer accounts, credit cards and setting the status to "closed", "cancelled" or whatever

    Hope that helps

    Tuesday, May 27, 2008 7:59 PM

All replies

  • I would say there are a couple obvious ways you can save a Customer, whether it is through a DAL (as you mention) that accepts a customer object to operate on, or customer itself has a save method, and using strategy pattern with dependency injection, the customer knows at runtime how to save itself. 

    For accounts and cards, I would suggest you  flesh out your business domain and then the class hierarchy. Most likely you would suggest separate classes, most likely even class hierarchies for each. For example, there is baseaccount which may have just an identifier, and that account could be a checking account or a savings, and could allow certain privileges related to demanding deposits, etc. You need to flesh these out in case your system needs to change in the future. Same goes for cards, at the base there is a card with some basic characteristics, and then different varieties, debit, credit which may be related to which accounnt types can have those cards. I would suggest using interfaces so you can clear up the distinction from how these entitites are used versus how they are implemented.
    Friday, April 25, 2008 2:55 PM
  • Hi

     

    Personally I facor the DD aproach over the Active Record stuff..
    so I would go for a CustomerRepository that allows you to save, load a customer

    this repository belongs in the DAL (or rather is the public interface of the DAL)

     

    If you have some logic regarding the Bank account and credit card (such as validity of bank account number, expiration dates and so on) you should definitly create  custom classes for those items.

     

    Next up you need to tackle the subject of ownership.  The question here becomes: can you save a bank account or a credit card itself, or do you need to go via the customer.  If an object can be saved by itself, it basically needs a repository.

     

    Hope this helps you out

    Saturday, April 26, 2008 6:25 AM
  • Hi Sameer,

    I'll tell you my thoughts based on my personal experience. Take those at your own discression

     

    1. I wouldn't put the Save() method on Customer class itself. I see domain entities better playing the role of data transfer objects (across layers) with very little behavior (mostly to update internal data, will talk more about this later)
      So to save a customer instance (same for retrieving it and any other CRUD operation) what I'd do is having a Data Access Object (DAO) in the Data Access Layer to close the CRUD gap (just in case, CRUD stands for Create-Retrieve-Update-Delete or their associated SQL commands, respectively INSERT-SELECT-UPDATE-DELETE, apparently CRUD sounded better than ISUD )
    2. About relationships between classes, if Customer has Accounts or CreditCards, I'd still delegate to the Customer DAO (which possibly may delegate to an Account DAO or a CreditCard DAO, don't want to answer here whether should or shouldn't be the case) storing that info
      What is likely to happen, depending on business rules, is that if invalidating a customer (i.e. the customer stops being so) implies invalidating all his/her accounts, credit cards, I still wouldn't change accounts/credit cards state thru the customer objetct but actually a business-layer level object reflecting the use case of invalidating a customer should -in my opinion- take over the situation, by getting all customer accounts, credit cards and setting the status to "closed", "cancelled" or whatever

    Hope that helps

    Tuesday, May 27, 2008 7:59 PM
  •  

    Thanks Diegum for your reply.

     

    How do you see the following approach.

     

    1.Enterprise Library data block would be taken as Data Access Layer.

    2.Business Logic Layer would be divided into two layer one for BusinessEntities another is BusinessLogic.

    3.CustomerEntity Class woud be in BusinessEntities Layer.

    4.All CRUD methods would be defined in CustomerBusinessLogic class in BusinessLogic Layer.

     

    Following would be High Level Diagram

     

    -----------------------------------

    Prensentation Layer     |

    -----------------------------------
    Business Entities Layer|

    -----------------------------------

    Business Logic Layer   |

    -----------------------------------

    Data Acess Layer         |

    -----------------------------------

     

    Regards,

    Sameer

    Wednesday, May 28, 2008 12:52 PM
  • Sounds like the approach you're taking is to have your "BusinessLogic" layer act as an Object/Relational Mapping (ORM) layer. A DD model combined with ORM is a great approach to take.

     

    Have you considered using an ORM framework such as Spring.NET (comes coupled with NHibernate), Castle.NET or LINQ? Using one of these will save you a substantial amount of time in development and testing, along with providing other advantages. 

     

    For custom ORMs I've built in the past they have taken some time to design and build correctly. Especially when you want some of the more complex features that the frameworks out there already give you ... for free.

     

    Wednesday, May 28, 2008 7:58 PM