introduction
Il existe un grand nombre de modèles et d'anti-modèles de programmation. Souvent, l'utilisation de modèles nous dicte l'expérience et la connaissance réelle d'eux-mêmes. Dans cet article, je veux discuter avec vous de l'application du modèle Singleton , à savoir son implémentation dans Net appliquée à Unity.
Singleton
Je note que j'écris du code dans une équipe, donc je prends autant de travail que possible à l'intérieur du code afin de décharger l'équipe et d'éliminer le besoin de réfléchir à certaines des difficultés de mise en œuvre de certains modèles dans Unity.
En étudiant la littérature sur Net 1 , en relation avec cette question 2, et à la suite de travaux sur plusieurs projets, la classe suivante est née:
using UnityEngine;
public class Singleton<T> : MonoBehaviour where T : Singleton<T>
{
private static T instance = null;
private bool alive = true;
public static T Instance
{
get
{
if (instance != null)
{
return instance;
}
else
{
T[] managers = GameObject.FindObjectsOfType<T>();
if (managers != null)
{
if (managers.Length == 1)
{
instance = managers[0];
DontDestroyOnLoad(instance);
return instance;
}
else
{
if (managers.Length > 1)
{
Debug.LogError($"Have more that one {typeof(T).Name} in scene. " +
"But this is Singleton! Check project.");
for (int i = 0; i < managers.Length; ++i)
{
T manager = managers[i];
Destroy(manager.gameObject);
}
}
}
}
GameObject go = new GameObject(typeof(T).Name, typeof(T));
instance = go.GetComponent<T>();
instance.Initialization();
DontDestroyOnLoad(instance.gameObject);
return instance;
}
}
set
{
instance = value as T;
}
}
public static bool IsAlive
{
get
{
if (instance == null)
return false;
return instance.alive;
}
}
protected void Awake()
{
if (instance == null)
{
DontDestroyOnLoad(gameObject);
instance = this as T;
Initialization();
}
else
{
Debug.LogError($"Have more that one {typeof(T).Name} in scene. " +
"But this is Singleton! Check project.");
DestroyImmediate(this);
}
}
protected void OnDestroy() { alive = false; }
protected void OnApplicationQuit() { alive = false; }
protected virtual void Initialization() { }
}
Je vais me concentrer sur plusieurs aspects.
Création d'objets
Lorsque vous développez un projet, et plus encore en travaillant en équipe> 3 personnes, une situation survient souvent lorsque la séquence de création d'objets devient floue. Strictement parlant 3 , la séquence d'appels à Awake () est aléatoire (bien sûr, ce n'est pas entièrement vrai, et le processus peut être influencé, mais la documentation est sacrée), c'est pourquoi il est nécessaire d'éliminer cet inconvénient gênant en implémentant la propriété Instance {get;} . En conséquence, nous obtenons un accès complet au singleton à partir de Awake () d' autres classes.
, Lazy, Awake() .
4-4, , Instance{get;}.
Unity — Awake(). , , Initialization(). (KISS).
, DI SD. . .
, , OnDestroy(), OnApplicationQuit() 5:
Did you spawn new GameObjects from OnDestroy?
, , , . , IsAlive(), , . , ...
De plus en plus, j'arrive à la conclusion qu'en utilisant le paradigme Unity, il est possible de mettre en œuvre mes projets sans Singleton. Souvent, l'application de ce modèle rend votre code hautement connecté et extrêmement fragile.
Remercier.
Sources
- Richter J. "CLR via C #. Programmation sur Microsoft.NET # Framework 4.5 en C #", 2013
- https://www.codingame.com/playgrounds/1979/different-ways-to-implement-singleton-in--net-and-make-people-hate-you-along-the-way
- https://docs.unity3d.com/en/current/ScriptReference/MonoBehaviour.Awake.html
- https://ru.wikipedia.org/wiki/Design_Patterns
- Dickinson Chris "Optimisation du jeu Unity 2017, deuxième édition", 2017