Graphics Reference
In-Depth Information
Traits can also be implemented at runtime in languages with first-class func-
tions or closures. This forgoes static type checking but allows the flexibility of
the design pattern with less boilerplate and in more languages. For example, List-
ing 37.7 uses the trait pattern in Python and depends on dynamic typing and run-
time error checks to ensure correctness.
Listing 37.7: A Python trait for exposing axis-aligned bounding box, sphere,
and point keys from primitives.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def getTriangleBoxBounds(triangle, box):
box = AABox(min(tri.vertex(0), tri.vertex(1), tri.vertex(2)),
max(tri.vertex(0), tri.vertex(1), tri.vertex(2)))
}
class SomeStructure:
_bounds = null
def __init__(self, boundsFunction):
self._bounds = boundsfunction
...
def insert(self, value):
Box key;
self._bounds(value, key)
...
}
};
SomeStructure s(getTriangleBoxBounds)
The trait design pattern for extracting keys has three main advantages. Traits
allow the data structure implementor to make the data structure work with Value
classes that predate it. For example, you can create your own new binary space par-
tition tree spatial data structure and write a trait to make it work with the Triangle
class from an existing library that you cannot modify. A related advantage is that
traits move the complexity of the key-extraction operation out of the Value class.
Another advantage of traits is that they allow instances of data structures
with the same Value to use different traits. For example, you may wish to
build one tree that uses the vertex of a triangle that is closest to the origin as
its position key, and another that uses the centroid of the triangle as its posi-
tion key. However, if getPositionKey is a method of Triangle , then this is
not possible. Under the pattern shown in Listing 37.5, these would be instan-
tiated as SomeStructure<Triangle, MinKey> and SomeStructure<Triangle,
CentroidKey> .
A disadvantage of traits compared to inheritance is that traits separate the
implementation of a Value class into multiple pieces. This can increase the cost
of designing and maintaining such a class.
Traits also involve more complicated semantics and syntax than other
approaches. This is particularly true for the variant shown in Listing 37.5 that
uses C++ templates. Many C++ programmers have never written their own trait-
based classes, or even their own templated classes. Almost all have used tem-
plated classes and traits, however. So this design pattern significantly increases
the barrier to creating a new kind of data structure and slightly increases the bar-
rier to creating a new kind of primitive, but introduces little barrier to using a data
structure.
 
 
Search WWH ::




Custom Search