Home > Back-end >  Code cleanup, How to split a class in multiple classes
Code cleanup, How to split a class in multiple classes

Time:03-01

I have a Unity project (a game) with the main logic all in one file. I don't want use the Unity tag because the question is definitely more C# oriented, but it's useful to know that the main class already inherits MonoBehaviour.

What I would like to do is split the main class into multiple classes in the best possible way and modifying as little code as possible.

This code below represents the structure as it is now (obviously the code is invented for the example).

public class Main : MonoBehaviour {

    public OtherClass1 otherClass1;
    private OtherClass2 otherClass2;

    public String var1;
    private String var2;

    void Start() {
    } 

    public void Func1() {
        var1 = "test";
        var1 = Func2(var1);
    }

    private void Func2(string _var1) {
        return "random"   _var1   var2;
    }

    // And other 2.500 rows of funcuntions...
}

This is the best I was able to do, but I hope someone has a better and cleaner solution.

public class Main : MonoBehaviour {

    public OtherClass1 otherClass1;
    private OtherClass2 otherClass2;

    public String var1;
    private String var2;

    private InitGame initGame;

    void Start() {
        initGame = new InitGame();
    } 

    public void Func1() {
        var1 = "test";
        var1 = initGame.Func2(this, var1);
    }

    // And other 2.500 rows of funcuntions...
}



public class InitGame() {

    private void Func2(Main _main, string _var1) {
        return "random"   _var1   _main.var2;
    }

    // And all other function relative to the game initialization...

}

The ideal would be to create classes with direct access to all the content (variables, functions, classes) of Main, without having to pass the reference.

Thanks

CodePudding user response:

You could use partial classes. A partial class is simply a class whose code is spilt among several code files. Every part of the class has access to all members of all parts. This approach is used in winforms Forms. One file has a name like Form1.designer.cs and is created by the form designer. The other one is named, e.g., Form1.cs and is the place where you put your user code.

You could have files like

// File: Main.cs
public partial class Main : MonoBehaviour {
}
// File: Main.attackLogic.cs
public partial class Main{
}
// File: Main.defenceLogic.cs
public partial class Main{
}

and so on.

But it also makes sense to have real separate classes for specific services. Especially if the logic and the corresponding data is self-contained. If those classes need to access the members of the main class, you must pass it a reference to the main class. This is best done in a constructor parameter and is a very common practice.


Another way to communicate with the main class is through user defined events. E.g. you could have a health service exposing an event:

public event Action<int> CriticalAlert;

in the logic of the service the event would be triggered like this

private int _health;
public int Health
{
    get { return _health; }
    set {  
        int oldHealth = _health;
        _health = value;
        if (oldHealth > CriticalLevel && _health <= CriticalLevel) {
            CriticalAlert?.Invoke(_health);
        }
    }
}

The main class then subscribes the event like this

_healthService = new HealthService(this);
_healthService.CriticalAlert  = HealthService_CriticalAlert;

The handler looks like this:

private void HealthService_CriticalAlert(int health)
{
    ...
}

Both approaches (partial and real classes) can be combined.

See also: Partial Classes and Methods (C# Programming Guide)

CodePudding user response:

Partial classes is the way to go.

You can even reference stuff between them and they will act as one.

  • Related