黑板类
1、概述
黑板类(BlackBoard)是一个轻量级数据管理工具,采用静态门面模式设计,为业务逻辑层提供简洁统一的数据存储和访问接口。该工具支持多线程安全操作,能够存储和管理任意类型的数据。
2、设计架构
双层架构设计
黑板类采用双层架构设计,分离接口层和实现层:
静态门面类(BlackBoard)
定位:面向业务逻辑的简洁接口层
特点:提供静态方法,无需实例化即可使用
功能:封装底层实现,简化调用方式
/// <summary>
/// 黑板数据静态门面类,提供数据存储、检索和管理的统一接口。
/// </summary>
public static class BlackBoard
{
// 设置指定类型和键的数据。
public static void Set<T>(string key, T value)
=> BlackBoardImpl.Set<T>(key, value);
// 获取指定类型和键的数据。
public static T Get<T>(string key)
=> BlackBoardImpl.Get<T>(key);
// 移除指定类型和键的数据。
public static void Remove<T>(string key)
=> BlackBoardImpl.Remove<T>(key);
// 清空所有存储的数据。
public static void Clear()
=> BlackBoardImpl.Clear();
}
实现类(BlackBoardImpl)
定位:内部数据管理实现层
特点:线程安全的数据存储机制
功能:实际的数据存储、检索和管理逻辑
using System;
using System.Collections.Generic;
/// <summary>
/// 黑板数据管理类,负责存储与检索任意类型的数据,按类型与键区分,支持线程安全操作。
/// </summary>
internal static class BlackBoardImpl
{
// 内部数据存储结构,按类型与键区分。
private static readonly Dictionary<Type, Dictionary<string, object>> _dataStore = new();
private static readonly object _lock = new();
// 设置指定类型与键的数据。
public static void Set<T>(string key, T value) where T : notnull
{
var type = typeof(T);
lock (_lock)
{
if (!_dataStore.ContainsKey(type))
_dataStore[type] = new Dictionary<string, object>();
_dataStore[type][key] = value;
}
}
// 获取指定类型与键的数据。
public static T Get<T>(string key) where T : notnull
{
var type = typeof(T);
lock (_lock)
{
if (_dataStore.ContainsKey(type) && _dataStore[type].ContainsKey(key))
return (T)_dataStore[type][key];
return default;
}
}
// 移除指定类型与键的数据。
public static void Remove<T>(string key) where T : notnull
{
var type = typeof(T);
lock (_lock)
{
if (_dataStore.ContainsKey(type))
_dataStore[type].Remove(key);
}
}
// 清空所有存储的数据。
public static void Clear()
{
lock (_lock)
{
_dataStore.Clear();
}
}
}
核心功能
1. 数据存储
// 存储任意类型数据
BlackBoard.Set("player_health", 100);
BlackBoard.Set("player_name", "John");
BlackBoard.Set("player_position", new Vector3(1, 2, 3));
2. 数据检索
// 按类型安全检索数据
int health = BlackBoard.Get<int>("player_health");
string name = BlackBoard.Get<string>("player_name");
Vector3 position = BlackBoard.Get<Vector3>("player_position");
3. 数据管理
// 移除特定数据
BlackBoard.Remove<int>("player_health");
// 清空所有数据
BlackBoard.Clear();
3、特性说明
类型安全
使用泛型约束确保类型安全
编译时类型检查,避免运行时类型错误
支持所有Unity常用数据类型
线程安全
使用lock机制确保多线程环境下的数据一致性
所有操作均为原子操作
避免数据竞争和并发访问问题
高性能
字典结构实现快速数据访问
按类型分层存储,提高检索效率
静态方法调用,减少对象创建开销
4、内部实现机制
数据存储结构
// 两层字典结构:类型 → 键值对
Dictionary<Type, Dictionary<string, object>> _dataStore
线程同步机制
private static readonly object _lock = new();
lock (_lock)
{
// 线程安全操作
}
类型约束
使用
where T : notnull
约束,避免空值问题支持值类型和引用类型的统一存储
5、使用场景
游戏状态管理
// 存储游戏全局状态
BlackBoard.Set("game_state", GameState.Playing);
BlackBoard.Set("score", 1000);
BlackBoard.Set("level", 5);
组件间通信
// 不同组件间共享数据
public class PlayerController : MonoBehaviour
{
void Update()
{
BlackBoard.Set("player_position", transform.position);
}
}
public class CameraController : MonoBehaviour
{
void LateUpdate()
{
Vector3 position = BlackBoard.Get<Vector3>("player_position");
// 相机跟随逻辑
}
}
配置数据管理
// 存储游戏配置
BlackBoard.Set("game_config", configData);
BlackBoard.Set("audio_volume", 0.8f);
6、注意事项
键名规范:建议使用有意义的键名,避免冲突
类型匹配:存储和检索时必须使用相同的类型
内存管理:及时清理不再使用的数据
性能考虑:频繁操作时注意性能影响
黑板类通过静态门面模式提供了简洁高效的数据存储解决方案。线程安全特性和类型安全设计特别适合在游戏开发场景中使用。