Pattern name: Structure-shy Traversal Intent Improve the Visitor pattern from [GOF] and make it more versatile. Succinctly represent an operation to be performed on the elements of an object structure. Structure-shy Traversal gathers the code describing the traversal in one place with minimal dependency on the class structure. Commit only to a navigation strategy and specify navigation details later. Also Known As: Adaptive Traversal, Structure-shy Walker Motivation For an operation to be performed on an object structure, usually many of the objects involved are accidental and not of inherent importance. Those objects have only simple traversal behavior and their methods are quite small. Statistics of object-oriented systems show that a large fraction of the methods in an application are very short. Those short methods are usually for object traversal. When several traversals have to be performed on an object structure, the tiny methods become a nuisance since they encode the details of the class structure into the methods. This leads to software which is heavily redundant and not reusable when the object structure changes. When writing a program it would be ideal if we could look into the future to see how the program would evolve. We could then write the persistent parts of the program and reuse it to create the transient versions of the program. When we use Structure-shy Traversal we make a guess at how we think that the program will evolve. We write navigation specifications which we think will be robust over the versions of the program. This way we try to capture the persistent architecture of the program and we write the architecture in such a way that it is easy to construct implementations of the architecture which are the evolutionary versions of the program. The architecture will help us to preserve integrity of the program as we move from version to version. Applicability Use the Structure-shy Traversal pattern when An object structure contains at least two classes of objects and you want to perform operations involving a group of objects. You want to avoid polluting the classes with many simple methods. You want to plan for expected and unexpected evolution. The classes defining the object structure may change often and you may often want to define new operations over the structure. (Notice here the difference from the Visitor Pattern from [GOF], where changes to the class structure are costly.) Solution Use succinct traversal specifications for expressing the traversal strategy. Candidates are: from A to B from A CONSTRAINT to B where CONSTRAINT is a path constraint like "bypass edge e" "at C through edge f" via C etc. join two traversals etc. Consequences Program becomes shorter in many cases. A paradox! Program will adapt to many changes in class structure. Structure-shy Traversal makes adding new operations easy, even with modified traversals. The Structure-shy Traversal pattern uses a powerful iterator that not only iterates through lists but through any kind of object structure. Implementation The implementation of the Structure-shy Traversal pattern can be done like the implementation of traversals with propagation patterns. For adding behavior to the traversals, see the Context pattern. Succinct traversals can be specified in different ways: - using primitives from-to, join, merge This leads to "positive" traversals specifications and to the consistency problem. It can be resolved by either using restrictions on the allowed customizers or by using a complex compilation algorithm. See the TOPLAS '95 (http://www.ccs.neu.edu/research/demeter/biblio/compile-ap.html) and ESOP' 96 papers. (http://www.ccs.neu.edu/research/demeter/biblio/compile2-ap.html) - using primitive from-constraint-to, where constraint is a bypassing constraint. This does not lead to a consistency problem. - adding join to the previous primitives. Can be compiled without consistency problems. - adding "from A at B through e1, ... ,en to C" to the previous primitives does not cause consistency problems. The meaning is that at class B we must go through the given edges. All other edges are bypassed. See the meta-object protocol paper: http://www.ccs.neu.edu/research/demeter/biblio/ap-reflect.html Known Uses The Structure-shy Traversal pattern is used extensively in the implementation of the Demeter Tools/C++ and in applications written with the Demeter Tools [DEM]. The database community has been working on structure-shy queries. Those are queries that are relatively independent of the structure of the schema. See the thesis by Coleman Harrison reachable from URL: http://www.ccs.neu.edu/home/lieber/theses-index.html The functional programming community has been working on polytypic programming. See http://www.cs.chalmers.se/~johanj/polytypism.html and [POLYTYPIC]. -------------------------------------------------- The area of ontological commitment is related to structure-shy behavior. Put simply, an ontology consists of a set of objects and relationships between them. But there is the notion of specializing an ontology. For more detail: http://www-ksl.stanford.edu/kst/what-is-an-ontology.html T. Gruber writes in [Gruber 1993, Report KSL 93-04, Knowledge Systems Laboratory, Stanford]: "An ontology should make as few claims as possible about the world being modeled to allow the agents committed to the ontology freedom to specialize and instantiate the ontology as needed." This is called minimal ontological commitment. Guarino et al. take a different point of view: ================ Nicola Guarino et al. Proc. of AAAI 94 Formalizing Ontological Commitments "Formalizing the ontological commitment of a logical language means offering a way to specify the intended meaning of its vocabulary by constraining the set of its models, giving explicit information about the intended nature of the modelling primitives used and their a priori relationships." ================ For more info on ontological commitment see: http://www-ksl-svc.stanford.edu:5915/ -------------------------------------------------- In summary, the Structure-Shy-Traversal pattern has been reinvented several times: In databases, attribute grammars, functional programming and software engineering. The software engineering community has developed the concept to considerable depth [EFF-IMPL1, EFF-IMPL2] and: http://www.ccs.neu.edu/research/demeter Sample Code Traversal CESM = from Company via Employee via Salary to Money ESM = from Employee via Salary to Money // print names of all employees who earn more than $100000 operation void select_more_than_100000 // traverse and do additional work using visitors this -> CESM() // first visitor // broadcast the employee name down; // it is available in member n of a BROADCAST object b ::+ b:BROADCAST:ESM // second visitor // select desired objects using work done // by earlier visitors ::+ SELECT 100000,cout << b->n> // visitor definitions are like class definitions class BROADCAST { T* v; source(thisTraversal)::{v=i;}} class SELECT { c::{if (cond) action}} Exercise: Define a notation to express adaptive traversals. References DEM: @BOOK{karl:demeter, AUTHOR = "Karl J. Lieberherr", TITLE = "Adaptive Object-Oriented Software: The Demeter Method with Propagation Patterns", PUBLISHER = "PWS Publishing Company, Boston", YEAR = "1996", NOTE = "ISBN 0-534-94602-X" } POLYTYPIC: @INPROCEEDINGS{jeuring:structure-shy?, AUTHOR = "Johann Jeuring", TITLE = "Polytypic pattern matching", BOOKTITLE = "Conference Record of FPCA '95, SIGPLAN-SIGARCH-WG2.8 Conference on Functional Programming and Computer Architecture", YEAR = "1995", ADDRESS = "San Diego", PAGES = "238--248", EDITOR = "", PUBLISHER = "" } http://www.cs.chalmers.se/~johanj/polytypism.html EFF-IMPL1: @ARTICLE{lieber-palsberg-xiao94, AUTHOR = "Jens Palsberg and Cun Xiao and Karl Lieberherr", TITLE = "Efficient Implementation of Adaptive Software", JOURNAL = toplas , YEAR = 1995, PAGES = "264--292", MONTH = mar, VOLUME = 17, NUMBER = 2 } EFF-IMPL2: @INPROCEEDINGS{gener-comp:jens-boaz-karl, AUTHOR = "Jens Palsberg and Boaz {Patt-Shamir} and Karl Lieberherr", TITLE = "A New Approach to Compiling Adaptive Programs", BOOKTITLE = "European Symposium on Programming", YEAR = "1996", ADDRESS = "Linkoping, Sweden", PAGES = "280-295", EDITOR = "Hanne Riis Nielson", PUBLISHER = "Springer Verlag" } GOF: @BOOK{gang-of-4, AUTHOR = "Erich Gamma and Richard Helm and Ralph Johnson and John Vlissides", TITLE = "Design Patterns: Elements of Reusable Object-Oriented Software", PUBLISHER = "Addison-Wesley", YEAR = "1995" } ==========================================================================