Predicates / Filters seperated out?

Posts   
 
    
thomas
User
Posts: 24
Joined: 21-Oct-2004
# Posted on: 07-Dec-2004 20:35:15   

Has anyone structured their projects in such a way as to locate all the various Predictes/Filters in a particular class or folder? I'm guessing since a given filter can possibly be used in numerous classes it would be nice to have it located in its own area - like a class or folder just for different predicates / filters.

Thomas

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 07-Dec-2004 21:30:40   

thomas wrote:

Has anyone structured their projects in such a way as to locate all the various Predictes/Filters in a particular class or folder? I'm guessing since a given filter can possibly be used in numerous classes it would be nice to have it located in its own area - like a class or folder just for different predicates / filters.

Thomas

I use a factory to spit out common predicates. You'll want to be careful in using global variables to store predicates as it can cause problems in instances where you modify the value of a predicate in two different places and assume it's going to give the same results!

Also, if you're considering globals, you might want to revisit your architecture. Perhaps you need to create business/service layers to provide discrete functionality for a given entity/process. In this manner, globals aren't necessary as each business/service component is self-sufficient and all predicates required would be encapsulated in calls like ".GetOrdersByRegion(regionID as integer)".

Hope that helps. simple_smile

Jeff...

thomas
User
Posts: 24
Joined: 21-Oct-2004
# Posted on: 08-Dec-2004 00:58:46   

Globals? Hmm. Didnt mean to make sound like that at all. At the same time I hesitate to call a class a "factory" when it possibly only contains methods to return predicates.... In my world a factory often hides implementation of certain code underneath it. Like a connection factory that produces a sqlconnection or oledbconnection depending on what you need. Since I would know that I need "PredicateToPullThisBasedOnThat" I could just instantiate that specific predicate. Then again, maybe I misunderstood you and I'm just rambling on for nothing simple_smile

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 08-Dec-2004 04:53:33   

thomas wrote:

Globals? Hmm. Didnt mean to make sound like that at all. At the same time I hesitate to call a class a "factory" when it possibly only contains methods to return predicates.... In my world a factory often hides implementation of certain code underneath it. Like a connection factory that produces a sqlconnection or oledbconnection depending on what you need.

Exactly...I'm not sure of the exact definition, but in this case I'm using it to refer to the centralized creation of "things" based on a request. In this case the "thing" is an IPredicateExpression, and in one of my current implementations I have an enum set up with values like "InventoryWithSerializedItems", and "AllNonSerializedItems" that gets passed to the factory which returns the proper IPredicateExpression. This way my schema is abstracted from the purpose and if anything changes I only need change the inner workings of the factory.

The second benefit is that I'm guaranteed to produce a unique IPredicateExpression for each caller which eliminates shared code (caller A changing the value of an IPredicate before caller B uses it).

If you're talking about a place to simply get a new instance of, say, a CompareValuePredicate, then see the "FactoryClasses.PredicateFactory" class.

Jeff...

thomas
User
Posts: 24
Joined: 21-Oct-2004
# Posted on: 08-Dec-2004 16:31:35   

Ah ! Thats what you meant. Now I understand. Did you see abig light go on over Los Angeles? That was me getting it simple_smile

Thomas

thomas
User
Posts: 24
Joined: 21-Oct-2004
# Posted on: 08-Dec-2004 16:50:19   

Just to clarify things. Is it true that I can think of PredicateExpressions as the equivalent of a complete Where clause? So in a way I could think of the factory you describe as a "Where Clause Factory" - which is pretty cool . And since Where clauses are frequently used across numerous often unrelated areas of an app, having somehting produce any sort of predefined Where clause on demand is a handy thing. It allows you to build an app in a way you never could using sprocs and T-SQL....

Thomas

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 08-Dec-2004 18:38:00   

thomas wrote:

