Now that we have a better understanding of interface class graphs, Doug proposed to equip them with bidirectional edges. Bidirectional edges provide ============================== Generalized Strategies We generalize traversal strategies by writing them against an interface strategy and allowing backward edges in a general way. --- Strategy graphs as abstractions of class graphs So far we have used strategies in the role of traversal specifications. Next we are giving strategies a second role: abstractions of the class graph we can program against. This second role is useful for at least two reasons: 1. A strategy type is an interface to a class graph for an entire APPC. All strategies used inside the APPC should be substrategies of the interface. 2. We can use strategies to define the blueprint for "new" kinds of traversal specifications. For example, for the strategy type {A -> {B,C}} we want to define the traversal {B <- A -> C} with backward edge {B <- A}. The backward path is well-defined if every A-object can have only one B-object associated with it. Therefore, an APPC should have _one_ strategy type IST in its interface to the class structure and the strategies local to the APPC are written modulo IST. Let's apply the idea of an interface strategy type to backward strategy-graph edges. It is useful to have backward strategy graph edges to avoid lengthy back transportation and searching code. While ordinary strategy graphs only express object traversal, strategy graphs with backward edges also express object searching. The backward edges are expressed modulo an interface strategy type. Definition of a backward edges: Given a strategy type IST, a generalized strategy graph wrt IST is a substrategy SG of IST with additional backward edges. For a backward edge X<-Y to be legal there must be a path in IST from Source(SG) to Y and for each such Y there is exactly one X reachable. The backward edge may have a constraint map associated with it which restricts the paths from Y to X to a unique path. The object searching consists of traversing from Source(SG) to Y and building a hashtable which associates the uniquely reachable X with Y. This hashtable allows us to retrieve the corresponding Y when we are at an X, effectively replacing a search operation. Source(SG)------> .Y. ^ | | X Let's consider our earlier example: IST: Graph -> Adjacency -> Neighbors -> Vertex -> Vertex through -> *,source,* generalized SG: Graph -> Neighbors -> Vertex <- Adjacency | | constraint: through ->*,source,* Source(SG) X Y Graph -> Neighbors -> Vertex <- Adjacency | | constraint: through ->*,source,* When we are at Vertex-object, the corresponding Adjacency-object will be retrieved automatically. Another example in the context of APPCs (see OOPSLA '98 paper): IST: {LineItemParty -> {PricerParty, ItemParty}} SG: {PricerParty <- LineItemParty -> ItemParty} Here we assume that a LineItemParty-object has exactly one PricerParty object associated with it. The association between objects is assumed to be static and is computed once at the beginning. The concept of an interface strategy graph with generalized strategies conforming to the interface can be extended to static and dynamic participant definitions. {pricer:PricerParty <- lineItem:LineItemParty -> item:ItemParty} allows us to use pricer in ItemParty or item in PricerParty. See: http://www.ccs.neu.edu/research/demeter/biblio/components