官术网_书友最值得收藏!

Static Classes

This approach involves creating a class that is globally accessible to the entire codebase at any time. Any kind of global manager class is often frowned upon in software engineering circles, partly since the name manager is vague and doesn't say much about what it's meant to do, but mostly because problems can be difficult to debug. Changes can occur from anywhere and at any point during runtime, and such classes tend to maintain state information that other systems rely upon. It is also perhaps the most difficult approach to change or replace, since many of our classes might contain direct function calls into it, requiring each to be modified at a future date if it were to be replaced. Despite all of these drawbacks, it is by far the easiest solution to understand and implement.

The Singleton design pattern is a common way of ensuring only one instance of a certain object type ever exists in memory. This design pattern is implemented by giving the class a private constructor, a static variable is maintained to keep track of the object instance, and the class can only be accessed through a static property it provides. Singletons can be useful for managing shared resources or heavy data traffic, such as file access, downloads, data parsing, and messaging. A Singleton ensures that we have a single entry point for such activities, rather than having tons of different subsystems competing for shared resources and potentially bottlenecking one another.

Singletons don't necessarily have to be globally accessible objects--their most important feature is that only a single instance of the object exists at a time. However, the way that Singletons are primarily used in most projects is to be a global access point to some shared functionality, and are designed to be created once during application initialization, persist through the entire lifecycle of the application, and only destroyed during application shutdown. As such, a simpler way of implementing this kind of behavior in C# is to use a Static Class. In other words, implementing the typical Singleton design pattern in C# just provides the same behavior as a Static Class, but takes more time and code to implement.

A Static Class that functions in much the same way as the EnemyManagerComponent as demonstrated in the previous example, can be defined as follows:

using System.Collections.Generic;
using UnityEngine;

public static class StaticEnemyManager {
private static List<Enemy> _enemies;

public static void CreateEnemy(GameObject prefab) {
string[] names = { "Tom", "Dick", "Harry" };
GameObject enemy = GameObject.Instantiate(prefab, 5.0f *
Random.insideUnitSphere, Quaternion.identity);
Enemy enemyComp = enemy.GetComponent<Enemy>();
enemy.gameObject.name = names[Random.Range(0, names.Length)];
_enemies.Add(enemyComp);
}

public static void KillAll() {
for (int i = 0; i < _enemies.Count; ++i) {
_enemies[i].Die();
GameObject.Destroy(_enemies[i].gameObject);
}
_enemies.Clear();
}
}

Note that every method, property, and field in a Static Class must have the static keyword attached, which implies that only one instance of this object will ever reside in memory. This also means that its public methods and fields are accessible from anywhere. Static Classes, by definition, do not allow any non-static fields to be defined.

If a Static Class' fields need to be initialized (such as the _enemies field, which is initially set to null), then Static Class fields can be initialized inline like so:

private static List<Enemy> _enemies = new List<Enemy>();

However, if object construction needs to be more complicated than this, then Static Classes can be given a static constructor, instead. The Static Class' constructor is automatically called the moment the class is first accessed through any it's fields, properties, or methods, and can be defined like so:

static StaticEnemyManager() {
_enemies = new List<Enemy>();
// more complicated initialization activity goes here
}

This time we have implemented the CreateEnemy() method so that it handles much of the activity for creating an enemy object. However, the Static Class must still be given a reference to a Prefab from which it can instantiate an enemy object from. A Static Class can only contain static member variables, and therefore cannot easily interface with the Inspector window in the same way that MonoBehaviours can, therefore requiring the caller to provide some implementation-specific information to it. To solve this problem, we could implement a companion-Component for our Static Class to keep our code properly Decoupled. The following code demonstrates what this class might look like:

using UnityEngine;

public class EnemyCreatorCompanionComponent : MonoBehaviour {
[SerializeField] private GameObject _enemyPrefab;

public void CreateEnemy() {
StaticEnemyManager.CreateEnemy(_enemyPrefab);
}
}

Despite these drawbacks, the StaticEnemyManager class illustrates a simple example of how a Static Class might be used to provide information or communication between external objects, providing a better alternative than using Find() or SendMessage().

主站蜘蛛池模板: 松溪县| 醴陵市| 济宁市| 汤阴县| 芜湖县| 西青区| 南召县| 高碑店市| 彭山县| 宜川县| 鹤山市| 公主岭市| 德庆县| 永仁县| 宝山区| 老河口市| 绥中县| 定安县| 尼勒克县| 郯城县| 克拉玛依市| 监利县| 陕西省| 高青县| 江达县| 朝阳区| 东阿县| 溆浦县| 车险| 竹北市| 铜梁县| 广宗县| 军事| 朔州市| 平遥县| 瑞丽市| 澎湖县| 五峰| 花莲县| 布拖县| 东莞市|