Question

I need a system of classes that describes a planetary system.

My first class is an atomary space body:

public class SpaceBody
{
    public string Name;
    public float Mass;
   // and so on
}

The second one is a system of space bodies and it also is SpaceBody:

public class SpaceBodySystem<ChildType>: SpaceBody where ChildType: SpaceBody, new()
{
    // ...
    public List<ChildType> Children;
    // ...
}

Next, I have a star:

public class Star: SpaceBodySystem<SpaceBody>
{
    public float Intencity;
    // ...
}

And finally, the whole star system is something like this (it can have more than one star):

public class StarSystem: SpaceBodySystem<Star>
{
    public bool OccupiedByAliens;
    // ...
}

The problem is: The stars should have planets (SpaceBodySystem) which in turn, may have their satellites and those satellites also may have their own satellites and so on... nesting depth is unlimited.

It's impossible with my current class system. I have to write something like this but this ugly solution has limited hierarchy level.

public class StarSystem: SpaceBodySystem<SpaceBodySystem<SpaceBodySystem<SpaceBody>>>
{
    public float Intencity;
    // ...
}

I ask the community to give me some advises how this structure can be improved. I thought about other scheme (interfaces, composition + delegation) and didn't managed to get an acceptable solution.

Many thanks for any help.

Was it helpful?

Solution

If you need the possibility to have multiple suns in a system, maybe you also want the possibility of two planets sharing a moon.

In that case, maybe you should have a SubSystem, which has an array of main bodies and an array of satellites. In a solar system, you can use stars as the main bodies and the planets as satellites. In a galaxy, maybe you can define some abstract centerpoint/waypoint as the main body and all the solar systems are satellites.

So for our solar system, you've got the SubSystem 'SolarSystem', with main body Sun and sattelites planets, each of which are subsystems as well. Subsystem Earth has a main body Earth and a satelite Moon.

Having a SubSystem Earth with one MainBody Earth might sound a bit redundant, but maybe you can solve that by using interfaces, so a simple subsystem like that (with one main body) can be implemented by a single class that implements both ISubSystem and IMainBody.

Or you can keep the implementation easier and make Earth(system) a separate subsystem with an array with one main body, which is Earth(planet) and an array with one satelite, which is the SubSystem Moon(system), containing main body Moon and no satellites.

OTHER TIPS

I think one class will do to set up a planetary system:

public class SpaceBody
{
    public string Name;
    public float Mass;
    public float Distance;
    public bool clockwise;
    //...
    public SpaceBody RevolvesAround;
    List<SpaceBody> Satellites;

}

If your base class for systems can have children which are themselves instances of, or derived from, that same base class, then you don't need to nest like that. Let me give an example:

public class SpaceBodySystem<ChildType>: SpaceBody where ChildType: SpaceBody, new()
{
    public List<ChildType> Children;
}

So, a SpaceBodySystem has children that are SpaceBody types, and it is itself a SpaceBody.

public class StarSystem : SpaceBodySystem<Star>
{
}

This class can represent a star, or a binary pair of two stars, or whatever.

public class PlanetarySystem : SpaceBodySystem<Moon>
{
    public Planet CentralPlanet;
}

This can represent a planet with any number of moons, where Planet inherits from SpaceBody.

public class SolarSystem : SpaceBodySystem<PlanetarySystem>
{
    public StarSystem CoreStar;
}

This class can now represent a solar system with some configuration of stars, and children which are all planets which may have moons.

In short, you don't need to keep nesting SpaceBodySystem<SpaceBodySystem<SpaceBodySystem<SpaceBody>>> because SpaceBodySystem inherits from SpaceBody, so if you just have SpaceBodySystem<SpaceBody>, then that inner SpaceBody might be a SpaceBodySystem, which might have further children, but you don't need to know that. That's the beauty of polymorphism.

Need to say in addition, I want to load my system from data file. Suppose, I have this input data (in attachment). And I have virtual method that reads and creates an object of SapceBody.

class SpaceBody...
{
    ...
    public virtual void CreateGameObject()
    {
        instance = new GameObject();
    }
    ...
}

class SpaceBodySystem...
{
    ...
    public override void CreateGameObject()
    {
        base.GameObject();
        foreach(ChildType child in Children)
        {
            child.CreateGameObject();
        }
    }
    ...
}


class Star: SpaceBodySytem<SpaceBody>
{
    ...
    public override void CreateGameObject()
    {
        base.GameObject();
        doExtraWorkForTheStar();
    }
    ...
}

StarSystem.CreateObject();
 // for attached file, will load and create one star (Sun) and nine planets.

So, if I use the declaration proposed by anaximander, the system doesn't see children of children. For example, the Earth is SpaceBody (but should be SpaceBodySytem) and will not create Moon in this case.

The GolezTrol's idea is fine.

solarsystem.json

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top