435,512 Members | 3,689 Online
Need help? Post your question and get tips & solutions from a community of 435,512 IT Pros & Developers. It's quick & easy.

# A little O-O design pattern question...

 P: n/a I'm curious to see if anyone has an opinion on this little design question - I'm doing a computational astronomy library in C#, purely for my own use, and one of the things that happens regularly is conversion of coordinates from one frame of reference to another: spherical coordinates in the ecliptic frame of reference, spherical coordinates in the equatorial frame of reference, 3D rectangular coordinates in either, galactic coordinates, horizontal coordinates, and on and on. The question relates to where to site the conversion methods most naturally. To illustrate the question, I've boiled it down to a simple case: Consider 2D plane coordinates: you have Cartesian (rectangular) coordinates (X and Y) and polar coordinates (angle and radius vector). The transformations between them are well-known and simple. So you can take rectangular coordinates (a subclass of Point, perhaps, named CartesianCoords), apply the transformation to X and Y, and get out polar coordinates. And vice versa. So where do the conversion methods best reside? Here are some possibilities: 1. A static conversion function such as CartesianToPolar(CartesianCoords cc) returning a PolarCoordinates object; 2. An instance method on a CartesianCoords object returning a PolarCoordinates object; 3. A PolarCoordinates constructor taking a CartesianCoords object, which applies the conversion and populates its data members from the outcome of the transformation. Admittedly this is a fairly minor point, for the example above, but when you have a half-dozen different coordinate systems, with potential conversions between all pairs, there's a combinatorial explosion that might get ugly. Also, while the transformation described above needs no other information besides the coordinates, some of the astronomical transformations require additional parameters. Any thoughts? Or if you don't think this is the right place to post a question like this, how about a suggestion for a more appropriate newsgroup or site (I didn't find a real natural venue in a quick search of the newsgroup names)? Thanks, Tom Dacon Dacon Software Consulting Nov 15 '05 #1
