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

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().

主站蜘蛛池模板: 木兰县| 隆尧县| 德令哈市| 同心县| 思茅市| 焉耆| 漳州市| 五华县| 三台县| 荔波县| 色达县| 阜康市| 武威市| 郁南县| 武隆县| 南昌市| 安远县| 阿尔山市| 塔城市| 乌审旗| 洱源县| 利津县| 南江县| 墨江| 六安市| 巴青县| 凌海市| 丹寨县| 古交市| 河源市| 长宁县| 芷江| 卢氏县| 盈江县| 嘉鱼县| 林周县| 尉犁县| 曲阳县| 山阴县| 嘉义市| 花莲县|