yorickyao
yorickyao
发布于 2025-10-14 / 31 阅读
0
0

🧩基于Unity的简单框架工具类(4)

黑板类

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、注意事项

  • 键名规范​:建议使用有意义的键名,避免冲突

  • 类型匹配​:存储和检索时必须使用相同的类型

  • 内存管理​:及时清理不再使用的数据

  • 性能考虑​:频繁操作时注意性能影响

黑板类通过静态门面模式提供了简洁高效的数据存储解决方案。线程安全特性和类型安全设计特别适合在游戏开发场景中使用。


评论