Search code examples
iphoneobjective-cclassoopooad

Database layer design


I have design level question in one of my project.I'm working on a project in which I need to fetch some objects using REST. Say for example fetch Customers and show it in a list.

Following operations that can be done on Customer,

  • Adding a Customer
  • Editing Customer details
  • Delete Customer

So I thought of including a Class named 'CustomerManager', included following methods,

  @interface CustomerManager
  - (CustomerManager *)sharedManager;

  - (BOOL)addCustomer:(Customer *)customer;
  - (BOOL)deleteCustomer:(Customer *)customer;
  - (BOOL)updateCustomer:(Customer *)customer;

  @end

  @implementation CustomerManager

   - (BOOL)addCustomer:(Customer *)customer;
    {
       NetworkManager  * manager = [NetworkManager manager]     addCustomer:customer ];
    }
   @end

In the ViewController where ever I need to perform customer related operations, I used to make it like this,

 Customer * manager = [Customer sharedManager];
 [manager addCustomer:customer];

 //fetch customer
 [manager customers];

 //While deleting
 [manager deleteCustomer:customer];

Everything is looking and working fine, until I get a design level question, why there was a manager in-between . All the work was done on Customer Object, so you need to have all the Customer related operations in the Customer Class, like something below.

  @interface Customer

  + (BOOL)addCustomer:(Customer *)customer;
  + (BOOL)deleteCustomer:(Customer *)customer;
  + (BOOL)updateCustomer:(Customer *)customer;
  + (NSArray *)customers;

  @end

The problem here is , even though network related code in a separate class, I need to have a Concrete reference of my network manager in all my model classes. Confused , which one to choose.

Which was the best way?. I would like to have some detailed answer for this.


Solution

  • I don't believe there to be a correct answer here. I personally have gone back and forth on how to have my web services interact with my models. But I can provide you with a few pointers:

    1. CustomerManager is overkill. The Customer model is responsible for managing itself -- you can place Customer-related methods inside of it. You don't need a separate object here.
    2. I typically use a super-class for my models. So, for example, you could have a class called ApplicationModel which Customer and all of your other models will inherit from. This is a great way to DRY up the code in your models. If you do decide to have network-related code in your models, I would suggest placing it in this super-class. That way if you need to make changes to the way the web services work, you only need to change code in 1 place.
    3. In general, I would suggest keeping network-related code separate from your models. I like to have my networking logic as isolated as possible. Network-related code is prone to change, and you want to minimize the number of places that networking changes impact your code. For example, I usually create a class that services as an API wrapper and it gives a public interface for making API calls. This class is also responsible for parsing the responses of those methods & interfacing with the models (i.e. parsing a JSON custom array and interfacing with Customer to add those objects to the database).