I have a static class called RenderingUtilities
that houses several useful methods and constants. Some of these constants are related to the Earth as an object such as the Earth's radius. I believe the constants related to the Earth should be contained in the Earth
class, but have conflicting thoughts on it since the RenderingUtilities
class shouldn't really depend on other objects.
The reason for this is that the Earth
class is an object that can be rendered to the screen. Thus it has a base class of RenderObject
and has properties and methods on its own. It will also rely on the RenderingUtilities
class to retrieve a geometric primitive in order to render. Thus this seems like circumnavigation to me.
However, my counter argument to my own counter argument is that since these are const
values and are accessed without creating an instance of the Earth
class, that it should be okay.
Rendering Utilities Class
The RenderingUtilities
class is a collection of helpful methods with the following categories:
- Conversions
- Assistive Rendering
- Simplifying the process of rendering text.
- Simplifying the process of rendering 2D polygons.
A very simple example method is the conversion from degrees to radians:
public static double ToRadians(this double degrees) => degrees * Math.PI / 180.0;
This allows quick access through the double
type, along with accessing it through the static class:
double radians = RenderingUtilities.ToRadians(45);
double degrees = 90;
radians = degrees.ToRadians();
There are more, but this should help add some clarity as to what the RenderingUtilities
class is helping with. There is no need to create individual classes for these helpful methods, and they are used quite often, such as rendering text that displays the position of the camera for debugging, or frame rate, or error messages, etc. There are practical applications such as rendering detailed information about a specific point on the Earth. However, the methods are generic enough that you supply a screen position, some text, and a color, and it displays it.
Render Object Class
The RenderObject
class is an abstract base class that is home to the fundamentals of each object rendered to the screen; such as:
public abstract class RenderObject {
#region Fields
private List<RenderObject> children = new List<RenderObject>();
#endregion
#region Properties
public bool Active { get; set; } = false;
public string Name { get; set; } = string.Empty;
public RenderObject Parent { get; protected set; } = null;
public RenderObject[] Children => children.ToArray();
#endregion
#region Public Methods
public abstract void Initialize();
public abstract void Update();
public abstract void Render();
#endregion
}
Earth Class
This class is derived from the class RenderObject
(see above). It is responsible for, well, rendering the Earth. This includes local instances of classes (also deriving from RenderObject
) such as:
- Gridlines
- Terrain
- Water
- etc.
The flow of the code there is very object oriented and that is what caused me to come here and pose this question.
The Current Placement of the Constants
The reason these constants are kept within the RenderingUtilities
class is due to the extensive use of those constants in conversion methods mentioned above. However, since they are related to the Earth
per se, I believe it may make more sense to move them there. For example:
// Doesn't make much sense.
RenderingUtilities.EARTH_RADIUS_IN_METERS
// Makes more sense.
Earth.RADIUS_IN_METERS
The Question
Is there an issue with regards to OOP practices that would prevent me from putting these constants in the Earth
class and using them in the static RenderingUtilities
class?
RenderingUtilities
class? Why did you couple your domain object (theEarth
class) with your rendering framework? Why does your domain object need to expose its internals (its constants)? Object-oriented design is more than just creating classes, and while I believe it will be next-to-impossible to answer your question without more details, you should know that one of the goals of OO is to encapsulate state within its own class so it doesn't get exposed to the outside world.