what Pattern for that situation?

  • Thread starter Thread starter Mariano Drago
  • Start date Start date
M

Mariano Drago

Hi there.
I have 4 classes:
CustomersCollection
Customer
ProductsCollection
Product

Both "collections" have an ArrayList and a method to "add" a Customer or a
Product respectively to the collection.

The Customer class internally has a ProductsCollection, so i can access the
products that this customer has buyed. That ProductsCollection is
automatically populated from the Customer constructor.

So, if i wanna get the products that a Customer buyed:
foreach(Product prod in customer.ProductsCollection) {
write(customer.Name + " has buyed " + prod.Name);
}

The problem im facing is that in a certain point i want to know what
customers have buyed a given Product. In the example above, i am inside the
loop with a "prod", i want to have something like
foreach(Product prod in customer.ProductsCollection) {
write(customer.Name + " has buyed " + prod.Name);
foreach(Customer cust in prod.CustomersCollection) {
write(prod.Name + " has been buyed by " + cust.Name);
}
}

wich i can resolve simply adding a CustomersCollection to the Product class,
but i will enter in an infinite loop of initialization, supose:
CustomerCollection CC = new CustomerCollection();
CC.Add(new Customer(1));

Customer constructor will hit de DB and retrieve customer info and products
info asociated to the customer. For each product retrieved from the DB
Customer class will internally add it to the ProductsCollection, and here
comes the loop, because the new product added (Product class) will try again
to create a CustomersCollections class of customer that buyed it, and that
customers will try to retrieve products... and so on.

Workarounds i have found are:
1) passing a boolean to the Customer constructor telling to populate or not
ProductsCollection
2) adding some variable like "belong_to" in both Customer and Product to see
if a population is needed.

Both workarounds are far from elegant, and since the problems looks very
simple, i hope someone have created some kinda pattern to resolve it.

I have see that VS "watch variable" presentes information that expands and
expands and expands and even "loops" itself, how they do that!!! ???

Thanks in advance and excuse my poor english.-
 
Mariano,

For this situation, I think that the best solution is to get all the
customers, then all the products, and construct your instances, not setting
the relations. Then, get the relations between the two (customers to
products, and vice versa). Cycle through each of the collections separately
(customers and products), linking up both of them.

Hope this helps.
 
Thanks for your reply Nicholas.
Anyway, i will try to find some kind of pattern to resolve the situation.
Its a pretty common problem and there must be a way.
Thanks again.-
 
Mariano,

You should be able to do it the way I said. Basically, don't set the
relations between the objects until you have all of the other information
about them loaded. Then, set the relations in a routine external to the
objects.
 
Mariano:

I have a different idea. I think your mistake is to "automatically populate"
your custom collections on instance constructor. It's better populate "on
demand" using Lazy Initialization Design Pattern. Singleton (GOF) use it.

Example code:

class CustomersCollection{
//fields
private ProductsCollection _products = null;

//constructor
CustomersCollection (){
//Populate();
}

//property
public ProductsCollection Products{
get {
if (_products==null) {
//it only populate once
Populate();
}
return _products;
}
}
}

Luis Carlos
 
Back
Top