Re: Business objects, subset of collection



Responding to Jimbalo22...

Hi,

I have a collection of business objects that the user works on via
data binding. The user needs to be able to work with a subset of the
collection and I am wondering what the best way to accomplish this is.

Example:

InvoiceCollection->Invoice->PaymentCollection->Payment

I assume this notation means something like:

[Customer]
| 1
|
| R1
|
| is billed with
| *
[Invoice]
+ date
| 1
|
| R2
|
| are paid by
| *
[Payments]
+ date

where InvoiceCollection and PaymnentCollection implement the R1 and R2 1:* relationships at OOP time.


The user wants to only work with invoices or payments for a certain
date.

Two ways I can think of are 1) work with a subset, or 2) Work with the
full set in a filtered fashion. I am leaning toward 2), but it gets
quite messy with a bunch of filter related methods in the public
interfaces.

The answer definitely depends -- on what problems are being solved and at what level of abstraction.

The most general approach is (2) and most of the abstract action languages (AALs) used in OOA/D will have a WHERE clause available for any relationship navigation to filter the set of objects accessed. Thus in an AAL method one might have something like

invoiceSet = this -> R1 WHERE (date=20080113)
FOREACH invoice IN invoiceSet
// process invoice objects

when the user wants invoices, or

paymentSet = this -> R1 -> R2 WHERE (date=20080113)
FOREACH payment IN paymentSet
// process payment objects

when the user wants payments. [Note that the WHERE clause filters the date attribute in the target set. When a multistage path is navigated it is assumed that the membership of the intermediate collections already limits the set adequately. If not, one needs to do the second fragment in two stages.]

This is fine so long as the filter is simple, such as a date. Each collection is optimized for efficient access via a date. As you point out, it gets somewhat messy if there are multiple filters (e.g., one also may want payments where the amount was less than some percentage of the outstanding balance). Then the collection class needs an interface for each distinct selection criteria. Each accessor may need a specialized implementation as well.

However, that is pretty much why collection classes exist; they manage collections. More to the point, that is /all/ they do; they encapsulate the collection management in one place. IOW, the collection class isolates and encapsulates complexity of a highly focused nature. In general that is a Good Thing. So there is nothing inherently wrong with the second approach.

Note that in the AAL, one just needs to substitute "amount<100" in the WHERE clause to deal with another selection criteria in the second fragment above. The details of how one mucks about to extract that set is left to the low level implementation so during OOA/D the application developer doesn't need to think about it.

However, at OOP time one addresses other issues like performance and maintainability. Suppose Invoices and Payments are very rarely added compared to how often the various selection criteria are accessed. In that case it may well be more efficient to have multiple 1:* relationships in parallel, each with its own optimized collection mechanics. Thus one has R2A optimized to access by <arbitrary> date and R2B optimized to access by some amount criteria. For example, one collection is sorted by date while the other is sorted by amount. The overhead of adding the same entry to each collection is <hopefully> small compared to accessing the same elements many times.

Maintainability may also drive the use of (1) simply because the internal mechanisms for optimizing around several disparate criteria are just making the collection object too complex to modify. This is a variation on your concern about the interface being "messy". However, multiple interface methods are usually not the core problem; the need to break up the collection is usually driven by the complexity of the implementation.

Bottom line: in OOA/D one wants to think generically about (2) without worrying about the details and the OOA/D notations are designed around that. But at OOP time one is addressing other issues and those may drive using (1).


--
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl@xxxxxxxxxxxxxxxxx
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info@xxxxxxxxxxxxxxxxx for your copy.
Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH
.



Relevant Pages

  • RE: Ignoring lines in a pivot table
    ... you can advance filter by more than one column. ... (either on your original sheet or the ... For example, I set up a data sheet with Invoice, Hired, and Value as the ... PS – I still think putting the filter on your pivot table might be easier;-) ...
    (microsoft.public.excel.misc)
  • Re: report group subtotals incorrect
    ... there are multiple payments of the invoice, ... This text box accumlates the total for the customer over their invoices, ... An alternative idea would be to use a subreport for the payments. ... > tehn totals per group. ...
    (microsoft.public.access.queries)
  • Re: create totals based on a field values...
    ... In general an invoice is no more final than ... form or report calculations to display those values ... Payments table. ... >doesn't change therefore the totals don't change... ...
    (microsoft.public.access.queries)
  • Re: SQL Query Double Counts on Multi-Table Query
    ... SUM AS TotalPayments ... tblPayments AS p ... Many-to-one relationship allowing multiple payments per invoice. ...
    (microsoft.public.access.queries)
  • Re: How to prevent duplicates?
    ... Orders to Payments should be a one to many relationship... ... On your main report each Invoice record should be derived from a Totals ... > Orders.CustomerID) INNER JOIN (((Contracts INNER JOIN (SIN INNER JOIN ...
    (microsoft.public.access.reports)