Just to clarify things. Is it true that I can think of PredicateExpressions as the equivalent of a complete Where clause? So in a way I could think of the factory you describe as a "Where Clause Factory" - which is pretty cool . And since Where clauses are frequently used across numerous often unrelated areas of an app, having somehting produce any sort of predefined Where clause on demand is a handy thing. It allows you to build an app in a way you never could using sprocs and T-SQL....

Thomas

All of the above is correct. simple_smile

Jeff... simple_smile

thomas
User
Posts: 24
Joined: 21-Oct-2004
# Posted on: 08-Dec-2004 21:39:09   

Halleluliah its starting to sink in!

You wouldn't believe how long its taking to get my head around this paradigm and I haven't even had to create any particularly difficult SQL call from Predicates as yet. Its been standard stuff that I can do with my eyes closed in T-SQL.

Thomas

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 08-Dec-2004 21:52:49   

thomas wrote:

Halleluliah its starting to sink in!

You wouldn't believe how long its taking to get my head around this paradigm and I haven't even had to create any particularly difficult SQL call from Predicates as yet. Its been standard stuff that I can do with my eyes closed in T-SQL.

Thomas

Yea, it's a pretty sweet system Frans has set up here. Especially in Adapter he's really focused on reusability and it has paid off in spades. I originally started in Self-Servicing (Adapter wasn't available at the time) and when I moved to Adapter things got even easier.

The nice addition Frans made in Adapter is the RelationPredicateBucket. The great thing about that is the fact that for any WHERE clause involving more than one table, there is created a dependency on the FROM clause, right? So, in marvelous OO fashion, the RelationPredicateBucket contains both the PredicateExpressionCollection (the set of WHERE clauses) and the RelationCollection (the set of FROM/JOIN clauses) that make up the proper set of filters and table selections for a given query.

What's more, since they are collections you can initially create an appropriate RelationPredicateBucket via a Factory (like my "InventoryWithSerializedItems" example), pass it along to whichever method needs it, then add to it to further limit/expand the query without tampering with the original criteria. Niiiiiiice... smile

Jeff...

thomas
User
Posts: 24
Joined: 21-Oct-2004
# Posted on: 09-Dec-2004 02:33:54   

I have to take a look at the Adapter approach. So far I've been doing SelfService because I thought it was easier to understand and it seemed to have less datatable centric code. I wouldn't want to try and explain this to a normal ADO.NET programmer and have to explain why I have all the datatables in the system without the use of other popular ADO.NET objects like datasets. SS seemed to be more akin to standard OO with objects and collections. So I started there. simple_smile

Thomas

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 09-Dec-2004 05:57:37   

thomas wrote:

I have to take a look at the Adapter approach. So far I've been doing SelfService because I thought it was easier to understand and it seemed to have less datatable centric code. I wouldn't want to try and explain this to a normal ADO.NET programmer and have to explain why I have all the datatables in the system without the use of other popular ADO.NET objects like datasets. SS seemed to be more akin to standard OO with objects and collections. So I started there. simple_smile

Thomas

Hey, there. FYI, Adapter and Self-Servicing use the same objects for data encapsulation (entities and collections), it's just the persistence mechanism that's different. Whereas you'll call EntityCollection.GetMulti*() in Self-Servicing, you'll call Adapter.FetchEntityCollection() in Adapter. Whereas you'll say "New Entity(ID)" in Self-Servicing, you'll call Adapter.FetchEntity() in Adapter. And, whereas in Self-Servicing you'll call Entity.Save(), in Adapter you'll call Virtually the same objects; it's just a different mechanism for fetching and persisting the data: Self-Servicing has the persistence methods in the data objects themselves while Adapter requires that all persistence take place through the DataAccessAdapter.

I do recommend that you use Adapter, but if time's short (when is it not?) you may need to use Self-Servicing. Self-Servicing gives you lazy-loading, but you don't get a clean separation of data and persistence, while with Adapter you must manually load all related entities and collections, but you get to control access to the persistence logic.

Beyond these things, the objects function the same whether through Self-servicing or Adapter.

Jeff...