OO design: child of multiple collections and validation

OO design: child of multiple collections and validation

Old forum URL: forums.lhotka.net/forums/t/836.aspx


AndrewCr posted on Monday, August 07, 2006

A question for the OO gurus here.  I’ve read the book, and the “Basic Concepts” thread, but I’m still struggling.

 

I’m working on a delivery dispatch system.  I have root objects representing an Order (responsibility: adds and edits a valid order) and Trip (responsibility: adds and edits a valid trip.)  These have an N to N relationship, is an order may require several trips, and a trip may carry several orders.

 

The Order object contains a collection of Stop (responsibility: adds and edits a stop) objects.  A Stop includes the information about where the stop is, what to pick up or drop off, when to be there, etc.

 

The Trip object likewise contains a collection of Stop objects, but possibly from a number of different Orders.  The Stops within a Trip are ordered in the way the truck will pick them up and drop them off.

 

The Stop objects are pretty similar, so I think I can get away with using the same object in both cases, although I’m willing do make them different if need be.  The problem is the collections.  The OrderStopCollection and the TripStopCollection have different validation logic (the Order wants to know that anything picked up has a matching drop-off, while the Trip wants to know that the Stops remain in order.)  If I edit a Stop from either collection, I need to run both sets of validation logic.

 

For example, let’s say after an order is entered, a customer calls in and changes the delivery time.  I assume I want to instantiate the Order, get the Stop and change that property.  However, if the Stop’s already assigned to a Trip, I also need to instantiate the Trip as well and run its validation.  And, to validate itself, it may need to load all the other Stops on the Trip.

 

I know all this derives from having a single object as a child of two different collections (specifically cited as “should be avoided” in chapter 6 of the latest CSLA books.)  But I can’t figure out a better way to do this.

 

Any ideas?

AndrewCr replied on Tuesday, August 08, 2006

Hmm, no responses?

 

I’ve looked at this a number of different ways, and I think the biggest problem I keep running into is the notion of validating interrelated objects.  It’s fine if the objects form a strict child-parent hierarchy since they can notify each other of changes and all dave together.  The problems arise when the validity of an object is based on object(s) that are not part of its family tree.  If/when those objects change, is there a good way to find and re-validate all dependent objects.  Also, bear in mind that the dependent objects may or may note be instantiated and may even have edits in progress.

 

Once again, any ideas?  Am I trying to do something ridiculous?

 

Thanks,

            Andy

marklindell replied on Tuesday, August 08, 2006

I mentioned this to other CSLA members when asking tough design questions.  I find it works best if you do the following:

  1. Clearly define all your use cases.
  2. Design an object graph for each use case
  3. Refactor your object graphs to satisfy as many as the use cases as possible balancing complexity.
  4. Then begin to code your CSLA objects.
I first encountered this when I was trying to design a graph for a senario where I needed to select single objects from a list and edit them.  I could have designed using a BusinessListBase containing BusinessBase objects but instead I choose to use a ReadOnlyListBase containing ReadOnlyBase objects and an additional BusinessBase object to satisfy the edit.  I have very complex concurrency rules and the complexity in implementing UI resolution of the single editable object was much simpler than the complexity if many objects were editted and were in various concurrency states.

If you design a single graph centerned around your complex validation requirements you may find it much simpler than a graph that meets all use cases.

Sorry I don't have a specific answer to your question but I hope this helps.

Mark Lindell

AndrewCr replied on Wednesday, August 09, 2006

Thanks for the feedback.  I’m still in the design stage for the general case I described, so I’m still doing use cases and laying out my object relationships.  (Although I’m already coding for a subset of this problem -- pesky deadlines!)  Anyway, I guess I’m resigned to the fact that it’s a deceptively hard problem.

 

If anyone else wants to weigh in on handling objects that are dependent on one another for validation but aren’t parent/children of one another, I’m all ears.

 

Thanks,

            Andy

 

 

RockfordLhotka replied on Wednesday, August 09, 2006

I think that your Stop objects are different for Order from Trip.

Sure, from a data perspective they both "add and edit a stop". But from a business perspective (which is far more important) they are quite different.

An Order has a Stop which is all about what to pick up and drop off, and about some guarantee of timely delivery. Additionally, this Stop is a request, not a real stop. In other words, only a Trip has real Stop objects, Orders probably have StopRequest objects.

A Trip has a Stop which is all about time and place. When to be where, and probably for how long.

I would suggest that these differences are such that they indicate using seperate objects - at least until you prove to yourself that they are the same.

But I'd speculate that Trip creation involves reviewing StopRequestInfo objects (another type) to organize them into a set of Stop objects reflecting the most efficient way to route the Trip.

AndrewCr replied on Thursday, August 10, 2006

Yes, what you say about the differences between the Stop objects is exactly true, and making this change both helps and hinders the inter-object validation problem.  On the one hand, the Trip doesn’t have to worry about validating the Stop Requests from the Order, only the sequence of actual Stops, as planned on the Trip.  On the other, as we divorce the order requests from the planning objects, the problem re-arises when there are after-the-fact changes/edits in the Order.

 

Suppose the customer calls back and changes the requested pickup time on the Order.  How do we notify the Trip to check that the stops meet the request?  Worse yet, suppose we assign a Driver to the Trip based on his availability or other fitness for the job.  If the Order changes or the Driver changes (suppose his previous Trip is going to finish late) we need to load and revalidate the Trip.

 

I know I’m describing a very complex system, and I don’t expect the forum folks here to solve it for me.  (Although if you can, I can get you a job.  8)  )  But I do keep running into one recurring problem -- how to validate objects that are dependent on non-parent/non-child objects that can change?

RockfordLhotka replied on Thursday, August 10, 2006

What you are describing though, is another use case - the "existing stop modification" use case or something like that.
 
Don't complicate the "enter an order/add a stop" and "schedule a trip" use cases by merging in this "modification" use case - handle each one by itself. Only merge objects if it is clear _after the fact_ that they have the same responsibility. ("after the fact" means after designing all three use cases, not after coding them...)
 
I think you are thinking too much in terms of what your existing objects can do for you, and not what you can do for your objects (OK, that was bad... <g>)
 
But seriously, focus on the use cases and design them individually - THEN figure out if existing objects can help you, or if you have different objects.
 
What I'm getting at, is that you may not have "cross-object" validation. The "modify" use case may have its own objects that validate themselves and/or modify the trip in ways that a Trip object (for adding a trip) doesn't do, and is unaware of. The rules for "modify" are possibly quite different from the rules for "add".
 
Rocky

Suppose the customer calls back and changes the requested pickup time on the Order.  How do we notify the Trip to check that the stops meet the request?  Worse yet, suppose we assign a Driver to the Trip based on his availability or other fitness for the job.  If the Order changes or the Driver changes (suppose his previous Trip is going to finish late) we need to load and revalidate the Trip.

Copyright (c) Marimer LLC