views:

73

answers:

4

i have a data access layer that abstracts the rest of the application away from the persistence technology. Right now the implementation is SQL server but that might change. Anyway, i find this main data access class getting larger and large as my tables grow (about 40 tables now). The interface of this data access layer is any question you might want to get data on

 public interface IOrderRepository
 {
       Customer[] GetCustomerForOrder(int orderID);
       Order[] GetCustomerOrders(int customerID);
       Product[] GetProductList(int orderID);
       Order[] GetallCustomersOrders(int customerID);
       etc . . .
 }

the implementation behind this is basic SQL stored procs running the appropriate queries and returning the results in typed collections

this will keep growing and growing. Its pretty maintainable as there isn't a real break of single responsibility but the class is now over 2000 lines of code.

so the question is, due to sure class size (and no real conceptual coupling), should this get broken down and if so on what dimension or level of abstraction.

+1  A: 

I think it should be factored just because of the size. There are always lots of dimension on which you can break it down. Since the breakdown is simply to make the code more manageable, don't choose too complex a dimension - keep it simple so that it is easy to guess in which class/interface a given function will be found.

Larry Watanabe
+1  A: 

This is a hard problem to crack .... firstly break it into multiple files and classes, and secondly split the business objects from the technology object; you can write your business objects in terms of a database interface (which you write yourself). and then in the future if you change DB all you need is to replace the technology object.

Sadly You can't really escape from data-schema growth, you will get more stored-procedures, more tables and more business objects. However, try your level headed best to alter rather than add new tables.

I suggest trying to form a workflow of coupling items them together as resources. By this I mean not making physical dependencies but documentation that will let you relate all the three types of items in you data layer -- e.g.., you could start putting annotations in the comments of your business objects to specify which stored-procedures and tables it depends on. You could do this for the stored-procedures even in the tables in SQL Server (the schema has a description field for tables). These tips should help you keep sight of the big-picture.

Hassan Syed
Please do NOT 'try [..] to alter rather than add new tables'. Many table aren't a problem. If you need one create one.
Jens Schauder
I am not suggesting throwing away common sense -- consider the following two points: Firstly, A crusade of normalization can be bad, both for clarity and performance of a data model. Secondly, I have seen many programmers create new tables for types which can be elegantly unified into a single data structure (table).
Hassan Syed
A: 

Consider a generic DAO if your language accomodates them. You might also think about query by example to cut down on the number of calls required.

duffymo
+2  A: 

Absolutely refactor. 2000 lines is huge.

I'd start by breaking it down by return type. Thus you would get one class for accessing Products, one for Orders, one for Customers and so on.

For each of the class, the set of columns selected should probably the same, so that could get refactored into a single variable/method as the extracting of the SQL values into objects.

Also the actual call to the Stored Procedure, including logging and exception handling could and should go into a separate class.

BTW you do have a violation of single responsibility. According to your description your class right now has the following responsibilities:

  • create sql statements for querying a table (about 40 times)
  • hydrating the results of calls to stored procedures
  • calling stored procedures

And I am assuming - logging - exception handling

Jens Schauder