Re: How to model decoupled hierarchies?



Responding to Kowalski...

Seems even simple things can turn out to be difficult to explain :)

There is just one typ of object. There is no polymorphy involved in the
object model.
Therefore I mean the following:

class Object {
private:
std::vector<Slice> _slices;
...
}

class Slice {
private:
std::vector<Countour> _contours;
...
}

class Contour {
private:
std::vector<ObjVertice> _objVertices;
...
}

class ObjVertex {
public:
double x,y,z;
}

Means an object contains a lot of slices. Each slice contain a lot of
contours. Each contour a lot of object vertices. With hierarchy I just
wanted to express a "folder-like" structure. The "..." just symbolize
that there are more properties then just the arrays.

OK, so the vectors are just instantiating 1:* relationships that break down a particular problem space structure that happens to be hierarchical. And...


My algorithm takes an object as input and generates the surface as
output. The surface is the second hierarchy and looks like this:

class Surface {
std::vector<SurfaceSector*> _sectors;
// maybe: std::vector<PerSliceElements> _sliceElements; // Does this
belong here??
}

// Since the surface sector object embodies the "business logic"
// there might be also different types of surface sectors.

class SurfaceSector {
Slice & _lowerSlice; // alternatively: PerSliceElements &
_lowerSliceElement;
Slice & _upperSlice; // alternatively: PerSliceElements &
_upperSliceElement;
std::vector<Region> _regions;
}

class Region {
std::vector<Triangle>
}

class Triangle {
ObjVertex *a, *b, *c;
}

Another problem space structure characterized by 1:* relationships that happens to be hierarchical. Now...

// This stuff I don't know there to put:

typedef std::vector<ObjVertices> PointGroup;

class PerSliceElements {
std::vector<PerContourElements> _contourElements;
std::vector<PointGroup> _pointGroups;
// maybe: Slice & _slice;
}

class PerContourElements {
std::vector<PerObjVertexElements > _vertexElements;
// or instead of above: std::vector<SurfaceNormal> _normals;
ConvexHull _hull;
// maybe: Contour & _contour;
}

class PerObjVertexElements {
SurfaceNormal _normal;
// maybe: ObjVertex & _vertex;
}

Since I'm not familiar with the problem space, the thing I am missing is how the first structure maps into the second. Alas, that seems to be the root of your concerns as well. B-)

There has to be some systematic way to "unwind" an Object structure into ObjVertices and then "rewind" them into a Surface structure. I am guessing that is algorithmically well-defined but tedious.

My inclination would be to encapsulate that mapping algorithm in some sort of factory object that builds the entire Surface structure by "walking" the relationships of the Object in hand. So one has:

<rest of Object structure>
|
| 1
[Slice]
| *
|
| R1
|
| element of
| 1
[Object]
| 1
| walks structure of
|
| R2
|
| 1
[SurfaceFactory]
| 1
|
| R3
|
| constructs
| *
[Surface]
| 1
|
| R4
|
| *
[Sector]
| 1
|
<rest of Surface structure>

Now one doesn't need explicit relationships between Surface elements and Object elements. I think that might eliminate the need for objects like PerSliceElements. I am guessing you only need those to abstract how the two surface structures are related during the construction of a Surface from an Object. If one encapsulates the entire construction is a single method, the need for them goes away.

Even if one needs to navigate back to the Object elements (e.g., to get {x,y,z} information) from the Structure elements, one can instantiate those direct relationships as one constructs the [Surface] structure because one will have the corresponding Object element in hand. That is, the links in [Triangle] can be initialized.

[Caveat. I am making an assumption that you need the [Surface] structure to solve some customer problem (e.g., it is a basic part of some sort of 3D display rendering). That assumption allows one to separate the concerns of constructing the [Surface] structure from the concerns of navigating it.]


Since there are many millions of vertices these elements shall be as
small as possible.
The algorithm is very complex and shall be as fast as just possible.
Speed have highest priority. Second comes "memory space" and third
"maintainability".

This is another reason why I think separating the concerns of constructing the [Surface] structure from those of doing something with a Surface is a good idea. That allows the construction algorithm to be encapsulated and optimized in one place. If one can eliminate intermediate objects like PerSliceElements, then one could have substantial performance gains in both context switches and heap operations.

A downside of delegation of responsibilities is performance when the number of objects is large. Ultimately one could delegate responsibilities down to the point where each bit was an object and one could have children in the time the program executes. So at some point one needs to find abstractions where one can substitute algorithmic processing for static structure even though static structure is the basis of high maintainability in the OO paradigm.

In the OO paradigm the criteria for that cut-bait point is whether the algorithm is unique to the problem in hand. IOW, one does not want to "hide" flow of control that is important to solving the particular problem. But if an algorithm exists outside the scope of the particular problem, it is fair game for encapsulation in a single method. (I have seen an entire linear programming package encoded in FORTRAN encapsulated as a single object method.)

I think encapsulating an Object "walker" algorithm to build a [Surface] structure is a good compromise. That's because such an algorithm really doesn't affect or depend on anything you actually do with the [Surface] to solve the application problem. It is simply a mapping function for the invariants of structures that exists beyond the scope of the particular problem (i.e., the algorithm can be abstractly specified in structure terms rather than specific problem terms). IOW, it's not going to change unless you make fundamental changes to the structures themselves, so maintainability is probably not a major issue.


*************
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: How to model decoupled hierarchies?
    ... Basically the class surface has a methode "void reconstruct( ... encapsulates the actual algorithm for reconstruction. ... The notion here of creating being the whole business logic and main purpose seems more appropriate for a particular subsystem whose subject matter was explicitly that construction. ... of) two slices), the section holds references to the slices. ...
    (comp.object)
  • Re: Concurrency problem: Compare and swap good enough?
    ... processes need to access the same buffer ... > in a realtime operating system i.e. one process can be preempted while ... However, that particular construction is ... simple mutual exclusion algorithm. ...
    (comp.programming)
  • Re: Commonality in subset construction and LR set of items construction algorithms
    ... a hard time as seeing them as anything but one algorithm. ... The idea of LR parsing is that a handle in a sentential form, i.e. the part of the sentential form which should be reduced in canonical bottom-up parsing, can be identified by a finite state automaton---sometimes dubbed handle-finding automaton. ... happens that, for any context-free grammars, the language of terminals and nonterminals prefixes up to the point where a reduction should occur is a regular language, and can be computed from the grammar. ... Constructing a deterministic finite state automaton from this grammar to find the handles in sentential forms ends up being the same as the LR item subset construction. ...
    (comp.theory)
  • Re: Factoring integers on a classical computer
    ... >constructively calculating the factors is, what I would call, surprising. ... but there is no known algorithm to compute the rank. ... *efficient* method of construction. ... Many proofs using the so-called "probabilistic method" of ...
    (sci.math)
  • Re: Factoring integers on a classical computer
    ... >constructively calculating the factors is, what I would call, surprising. ... but there is no known algorithm to compute the rank. ... *efficient* method of construction. ... Many proofs using the so-called "probabilistic method" of ...
    (comp.theory)