10 Replies

 P: n/a I would suggest writing a class for each kind of coordinate, and then add conversion operators between the ones that are equivalent. So, that would allow you to specify a method taking PolarCoordinate, and if the user passed a CartesianCoordinate, it would be converted automatically. For the ones that take parameters, I think you'll want to define constructors that take the coordinate and the additional parameters. "Tom Dacon" wrote in message news:O4**************@TK2MSFTNGP09.phx.gbl... I'm curious to see if anyone has an opinion on this little design question - I'm doing a computational astronomy library in C#, purely for my own use, and one of the things that happens regularly is conversion of coordinates from one frame of reference to another: spherical coordinates in the ecliptic frame of reference, spherical coordinates in the equatorial frame of reference, 3D rectangular coordinates in either, galactic coordinates, horizontal coordinates, and on and on. The question relates to where to site the conversion methods most naturally. To illustrate the question, I've boiled it down to a simple case: Consider 2D plane coordinates: you have Cartesian (rectangular) coordinates (X and Y) and polar coordinates (angle and radius vector). The transformations between them are well-known and simple. So you can take rectangular coordinates (a subclass of Point, perhaps, named CartesianCoords), apply the transformation to X and Y, and get out polar coordinates. And vice versa. So where do the conversion methods best reside? Here are some possibilities: 1. A static conversion function such as CartesianToPolar(CartesianCoords cc) returning a PolarCoordinates object; 2. An instance method on a CartesianCoords object returning a PolarCoordinates object; 3. A PolarCoordinates constructor taking a CartesianCoords object, which applies the conversion and populates its data members from the outcome of the transformation. Admittedly this is a fairly minor point, for the example above, but when you have a half-dozen different coordinate systems, with potential conversions between all pairs, there's a combinatorial explosion that might get ugly. Also, while the transformation described above needs no other information besides the coordinates, some of the astronomical transformations require additional parameters. Any thoughts? Or if you don't think this is the right place to post a question like this, how about a suggestion for a more appropriate newsgroup or site (I didn't find a real natural venue in a quick search of the newsgroup names)? Thanks, Tom Dacon Dacon Software Consulting Nov 15 '05 #2

 P: n/a From reading it, I think a shared [static] method may be in your best interests especially if you don't need to reference anything in particular. You could create a base class to inherit off of, but I don't know if you really need to, unless there is a clear heirarchy between the two. But simply build a external library (like your doing, create a class called computations and add shared methods to do your dirty work... But I dont' see a real need for object inheritance at this point, maybe I'm wrong. Hope it helps. -CJ "Tom Dacon" wrote in message news:O4**************@TK2MSFTNGP09.phx.gbl... I'm curious to see if anyone has an opinion on this little design question - I'm doing a computational astronomy library in C#, purely for my own use, and one of the things that happens regularly is conversion of coordinates from one frame of reference to another: spherical coordinates in the ecliptic frame of reference, spherical coordinates in the equatorial frame of reference, 3D rectangular coordinates in either, galactic coordinates, horizontal coordinates, and on and on. The question relates to where to site the conversion methods most naturally. To illustrate the question, I've boiled it down to a simple case: Consider 2D plane coordinates: you have Cartesian (rectangular) coordinates (X and Y) and polar coordinates (angle and radius vector). The transformations between them are well-known and simple. So you can take rectangular coordinates (a subclass of Point, perhaps, named CartesianCoords), apply the transformation to X and Y, and get out polar coordinates. And vice versa. So where do the conversion methods best reside? Here are some possibilities: 1. A static conversion function such as CartesianToPolar(CartesianCoords cc) returning a PolarCoordinates object; 2. An instance method on a CartesianCoords object returning a PolarCoordinates object; 3. A PolarCoordinates constructor taking a CartesianCoords object, which applies the conversion and populates its data members from the outcome of the transformation. Admittedly this is a fairly minor point, for the example above, but when you have a half-dozen different coordinate systems, with potential conversions between all pairs, there's a combinatorial explosion that might get ugly. Also, while the transformation described above needs no other information besides the coordinates, some of the astronomical transformations require additional parameters. Any thoughts? Or if you don't think this is the right place to post a question like this, how about a suggestion for a more appropriate newsgroup or site (I didn't find a real natural venue in a quick search of the newsgroup names)? Thanks, Tom Dacon Dacon Software Consulting Nov 15 '05 #3

 P: n/a Hi Tom, Why do not take note of the way the framework itself handle a similar situation, It provide a Convert class that deal with converting from one basic type to other, if you see this class is similar to what you want. It has for example ToDecimal that return a decimal struct and has one version for each of the types in the CLR, you could do the same, create a class CoordinateConvert that define a method like ToCartesian overloaded as needed: CartesianClass ToCartesian( SphericClass o); CartesianClass ToCartesian( GalacticClass o); CartesianClass ToCartesian( EclipticClass o); Hope this help, -- Ignacio Machin, ignacio.machin AT dot.state.fl.us Florida Department Of Transportation "Tom Dacon" wrote in message news:O4**************@TK2MSFTNGP09.phx.gbl... I'm curious to see if anyone has an opinion on this little design question - I'm doing a computational astronomy library in C#, purely for my own use, and one of the things that happens regularly is conversion of coordinates from one frame of reference to another: spherical coordinates in the ecliptic frame of reference, spherical coordinates in the equatorial frame of reference, 3D rectangular coordinates in either, galactic coordinates, horizontal coordinates, and on and on. The question relates to where to site the conversion methods most naturally. To illustrate the question, I've boiled it down to a simple case: Consider 2D plane coordinates: you have Cartesian (rectangular) coordinates (X and Y) and polar coordinates (angle and radius vector). The transformations between them are well-known and simple. So you can take rectangular coordinates (a subclass of Point, perhaps, named CartesianCoords), apply the transformation to X and Y, and get out polar coordinates. And vice versa. So where do the conversion methods best reside? Here are some possibilities: 1. A static conversion function such as CartesianToPolar(CartesianCoords cc) returning a PolarCoordinates object; 2. An instance method on a CartesianCoords object returning a PolarCoordinates object; 3. A PolarCoordinates constructor taking a CartesianCoords object, which applies the conversion and populates its data members from the outcome of the transformation. Admittedly this is a fairly minor point, for the example above, but when you have a half-dozen different coordinate systems, with potential conversions between all pairs, there's a combinatorial explosion that might get ugly. Also, while the transformation described above needs no other information besides the coordinates, some of the astronomical transformations require additional parameters. Any thoughts? Or if you don't think this is the right place to post a question like this, how about a suggestion for a more appropriate newsgroup or site (I didn't find a real natural venue in a quick search of the newsgroup names)? Thanks, Tom Dacon Dacon Software Consulting Nov 15 '05 #4

 P: n/a Hi, "Eric Gunnerson [MS]" wrote in message news:uI**************@TK2MSFTNGP12.phx.gbl... I would suggest writing a class for each kind of coordinate, and then add conversion operators between the ones that are equivalent. The problem I see with this is the difficult to maintain it. If tomorrow you include a new coordinate you need to derive/change ALL the classes, in other words the classes are tighly coupled ( not a good thing in OOP ) the best idea is to keep all the possible conversion on a single class, in this escenario if a new coordinate is added you only need to expand this class to include the new overloaded method. Hope this help, -- Ignacio Machin, ignacio.machin AT dot.state.fl.us Florida Department Of Transportation Nov 15 '05 #5

 P: n/a Hi Tom, I thought about this and then read the other replies and I'm posting as a response to Ignacio. With questions like these I think in terms of need-to-know (which I guess is my vocabulary for tight-coupling). If a class doesn't need to know about another in order to do its thing, why burden it? Especially when the extraneous knowledge is two-way and the set of others gets bigger - that explosion you mentioned. This suggests an intermediary - someone who knows everyone in the set - a bit like an introduction agency, maybe. In other words, Ignacio's CoordConverter. There is a case for favourites, though - for the sake of convenience. For instance, in .NET an Integer knows how to turn itself into a string and parse itself from one. For completeness the CoordConverter would also provide that conversion, of course, but for ease of programming it could simply get the Coord to do the job. To help cut down on your explosion, the Converter could do two-stage, and maybe even three-stage, conversions, although you'd have to give accuracy and computational cost at least a passing thought. Using this approach, I think that the centralised nature of a Converter would be a boon. Regards, Fergus ps. Small points can develop into principles. ;-) Nov 15 '05 #6

 P: n/a On Fri, 3 Oct 2003 12:55:53 -0700, "Tom Dacon" wrote: I'm curious to see if anyone has an opinion on this little design question - The most robust model is to use inheritance. The trick is to decide on a "base co-ordinate system". All sub-classes need implement a conversion to and from that base only. A little VB code to demonstrate... Public MustInherit Class BaseCoordinate ' This is the conversion function Public Function SetValue(ByVal oValue As BaseCoordinate) SetBaseCoordinateValue(oValue.GetBaseCoordinateVal ue()) End Function ' You might want to implement these as a property instead Protected MustOverride Function GetBaseCoordinateValue() _ As BaseCoordinate Protected MustOverride Function SetBaseCoordinateValue( _ ByVal oValue As BaseCoordinate) As BaseCoordinate End Class .... after which, casting is safe. Just plonk any old co-ordinate system in as the value to SetValue() and the correct conversion functions will be called. By all means, implement a shared method to do actual conversion, but it's nice to supply a constructor too. Rgds, Nov 15 '05 #7

 P: n/a Applying the principles of Design Patterns... 1. Program to an interface not an implementation. 2. Find out what is changing and abstract it. You have different algorithms for converting. The Strategy Pattern might fit into this. You have different classes for different type of conversions and the context will give you appropriate algorithm based on the pre-defined conditions. I feel more elegant way of handling this might be with the help of Strategy Pattern. "Tom Dacon" wrote in message news:O4**************@TK2MSFTNGP09.phx.gbl... I'm curious to see if anyone has an opinion on this little design question - I'm doing a computational astronomy library in C#, purely for my own use, and one of the things that happens regularly is conversion of coordinates from one frame of reference to another: spherical coordinates in the ecliptic frame of reference, spherical coordinates in the equatorial frame of reference, 3D rectangular coordinates in either, galactic coordinates, horizontal coordinates, and on and on. The question relates to where to site the conversion methods most naturally. To illustrate the question, I've boiled it down to a simple case: Consider 2D plane coordinates: you have Cartesian (rectangular) coordinates (X and Y) and polar coordinates (angle and radius vector). The transformations between them are well-known and simple. So you can take rectangular coordinates (a subclass of Point, perhaps, named CartesianCoords), apply the transformation to X and Y, and get out polar coordinates. And vice versa. So where do the conversion methods best reside? Here are some possibilities: 1. A static conversion function such as CartesianToPolar(CartesianCoords cc) returning a PolarCoordinates object; 2. An instance method on a CartesianCoords object returning a PolarCoordinates object; 3. A PolarCoordinates constructor taking a CartesianCoords object, which applies the conversion and populates its data members from the outcome of the transformation. Admittedly this is a fairly minor point, for the example above, but when you have a half-dozen different coordinate systems, with potential conversions between all pairs, there's a combinatorial explosion that might get ugly. Also, while the transformation described above needs no other information besides the coordinates, some of the astronomical transformations require additional parameters. Any thoughts? Or if you don't think this is the right place to post a question like this, how about a suggestion for a more appropriate newsgroup or site (I didn't find a real natural venue in a quick search of the newsgroup names)? Thanks, Tom Dacon Dacon Software Consulting Nov 15 '05 #8

 P: n/a Applying the principles of Design Patterns... 1. Program to an interface not an implementation. 2. Find out what is changing and abstract it. You have different algorithms for converting. The Strategy Pattern might fit into this. You have different classes for different type of conversions and the context will give you appropriate algorithm based on the pre-defined conditions. I feel more elegant way of handling this might be with the help of Strategy Pattern. "Tom Dacon" wrote in message news:O4**************@TK2MSFTNGP09.phx.gbl... I'm curious to see if anyone has an opinion on this little design question - I'm doing a computational astronomy library in C#, purely for my own use, and one of the things that happens regularly is conversion of coordinates from one frame of reference to another: spherical coordinates in the ecliptic frame of reference, spherical coordinates in the equatorial frame of reference, 3D rectangular coordinates in either, galactic coordinates, horizontal coordinates, and on and on. The question relates to where to site the conversion methods most naturally. To illustrate the question, I've boiled it down to a simple case: Consider 2D plane coordinates: you have Cartesian (rectangular) coordinates (X and Y) and polar coordinates (angle and radius vector). The transformations between them are well-known and simple. So you can take rectangular coordinates (a subclass of Point, perhaps, named CartesianCoords), apply the transformation to X and Y, and get out polar coordinates. And vice versa. So where do the conversion methods best reside? Here are some possibilities: 1. A static conversion function such as CartesianToPolar(CartesianCoords cc) returning a PolarCoordinates object; 2. An instance method on a CartesianCoords object returning a PolarCoordinates object; 3. A PolarCoordinates constructor taking a CartesianCoords object, which applies the conversion and populates its data members from the outcome of the transformation. Admittedly this is a fairly minor point, for the example above, but when you have a half-dozen different coordinate systems, with potential conversions between all pairs, there's a combinatorial explosion that might get ugly. Also, while the transformation described above needs no other information besides the coordinates, some of the astronomical transformations require additional parameters. Any thoughts? Or if you don't think this is the right place to post a question like this, how about a suggestion for a more appropriate newsgroup or site (I didn't find a real natural venue in a quick search of the newsgroup names)? Thanks, Tom Dacon Dacon Software Consulting Nov 15 '05 #9

 P: n/a I don't know if any of the responders are still watching this thread, but if any of you are I'd like to thank you for your responses. I've decided to go with a converter class with a set of static methods to do the various conversions, in order to collect all the transforms in a single place. For the most commonly-used conversions, I'll supply a little syntactic sugar on some of the coordinate classes, either in constructors or in function methods that output a transformed coordinate object. They themselves will use the static methods, so as to keep the logic all in one place. I investigated the TypeConverter class as a mechanism for the conversions, with a view toward using a pattern that's used by the framework itself, but ultimately didn't go down that road. The problem is that some of the conversions are parameterized and require externally-supplied bits of information not already encapsulated in the coordinate object's state. So a set of explicit static methods with overloads appears to be the way to go. Thanks for taking the time to comment, Tom Dacon Dacon Software Consulting "Tom Dacon" wrote in message news:O4**************@TK2MSFTNGP09.phx.gbl... I'm curious to see if anyone has an opinion on this little design question - I'm doing a computational astronomy library in C#, purely for my own use, and one of the things that happens regularly is conversion of coordinates from one frame of reference to another: spherical coordinates in the ecliptic frame of reference, spherical coordinates in the equatorial frame of reference, 3D rectangular coordinates in either, galactic coordinates, horizontal coordinates, and on and on. The question relates to where to site the conversion methods most naturally. To illustrate the question, I've boiled it down to a simple case: Consider 2D plane coordinates: you have Cartesian (rectangular) coordinates (X and Y) and polar coordinates (angle and radius vector). The transformations between them are well-known and simple. So you can take rectangular coordinates (a subclass of Point, perhaps, named CartesianCoords), apply the transformation to X and Y, and get out polar coordinates. And vice versa. So where do the conversion methods best reside? Here are some possibilities: 1. A static conversion function such as CartesianToPolar(CartesianCoords cc) returning a PolarCoordinates object; 2. An instance method on a CartesianCoords object returning a PolarCoordinates object; 3. A PolarCoordinates constructor taking a CartesianCoords object, which applies the conversion and populates its data members from the outcome of the transformation. Admittedly this is a fairly minor point, for the example above, but when you have a half-dozen different coordinate systems, with potential conversions between all pairs, there's a combinatorial explosion that might get ugly. Also, while the transformation described above needs no other information besides the coordinates, some of the astronomical transformations require additional parameters. Any thoughts? Or if you don't think this is the right place to post a question like this, how about a suggestion for a more appropriate newsgroup or site (I didn't find a real natural venue in a quick search of the newsgroup names)? Thanks, Tom Dacon Dacon Software Consulting Nov 15 '05 #10

 P: n/a Hi Tom, Way to go! ;-)) Regards, Fergus Nov 15 '05 #11

### This discussion thread is closed

Replies have been disabled for this discussion.