There are many different ways of referencing one component to another, each with their own advantages and disadvantages.
|Get Component||Call the GetComponent method whenever you need another component.|
|Get Component Cached||Call the GetComponent method on startup and store it in a field.|
|Require Component||Use a [RequireComponent] attribute so Unity will ensure that the other component exists.|
|Serialize Field||Use a serialized field and assign the reference in the Inspector.|
|Reset Method||Use a Reset method to automatically assign a serialized field.|
|On Validate Method||Use an OnValidate method to automatically assign a serialized field.|
|Extension Methods||Use extension methods to simplify the OnValidate approach.|
Each approach has its merits, but I personally find using Extension Methods in the OnValidate Method to be the most effective because it gives flexible code that isn't directly tied to a specific hierarchy configuration and also makes it easy for non-programmers to use the scripts because they can easily see when other components are required but it will still try to automatically find those components so they don't need to be assigned manually.