views:

25

answers:

1

Hi All,

Here are my classes :

class PriceScale
-int ID
-float bookingFees
-Product product
-List<PricePeriod> periods

Class Product
-int ID
-string name
-List<PriceScale> priceScales

class PricePeriod
-DateTime begin
-DateTime end
-float price
-PriceScale scale

As you can see I strictly applied business rules "A product as many price scales, and a price scale has many period".

My problem : for instance when I'm dealing with the Product class I don't like to ask myself "Is the priceScales loaded ?" (cause I won't load it every time I need a product)

Solution :

1/ Lazy loading : I don't like it, cause you run sql query without even knowing it, and you can end up with a 1+n query problem (I'm working on the price computing system so I really need to be sure of which sql query is executed)

2/ Always load it : I don't like it, cause if I apply this logic to everything I'll end up loading the whole database.

3/ Remove the composition (ie the member priceScales),in that case what is the best way to deal with price scale :

  • get a Dictionnary<int,List<PriceScales>> where the key is the product id ?

  • something else ?

4/ Add at the beginning of my method where I need the priceScales

checkPriceScalesAreLoaded(productList);

It looks like lazy loading, but it's more explicit.

5/ Something else I didn't even think about :)

Thanks

A: 

To me this sounds like a persistence problem after all, not quite related to OOP or composition.

Are you loading your objects from a DB? If so, what language and persistence mechanism you are using? This influences possible solutions a lot.

For example with Java and Hibernate, the recommended way is to use the default lazy fetching strategy, then measure performance and fine-tune (selectively switching fetching strategy locally) as appropriate. You can switch to eager fetching, or batch/join queries, on individual mappings/properties/queries, while keeping the lazy fetching strategy on the rest.

Péter Török
I use a SQL server DB and c#.net, as I said I'd like to avoid lazy loading and in fact ORM because : this part of the system is one of the most important and I don't know how to use perfectly an ORM (such as NHibernate) to be able to avoid n+1 query, or other perf trouble (I tried it in some admin panel, but here I'm not confident enough). So if you think it's not a OOP problem, do you suggest that my class design is ok ?
remi bourgarel
@remi, yes, your class design looks basically OK from the OOP point of view. Persistence is a different issue though. I am not familiar with your platform so I can't give you much concrete advice. But in general, I believe that developing persistence for a bigger app without ORM is going to be a _lot_ of pain. So I think that investing the time to learn NHibernate or an alternative would pay back manifold over time. But others might have better ideas specifically for your platform.
Péter Török
@Peter : I disagree it's not only a persistence problem. It's also a memory problem , I don't want to put 500MB of data in memory if I want to use only 50MB. In this part of the software , SQL query is maybe 75% of the execution time so I really want to handle everything (maybe it's a common way of thinking from an orm-noob, and I'm certainly wrong about it). So I'll try to improve my knowledge about NHibernate with less important stuff, but right now I don't want to take the risk.
remi bourgarel