GFramework/docs/zh-CN/tutorials/large-project-organization.md
GeWuYou 9edf64193f docs(architecture): 更新架构设计模式指南文档
- 将标题从"架构模式最佳实践"改为"架构设计模式指南"
- 添加全面的架构设计模式介绍和概述
- 新增MVC模式详细说明,包括概念、GFramework实现示例和最佳实践
- 新增MVVM模式详细说明,包括概念、GFramework实现示例和最佳实践
- 新增命令模式详细说明,包括概念、实现示例和撤销功能支持
- 新增查询模式详细说明,包括CQRS概念和复杂查询示例
- 新增事件驱动模式详细说明,包括事件定义和监听实现
- 新增依赖注入模式详细说明,包括构造函数注入示例
- 新增服务定位器模式详细说明,包括与依赖注入对比
- 新增对象池模式详细说明,包括通用对象池实现
- 新增状态模式详细说明,包括异步状态和状态机系统
- 补充模式选择与组合建议,针对小型、中型、大型项目提供不同方案
- 更新代码示例中的泛型语法格式,统一使用尖括号表示法
2026-03-07 17:32:26 +08:00

47 KiB

title, description
title description
大型项目组织 学习如何使用 GFramework 组织和管理大型游戏项目

大型项目组织

学习目标

完成本教程后,你将能够:

  • 理解大型游戏项目的组织原则
  • 设计清晰的项目结构和模块划分
  • 实现分层架构和依赖管理
  • 使用模块化设计分离功能
  • 建立代码组织规范和团队协作流程
  • 应用最佳实践提高项目可维护性

前置条件

步骤 1: 项目结构设计

首先,让我们设计一个清晰的项目结构,将代码按功能和层次组织。

1.1 推荐的目录结构

MyLargeGame/
├── src/
│   ├── MyGame.Core/                    # 核心层
│   │   ├── Architecture/               # 架构定义
│   │   │   ├── GameArchitecture.cs
│   │   │   └── GameContext.cs
│   │   ├── Constants/                  # 常量定义
│   │   │   ├── GameConstants.cs
│   │   │   └── LayerConstants.cs
│   │   └── Extensions/                 # 扩展方法
│   │       └── GameExtensions.cs
│   │
│   ├── MyGame.Domain/                  # 领域层
│   │   ├── Models/                     # 数据模型
│   │   │   ├── Player/
│   │   │   │   ├── PlayerModel.cs
│   │   │   │   └── PlayerStatsModel.cs
│   │   │   ├── Inventory/
│   │   │   │   ├── InventoryModel.cs
│   │   │   │   └── ItemModel.cs
│   │   │   └── Combat/
│   │   │       ├── CombatModel.cs
│   │   │       └── SkillModel.cs
│   │   ├── Events/                     # 领域事件
│   │   │   ├── Player/
│   │   │   │   ├── PlayerLevelUpEvent.cs
│   │   │   │   └── PlayerHealthChangedEvent.cs
│   │   │   └── Combat/
│   │   │       └── DamageDealtEvent.cs
│   │   └── Enums/                      # 枚举定义
│   │       ├── ItemType.cs
│   │       └── SkillType.cs
│   │
│   ├── MyGame.Application/             # 应用层
│   │   ├── Systems/                    # 业务系统
│   │   │   ├── Player/
│   │   │   │   ├── PlayerSystem.cs
│   │   │   │   └── PlayerLevelSystem.cs
│   │   │   ├── Inventory/
│   │   │   │   └── InventorySystem.cs
│   │   │   └── Combat/
│   │   │       ├── CombatSystem.cs
│   │   │       └── SkillSystem.cs
│   │   ├── Commands/                   # 命令
│   │   │   ├── Player/
│   │   │   │   └── MovePlayerCommand.cs
│   │   │   └── Inventory/
│   │   │       └── AddItemCommand.cs
│   │   ├── Queries/                    # 查询
│   │   │   ├── Player/
│   │   │   │   └── GetPlayerStatsQuery.cs
│   │   │   └── Inventory/
│   │   │       └── GetItemsQuery.cs
│   │   └── Utilities/                  # 工具类
│   │       ├── MathUtility.cs
│   │       └── PathfindingUtility.cs
│   │
│   ├── MyGame.Infrastructure/          # 基础设施层
│   │   ├── Data/                       # 数据访问
│   │   │   ├── Repositories/
│   │   │   │   ├── PlayerRepository.cs
│   │   │   │   └── SaveRepository.cs
│   │   │   └── Serializers/
│   │   │       └── JsonGameSerializer.cs
│   │   ├── Resources/                  # 资源管理
│   │   │   ├── AssetLoader.cs
│   │   │   └── ResourceCache.cs
│   │   └── Services/                   # 外部服务
│   │       ├── AudioService.cs
│   │       └── NetworkService.cs
│   │
│   ├── MyGame.Presentation/            # 表现层
│   │   ├── Controllers/                # 控制器
│   │   │   ├── Player/
│   │   │   │   └── PlayerController.cs
│   │   │   └── UI/
│   │   │       └── UIController.cs
│   │   ├── Views/                      # 视图
│   │   │   ├── HUD/
│   │   │   │   ├── HealthBarView.cs
│   │   │   │   └── MiniMapView.cs
│   │   │   └── Menus/
│   │   │       ├── MainMenuView.cs
│   │   │       └── InventoryView.cs
│   │   └── ViewModels/                 # 视图模型
│   │       └── InventoryViewModel.cs
│   │
│   └── MyGame.Modules/                 # 功能模块
│       ├── PlayerModule/
│       │   └── PlayerModule.cs
│       ├── CombatModule/
│       │   └── CombatModule.cs
│       ├── InventoryModule/
│       │   └── InventoryModule.cs
│       └── QuestModule/
│           └── QuestModule.cs
│
├── tests/
│   ├── MyGame.Core.Tests/
│   ├── MyGame.Domain.Tests/
│   └── MyGame.Application.Tests/
│
└── docs/
    ├── architecture.md
    ├── coding-standards.md
    └── api/

结构说明:

  • Core: 核心架构和基础设施,不依赖其他层
  • Domain: 领域模型和业务规则,纯业务逻辑
  • Application: 应用服务和用例,协调领域对象
  • Infrastructure: 技术实现,如数据访问、资源加载
  • Presentation: 表现层,处理用户交互和显示
  • Modules: 功能模块,封装完整的功能单元

1.2 创建核心架构

using GFramework.Core.architecture;
using GFramework.Core.Abstractions.architecture;

namespace MyGame.Core.Architecture
{
    /// <summary>
    /// 游戏主架构
    /// </summary>
    public class GameArchitecture : Architecture
    {
        public static IArchitecture Interface { get; private set; }

        protected override void Init()
        {
            Interface = this;

            Console.WriteLine("初始化游戏架构...");
        }

        protected override void InstallModules()
        {
            // 模块将在步骤 3 中安装
            Console.WriteLine("安装功能模块...");
        }
    }
}

步骤 2: 架构分层

实现清晰的分层架构,确保各层职责明确,依赖关系单向。

2.1 领域层 - 玩家模型

using GFramework.Core.model;
using GFramework.Core.property;

namespace MyGame.Domain.Models.Player
{
    /// <summary>
    /// 玩家数据模型
    /// </summary>
    public class PlayerModel : AbstractModel
    {
        // 基础属性
        public BindableProperty<string> Name { get; } = new("Player");
        public BindableProperty<int> Level { get; } = new(1);
        public BindableProperty<int> Experience { get; } = new(0);

        // 战斗属性
        public BindableProperty<int> Health { get; } = new(100);
        public BindableProperty<int> MaxHealth { get; } = new(100);
        public BindableProperty<int> Mana { get; } = new(50);
        public BindableProperty<int> MaxMana { get; } = new(50);

        // 位置信息
        public BindableProperty<float> PositionX { get; } = new(0f);
        public BindableProperty<float> PositionY { get; } = new(0f);
        public BindableProperty<float> PositionZ { get; } = new(0f);

        protected override void OnInit()
        {
            Console.WriteLine($"玩家模型初始化: {Name.Value}");

            // 监听等级变化
            Level.Register(OnLevelChanged);
        }

        private void OnLevelChanged(int newLevel)
        {
            Console.WriteLine($"玩家升级到 {newLevel} 级");

            // 升级时恢复生命值和法力值
            Health.Value = MaxHealth.Value;
            Mana.Value = MaxMana.Value;
        }

        /// <summary>
        /// 受到伤害
        /// </summary>
        public void TakeDamage(int damage)
        {
            Health.Value = Math.Max(0, Health.Value - damage);

            if (Health.Value == 0)
            {
                Console.WriteLine("玩家死亡");
            }
        }

        /// <summary>
        /// 获得经验
        /// </summary>
        public void GainExperience(int exp)
        {
            Experience.Value += exp;

            // 检查是否升级
            int expNeeded = GetExperienceForNextLevel();
            if (Experience.Value >= expNeeded)
            {
                LevelUp();
            }
        }

        private void LevelUp()
        {
            Level.Value++;
            Experience.Value = 0;

            // 提升属性
            MaxHealth.Value += 10;
            MaxMana.Value += 5;
        }

        private int GetExperienceForNextLevel()
        {
            return Level.Value * 100;
        }
    }
}

2.2 领域层 - 领域事件

using GFramework.Core.Abstractions.events;

namespace MyGame.Domain.Events.Player
{
    /// <summary>
    /// 玩家升级事件
    /// </summary>
    public record PlayerLevelUpEvent(int NewLevel, int OldLevel) : IEvent;

    /// <summary>
    /// 玩家生命值变化事件
    /// </summary>
    public record PlayerHealthChangedEvent(int NewHealth, int OldHealth, int MaxHealth) : IEvent;

    /// <summary>
    /// 玩家死亡事件
    /// </summary>
    public record PlayerDeathEvent(string Reason) : IEvent;

    /// <summary>
    /// 玩家位置变化事件
    /// </summary>
    public record PlayerPositionChangedEvent(float X, float Y, float Z) : IEvent;
}

2.3 应用层 - 玩家系统

using GFramework.Core.system;
using GFramework.Core.Abstractions.events;
using MyGame.Domain.Models.Player;
using MyGame.Domain.Events.Player;

namespace MyGame.Application.Systems.Player
{
    /// <summary>
    /// 玩家管理系统
    /// </summary>
    public class PlayerSystem : AbstractSystem
    {
        private PlayerModel _playerModel;
        private IEventBus _eventBus;

        protected override void OnInit()
        {
            // 获取依赖
            _playerModel = this.GetModel<PlayerModel>();
            _eventBus = this.GetService<IEventBus>();

            // 监听玩家属性变化
            _playerModel.Level.Register(OnLevelChanged);
            _playerModel.Health.Register(OnHealthChanged);

            Console.WriteLine("玩家系统初始化完成");
        }

        private void OnLevelChanged(int newLevel)
        {
            // 发布升级事件
            _eventBus.Publish(new PlayerLevelUpEvent(newLevel, newLevel - 1));
        }

        private void OnHealthChanged(int newHealth)
        {
            // 发布生命值变化事件
            _eventBus.Publish(new PlayerHealthChangedEvent(
                newHealth,
                _playerModel.Health.Value,
                _playerModel.MaxHealth.Value
            ));

            // 检查死亡
            if (newHealth == 0)
            {
                _eventBus.Publish(new PlayerDeathEvent("生命值耗尽"));
            }
        }

        /// <summary>
        /// 移动玩家
        /// </summary>
        public void MovePlayer(float x, float y, float z)
        {
            _playerModel.PositionX.Value = x;
            _playerModel.PositionY.Value = y;
            _playerModel.PositionZ.Value = z;

            _eventBus.Publish(new PlayerPositionChangedEvent(x, y, z));
        }

        /// <summary>
        /// 治疗玩家
        /// </summary>
        public void HealPlayer(int amount)
        {
            int newHealth = Math.Min(
                _playerModel.Health.Value + amount,
                _playerModel.MaxHealth.Value
            );

            _playerModel.Health.Value = newHealth;
            Console.WriteLine($"玩家恢复 {amount} 点生命值");
        }
    }
}

2.4 应用层 - 命令模式

using GFramework.Core.command;
using MyGame.Domain.Models.Player;

namespace MyGame.Application.Commands.Player
{
    /// <summary>
    /// 移动玩家命令
    /// </summary>
    public class MovePlayerCommand : AbstractCommand
    {
        private readonly float _x;
        private readonly float _y;
        private readonly float _z;
        private float _oldX;
        private float _oldY;
        private float _oldZ;

        public MovePlayerCommand(float x, float y, float z)
        {
            _x = x;
            _y = y;
            _z = z;
        }

        protected override void OnExecute()
        {
            var playerModel = this.GetModel<PlayerModel>();

            // 保存旧位置(用于撤销)
            _oldX = playerModel.PositionX.Value;
            _oldY = playerModel.PositionY.Value;
            _oldZ = playerModel.PositionZ.Value;

            // 移动到新位置
            playerModel.PositionX.Value = _x;
            playerModel.PositionY.Value = _y;
            playerModel.PositionZ.Value = _z;

            Console.WriteLine($"玩家移动到 ({_x}, {_y}, {_z})");
        }

        protected override void OnUndo()
        {
            var playerModel = this.GetModel<PlayerModel>();

            // 恢复旧位置
            playerModel.PositionX.Value = _oldX;
            playerModel.PositionY.Value = _oldY;
            playerModel.PositionZ.Value = _oldZ;

            Console.WriteLine($"撤销移动,返回 ({_oldX}, {_oldY}, {_oldZ})");
        }
    }
}

步骤 3: 模块化设计

使用 IArchitectureModule 将相关功能封装成独立模块。

3.1 创建玩家模块

using GFramework.Core.Abstractions.architecture;
using MyGame.Domain.Models.Player;
using MyGame.Application.Systems.Player;

namespace MyGame.Modules.PlayerModule
{
    /// <summary>
    /// 玩家功能模块
    /// </summary>
    public class PlayerModule : IArchitectureModule
    {
        public string Name => "PlayerModule";
        public string Version => "1.0.0";

        public void Install(IArchitecture architecture)
        {
            Console.WriteLine($"安装模块: {Name} v{Version}");

            // 注册玩家相关的 Model
            architecture.RegisterModel(new PlayerModel());

            // 注册玩家相关的 System
            architecture.RegisterSystem(new PlayerSystem());
            architecture.RegisterSystem(new PlayerLevelSystem());

            Console.WriteLine($"模块 {Name} 安装完成");
        }

        public void Uninstall(IArchitecture architecture)
        {
            Console.WriteLine($"卸载模块: {Name}");

            // 清理资源
            // 注意: GFramework 会自动处理组件的清理
        }
    }

    /// <summary>
    /// 玩家等级系统
    /// </summary>
    public class PlayerLevelSystem : AbstractSystem
    {
        protected override void OnInit()
        {
            var playerModel = this.GetModel<PlayerModel>();

            // 监听升级事件
            playerModel.Level.Register(level =>
            {
                Console.WriteLine($"等级系统: 玩家达到 {level} 级");
                CalculateStats(level);
            });
        }

        private void CalculateStats(int level)
        {
            // 根据等级计算属性
            Console.WriteLine($"重新计算 {level} 级的属性");
        }
    }
}

3.2 创建战斗模块

using GFramework.Core.Abstractions.architecture;
using GFramework.Core.system;
using MyGame.Domain.Models.Player;

namespace MyGame.Modules.CombatModule
{
    /// <summary>
    /// 战斗功能模块
    /// </summary>
    public class CombatModule : IArchitectureModule
    {
        public string Name => "CombatModule";
        public string Version => "1.0.0";

        public void Install(IArchitecture architecture)
        {
            Console.WriteLine($"安装模块: {Name} v{Version}");

            // 注册战斗系统
            architecture.RegisterSystem(new CombatSystem());
            architecture.RegisterSystem(new SkillSystem());
            architecture.RegisterSystem(new DamageCalculationSystem());

            Console.WriteLine($"模块 {Name} 安装完成");
        }

        public void Uninstall(IArchitecture architecture)
        {
            Console.WriteLine($"卸载模块: {Name}");
        }
    }

    /// <summary>
    /// 战斗系统
    /// </summary>
    public class CombatSystem : AbstractSystem
    {
        private PlayerModel _playerModel;

        protected override void OnInit()
        {
            _playerModel = this.GetModel<PlayerModel>();
            Console.WriteLine("战斗系统初始化完成");
        }

        /// <summary>
        /// 攻击目标
        /// </summary>
        public void Attack(string targetName, int damage)
        {
            Console.WriteLine($"玩家攻击 {targetName},造成 {damage} 点伤害");

            // 获取伤害计算系统
            var damageSystem = this.GetSystem<DamageCalculationSystem>();
            int finalDamage = damageSystem.CalculateDamage(damage);

            Console.WriteLine($"最终伤害: {finalDamage}");
        }
    }

    /// <summary>
    /// 技能系统
    /// </summary>
    public class SkillSystem : AbstractSystem
    {
        private readonly Dictionary<string, float> _cooldowns = new();

        protected override void OnInit()
        {
            Console.WriteLine("技能系统初始化完成");
        }

        /// <summary>
        /// 使用技能
        /// </summary>
        public bool UseSkill(string skillName, int manaCost)
        {
            var playerModel = this.GetModel<PlayerModel>();

            // 检查法力值
            if (playerModel.Mana.Value < manaCost)
            {
                Console.WriteLine($"法力值不足,无法使用 {skillName}");
                return false;
            }

            // 检查冷却
            if (_cooldowns.ContainsKey(skillName))
            {
                Console.WriteLine($"技能 {skillName} 冷却中");
                return false;
            }

            // 消耗法力值
            playerModel.Mana.Value -= manaCost;

            Console.WriteLine($"使用技能: {skillName}");
            return true;
        }
    }

    /// <summary>
    /// 伤害计算系统
    /// </summary>
    public class DamageCalculationSystem : AbstractSystem
    {
        protected override void OnInit()
        {
            Console.WriteLine("伤害计算系统初始化完成");
        }

        /// <summary>
        /// 计算最终伤害
        /// </summary>
        public int CalculateDamage(int baseDamage)
        {
            var playerModel = this.GetModel<PlayerModel>();

            // 根据等级增加伤害
            float levelBonus = 1.0f + (playerModel.Level.Value * 0.1f);
            int finalDamage = (int)(baseDamage * levelBonus);

            return finalDamage;
        }
    }
}

3.3 创建库存模块

using GFramework.Core.Abstractions.architecture;
using GFramework.Core.model;
using GFramework.Core.system;
using GFramework.Core.property;

namespace MyGame.Modules.InventoryModule
{
    /// <summary>
    /// 库存功能模块
    /// </summary>
    public class InventoryModule : IArchitectureModule
    {
        public string Name => "InventoryModule";
        public string Version => "1.0.0";

        public void Install(IArchitecture architecture)
        {
            Console.WriteLine($"安装模块: {Name} v{Version}");

            // 注册库存模型和系统
            architecture.RegisterModel(new InventoryModel());
            architecture.RegisterSystem(new InventorySystem());

            Console.WriteLine($"模块 {Name} 安装完成");
        }

        public void Uninstall(IArchitecture architecture)
        {
            Console.WriteLine($"卸载模块: {Name}");
        }
    }

    /// <summary>
    /// 物品数据
    /// </summary>
    public class Item
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public int Quantity { get; set; }
        public ItemType Type { get; set; }
    }

    public enum ItemType
    {
        Weapon,
        Armor,
        Consumable,
        Material,
        Quest
    }

    /// <summary>
    /// 库存模型
    /// </summary>
    public class InventoryModel : AbstractModel
    {
        public BindableProperty<int> MaxSlots { get; } = new(50);
        public BindableProperty<int> Gold { get; } = new(0);

        private readonly List<Item> _items = new();

        protected override void OnInit()
        {
            Console.WriteLine("库存模型初始化完成");
        }

        /// <summary>
        /// 添加物品
        /// </summary>
        public bool AddItem(Item item)
        {
            if (_items.Count >= MaxSlots.Value)
            {
                Console.WriteLine("库存已满");
                return false;
            }

            // 检查是否已有相同物品
            var existingItem = _items.FirstOrDefault(i => i.Id == item.Id);
            if (existingItem != null)
            {
                existingItem.Quantity += item.Quantity;
            }
            else
            {
                _items.Add(item);
            }

            Console.WriteLine($"添加物品: {item.Name} x{item.Quantity}");
            return true;
        }

        /// <summary>
        /// 移除物品
        /// </summary>
        public bool RemoveItem(string itemId, int quantity)
        {
            var item = _items.FirstOrDefault(i => i.Id == itemId);
            if (item == null)
            {
                Console.WriteLine($"物品不存在: {itemId}");
                return false;
            }

            if (item.Quantity < quantity)
            {
                Console.WriteLine($"物品数量不足: {item.Name}");
                return false;
            }

            item.Quantity -= quantity;
            if (item.Quantity == 0)
            {
                _items.Remove(item);
            }

            Console.WriteLine($"移除物品: {item.Name} x{quantity}");
            return true;
        }

        /// <summary>
        /// 获取所有物品
        /// </summary>
        public IReadOnlyList<Item> GetAllItems() => _items.AsReadOnly();
    }

    /// <summary>
    /// 库存系统
    /// </summary>
    public class InventorySystem : AbstractSystem
    {
        private InventoryModel _inventoryModel;

        protected override void OnInit()
        {
            _inventoryModel = this.GetModel<InventoryModel>();
            Console.WriteLine("库存系统初始化完成");
        }

        /// <summary>
        /// 使用物品
        /// </summary>
        public void UseItem(string itemId)
        {
            var items = _inventoryModel.GetAllItems();
            var item = items.FirstOrDefault(i => i.Id == itemId);

            if (item == null)
            {
                Console.WriteLine($"物品不存在: {itemId}");
                return;
            }

            Console.WriteLine($"使用物品: {item.Name}");

            // 根据物品类型执行不同逻辑
            switch (item.Type)
            {
                case ItemType.Consumable:
                    UseConsumable(item);
                    break;
                case ItemType.Weapon:
                    EquipWeapon(item);
                    break;
                default:
                    Console.WriteLine($"无法使用该类型的物品: {item.Type}");
                    break;
            }
        }

        private void UseConsumable(Item item)
        {
            Console.WriteLine($"消耗物品: {item.Name}");
            _inventoryModel.RemoveItem(item.Id, 1);
        }

        private void EquipWeapon(Item item)
        {
            Console.WriteLine($"装备武器: {item.Name}");
        }
    }
}

步骤 4: 依赖管理

使用 IoC 容器管理依赖关系,实现松耦合设计。

4.1 注册服务

using GFramework.Core.architecture;
using GFramework.Core.Abstractions.architecture;
using GFramework.Core.ioc;
using MyGame.Modules.PlayerModule;
using MyGame.Modules.CombatModule;
using MyGame.Modules.InventoryModule;

namespace MyGame.Core.Architecture
{
    /// <summary>
    /// 游戏主架构(完整版)
    /// </summary>
    public class GameArchitecture : Architecture
    {
        public static IArchitecture Interface { get; private set; }

        protected override void Init()
        {
            Interface = this;

            Console.WriteLine("=== 初始化游戏架构 ===");

            // 注册核心服务
            RegisterCoreServices();
        }

        protected override void InstallModules()
        {
            Console.WriteLine("\n=== 安装功能模块 ===");

            // 按依赖顺序安装模块
            InstallModule(new PlayerModule());      // 基础模块
            InstallModule(new InventoryModule());   // 依赖玩家模块
            InstallModule(new CombatModule());      // 依赖玩家模块
            InstallModule(new QuestModule());       // 依赖多个模块

            Console.WriteLine("\n=== 所有模块安装完成 ===");
        }

        /// <summary>
        /// 注册核心服务
        /// </summary>
        private void RegisterCoreServices()
        {
            // 注册日志服务
            var loggerFactory = new ConsoleLoggerFactory();
            RegisterService<ILoggerFactory>(loggerFactory);

            // 注册配置服务
            var configManager = new ConfigurationManager();
            RegisterService<IConfigurationManager>(configManager);

            // 注册资源管理器
            var resourceManager = new ResourceManager();
            RegisterService<IResourceManager>(resourceManager);

            Console.WriteLine("核心服务注册完成");
        }
    }

    // 简化的服务实现示例
    public interface ILoggerFactory { }
    public class ConsoleLoggerFactory : ILoggerFactory { }

    public interface IConfigurationManager { }
    public class ConfigurationManager : IConfigurationManager { }

    public interface IResourceManager { }
    public class ResourceManager : IResourceManager { }
}

4.2 创建任务模块(展示模块间依赖)

using GFramework.Core.Abstractions.architecture;
using GFramework.Core.model;
using GFramework.Core.system;
using MyGame.Domain.Models.Player;
using MyGame.Modules.InventoryModule;

namespace MyGame.Modules.QuestModule
{
    /// <summary>
    /// 任务功能模块
    /// </summary>
    public class QuestModule : IArchitectureModule
    {
        public string Name => "QuestModule";
        public string Version => "1.0.0";

        public void Install(IArchitecture architecture)
        {
            Console.WriteLine($"安装模块: {Name} v{Version}");

            // 注册任务模型和系统
            architecture.RegisterModel(new QuestModel());
            architecture.RegisterSystem(new QuestSystem());

            Console.WriteLine($"模块 {Name} 安装完成");
        }

        public void Uninstall(IArchitecture architecture)
        {
            Console.WriteLine($"卸载模块: {Name}");
        }
    }

    /// <summary>
    /// 任务数据
    /// </summary>
    public class Quest
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public bool IsCompleted { get; set; }
        public int RewardExp { get; set; }
        public int RewardGold { get; set; }
    }

    /// <summary>
    /// 任务模型
    /// </summary>
    public class QuestModel : AbstractModel
    {
        private readonly List<Quest> _activeQuests = new();
        private readonly List<Quest> _completedQuests = new();

        protected override void OnInit()
        {
            Console.WriteLine("任务模型初始化完成");
        }

        public void AddQuest(Quest quest)
        {
            _activeQuests.Add(quest);
            Console.WriteLine($"接受任务: {quest.Name}");
        }

        public void CompleteQuest(int questId)
        {
            var quest = _activeQuests.FirstOrDefault(q => q.Id == questId);
            if (quest != null)
            {
                quest.IsCompleted = true;
                _activeQuests.Remove(quest);
                _completedQuests.Add(quest);
                Console.WriteLine($"完成任务: {quest.Name}");
            }
        }

        public IReadOnlyList<Quest> GetActiveQuests() => _activeQuests.AsReadOnly();
    }

    /// <summary>
    /// 任务系统(依赖多个模块)
    /// </summary>
    public class QuestSystem : AbstractSystem
    {
        private QuestModel _questModel;
        private PlayerModel _playerModel;
        private InventoryModel _inventoryModel;

        protected override void OnInit()
        {
            // 获取依赖的模型
            _questModel = this.GetModel<QuestModel>();
            _playerModel = this.GetModel<PlayerModel>();
            _inventoryModel = this.GetModel<InventoryModel>();

            Console.WriteLine("任务系统初始化完成");
        }

        /// <summary>
        /// 完成任务并发放奖励
        /// </summary>
        public void CompleteQuest(int questId)
        {
            var quest = _questModel.GetActiveQuests()
                .FirstOrDefault(q => q.Id == questId);

            if (quest == null)
            {
                Console.WriteLine($"任务不存在: {questId}");
                return;
            }

            // 标记任务完成
            _questModel.CompleteQuest(questId);

            // 发放奖励
            GiveRewards(quest);
        }

        private void GiveRewards(Quest quest)
        {
            Console.WriteLine($"\n=== 任务奖励 ===");

            // 经验奖励
            if (quest.RewardExp > 0)
            {
                _playerModel.GainExperience(quest.RewardExp);
                Console.WriteLine($"获得经验: {quest.RewardExp}");
            }

            // 金币奖励
            if (quest.RewardGold > 0)
            {
                _inventoryModel.Gold.Value += quest.RewardGold;
                Console.WriteLine($"获得金币: {quest.RewardGold}");
            }

            Console.WriteLine("=================\n");
        }
    }
}

步骤 5: 代码组织

建立清晰的代码组织规范,提高代码可读性和可维护性。

5.1 命名规范

namespace MyGame.Core.Constants
{
    /// <summary>
    /// 游戏常量定义
    /// </summary>
    public static class GameConstants
    {
        // 游戏配置
        public const string GameName = "MyLargeGame";
        public const string GameVersion = "1.0.0";

        // 玩家配置
        public const int DefaultPlayerLevel = 1;
        public const int MaxPlayerLevel = 100;
        public const int DefaultHealth = 100;
        public const int DefaultMana = 50;

        // 库存配置
        public const int DefaultInventorySlots = 50;
        public const int MaxInventorySlots = 200;

        // 战斗配置
        public const float BaseDamageMultiplier = 1.0f;
        public const float CriticalDamageMultiplier = 2.0f;
    }

    /// <summary>
    /// 层级常量
    /// </summary>
    public static class LayerConstants
    {
        public const string PlayerLayer = "Player";
        public const string EnemyLayer = "Enemy";
        public const string EnvironmentLayer = "Environment";
        public const string UILayer = "UI";
    }

    /// <summary>
    /// 事件名称常量
    /// </summary>
    public static class EventNames
    {
        public const string PlayerLevelUp = "Player.LevelUp";
        public const string PlayerDeath = "Player.Death";
        public const string QuestCompleted = "Quest.Completed";
        public const string ItemAcquired = "Item.Acquired";
    }
}

5.2 文件组织规范

// 文件: PlayerModel.cs
// 位置: MyGame.Domain/Models/Player/PlayerModel.cs

using GFramework.Core.model;
using GFramework.Core.property;

namespace MyGame.Domain.Models.Player
{
    /// <summary>
    /// 玩家数据模型
    /// 职责: 管理玩家的核心数据和状态
    /// </summary>
    /// <remarks>
    /// 该模型包含:
    /// - 基础属性(名称、等级、经验)
    /// - 战斗属性(生命值、法力值)
    /// - 位置信息
    /// </remarks>
    public class PlayerModel : AbstractModel
    {
        #region Properties

        // 基础属性
        public BindableProperty<string> Name { get; } = new("Player");
        public BindableProperty<int> Level { get; } = new(1);
        public BindableProperty<int> Experience { get; } = new(0);

        // 战斗属性
        public BindableProperty<int> Health { get; } = new(100);
        public BindableProperty<int> MaxHealth { get; } = new(100);

        #endregion

        #region Lifecycle

        protected override void OnInit()
        {
            RegisterEventHandlers();
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// 受到伤害
        /// </summary>
        /// <param name="damage">伤害值</param>
        public void TakeDamage(int damage)
        {
            Health.Value = Math.Max(0, Health.Value - damage);
        }

        #endregion

        #region Private Methods

        private void RegisterEventHandlers()
        {
            Level.Register(OnLevelChanged);
        }

        private void OnLevelChanged(int newLevel)
        {
            Console.WriteLine($"玩家升级到 {newLevel} 级");
        }

        #endregion
    }
}

5.3 扩展方法组织

using GFramework.Core.Abstractions.architecture;
using MyGame.Domain.Models.Player;

namespace MyGame.Core.Extensions
{
    /// <summary>
    /// 游戏扩展方法
    /// </summary>
    public static class GameExtensions
    {
        /// <summary>
        /// 获取玩家模型(快捷方法)
        /// </summary>
        public static PlayerModel GetPlayerModel(this IArchitecture architecture)
        {
            return architecture.GetModel<PlayerModel>();
        }

        /// <summary>
        /// 检查玩家是否存活
        /// </summary>
        public static bool IsPlayerAlive(this IArchitecture architecture)
        {
            var player = architecture.GetPlayerModel();
            return player.Health.Value > 0;
        }

        /// <summary>
        /// 获取玩家位置
        /// </summary>
        public static (float x, float y, float z) GetPlayerPosition(this IArchitecture architecture)
        {
            var player = architecture.GetPlayerModel();
            return (player.PositionX.Value, player.PositionY.Value, player.PositionZ.Value);
        }
    }

    /// <summary>
    /// 玩家模型扩展方法
    /// </summary>
    public static class PlayerModelExtensions
    {
        /// <summary>
        /// 检查是否满血
        /// </summary>
        public static bool IsFullHealth(this PlayerModel player)
        {
            return player.Health.Value == player.MaxHealth.Value;
        }

        /// <summary>
        /// 获取生命值百分比
        /// </summary>
        public static float GetHealthPercentage(this PlayerModel player)
        {
            return (float)player.Health.Value / player.MaxHealth.Value;
        }

        /// <summary>
        /// 检查是否低血量
        /// </summary>
        public static bool IsLowHealth(this PlayerModel player, float threshold = 0.3f)
        {
            return player.GetHealthPercentage() < threshold;
        }
    }
}

步骤 6: 团队协作

建立团队协作规范,确保代码质量和开发效率。

6.1 代码审查清单

创建代码审查清单文档:

# 代码审查清单

## 架构设计
- [ ] 组件是否放在正确的层级(Core/Domain/Application/Infrastructure/Presentation)
- [ ] 是否遵循单一职责原则
- [ ] 依赖关系是否合理(避免循环依赖)
- [ ] 是否正确使用了模块化设计

## 代码质量
- [ ] 命名是否清晰且符合规范
- [ ] 是否有适当的注释和文档
- [ ] 是否有单元测试覆盖
- [ ] 是否处理了异常情况

## GFramework 使用
- [ ] 是否正确继承了基类(AbstractModel/AbstractSystem等)
- [ ] 是否正确使用了生命周期方法(OnInit/OnDestroy)
- [ ] 是否正确使用了依赖注入(GetModel/GetSystem/GetService)
- [ ] 事件是否正确注册和注销

## 性能考虑
- [ ] 是否避免了不必要的对象创建
- [ ] 是否正确使用了对象池
- [ ] 是否避免了频繁的 GC 分配
- [ ] 协程使用是否合理

## 可维护性
- [ ] 代码是否易于理解和修改
- [ ] 是否有适当的日志记录
- [ ] 配置是否可外部化
- [ ] 是否便于测试

6.2 Git 工作流

# 功能分支命名规范
feature/player-system      # 新功能
bugfix/inventory-crash      # Bug 修复
refactor/combat-module      # 重构
docs/api-documentation      # 文档更新

# 提交信息规范
feat: 添加玩家升级系统
fix: 修复库存物品重复添加的问题
refactor: 重构战斗系统的伤害计算
docs: 更新架构设计文档
test: 添加玩家系统单元测试
chore: 更新依赖包版本

6.3 项目配置文件

创建 .editorconfig 统一代码风格:

# EditorConfig is awesome: https://EditorConfig.org

root = true

[*]
charset = utf-8
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true

[*.cs]
# 命名规则
dotnet_naming_rule.interfaces_should_be_prefixed_with_i.severity = warning
dotnet_naming_rule.interfaces_should_be_prefixed_with_i.symbols = interface
dotnet_naming_rule.interfaces_should_be_prefixed_with_i.style = begins_with_i

# 代码风格
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true

[*.md]
trim_trailing_whitespace = false

完整代码

Program.cs - 主程序

using MyGame.Core.Architecture;
using MyGame.Application.Systems.Player;
using MyGame.Modules.InventoryModule;
using MyGame.Modules.QuestModule;
using MyGame.Core.Extensions;

namespace MyGame
{
    class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine("=== 大型游戏项目示例 ===\n");

            // 1. 初始化架构
            var architecture = new GameArchitecture();
            architecture.Initialize();
            await architecture.WaitUntilReadyAsync();

            Console.WriteLine("\n=== 架构初始化完成 ===\n");

            // 2. 测试玩家系统
            await TestPlayerSystem(architecture);

            // 3. 测试库存系统
            await TestInventorySystem(architecture);

            // 4. 测试任务系统
            await TestQuestSystem(architecture);

            // 5. 测试模块协作
            await TestModuleIntegration(architecture);

            Console.WriteLine("\n=== 测试完成 ===");
        }

        static async Task TestPlayerSystem(GameArchitecture architecture)
        {
            Console.WriteLine("\n--- 测试玩家系统 ---");

            var playerSystem = architecture.GetSystem<PlayerSystem>();
            var playerModel = architecture.GetPlayerModel();

            // 移动玩家
            playerSystem.MovePlayer(10, 0, 5);
            Console.WriteLine($"玩家位置: {architecture.GetPlayerPosition()}");

            // 受到伤害
            playerModel.TakeDamage(30);
            Console.WriteLine($"当前生命值: {playerModel.Health.Value}/{playerModel.MaxHealth.Value}");

            // 治疗
            playerSystem.HealPlayer(20);
            Console.WriteLine($"治疗后生命值: {playerModel.Health.Value}/{playerModel.MaxHealth.Value}");

            // 获得经验
            playerModel.GainExperience(150);

            await Task.Delay(500);
        }

        static async Task TestInventorySystem(GameArchitecture architecture)
        {
            Console.WriteLine("\n--- 测试库存系统 ---");

            var inventoryModel = architecture.GetModel<InventoryModel>();
            var inventorySystem = architecture.GetSystem<InventorySystem>();

            // 添加物品
            inventoryModel.AddItem(new Item
            {
                Id = "potion_health",
                Name = "生命药水",
                Description = "恢复 50 点生命值",
                Quantity = 5,
                Type = ItemType.Consumable
            });

            inventoryModel.AddItem(new Item
            {
                Id = "sword_iron",
                Name = "铁剑",
                Description = "基础武器",
                Quantity = 1,
                Type = ItemType.Weapon
            });

            // 显示库存
            var items = inventoryModel.GetAllItems();
            Console.WriteLine($"\n当前库存 ({items.Count}/{inventoryModel.MaxSlots.Value}):");
            foreach (var item in items)
            {
                Console.WriteLine($"  - {item.Name} x{item.Quantity} ({item.Type})");
            }

            // 使用物品
            inventorySystem.UseItem("potion_health");

            await Task.Delay(500);
        }

        static async Task TestQuestSystem(GameArchitecture architecture)
        {
            Console.WriteLine("\n--- 测试任务系统 ---");

            var questModel = architecture.GetModel<QuestModel>();
            var questSystem = architecture.GetSystem<QuestSystem>();

            // 添加任务
            questModel.AddQuest(new Quest
            {
                Id = 1,
                Name = "击败史莱姆",
                Description = "击败 10 只史莱姆",
                RewardExp = 100,
                RewardGold = 50
            });

            // 显示活动任务
            var activeQuests = questModel.GetActiveQuests();
            Console.WriteLine($"\n活动任务 ({activeQuests.Count}):");
            foreach (var quest in activeQuests)
            {
                Console.WriteLine($"  - {quest.Name}: {quest.Description}");
            }

            // 完成任务
            await Task.Delay(1000);
            questSystem.CompleteQuest(1);

            await Task.Delay(500);
        }

        static async Task TestModuleIntegration(GameArchitecture architecture)
        {
            Console.WriteLine("\n--- 测试模块协作 ---");

            var playerModel = architecture.GetPlayerModel();
            var inventoryModel = architecture.GetModel<InventoryModel>();

            Console.WriteLine($"\n玩家状态:");
            Console.WriteLine($"  等级: {playerModel.Level.Value}");
            Console.WriteLine($"  经验: {playerModel.Experience.Value}");
            Console.WriteLine($"  生命值: {playerModel.Health.Value}/{playerModel.MaxHealth.Value}");
            Console.WriteLine($"  金币: {inventoryModel.Gold.Value}");
            Console.WriteLine($"  库存物品: {inventoryModel.GetAllItems().Count}");

            // 检查玩家状态
            if (architecture.IsPlayerAlive())
            {
                Console.WriteLine("\n玩家状态: 存活");

                if (playerModel.IsLowHealth())
                {
                    Console.WriteLine("警告: 生命值过低!");
                }
            }

            await Task.Delay(500);
        }
    }
}

运行结果

运行程序后,你将看到类似以下的输出:

=== 大型游戏项目示例 ===

=== 初始化游戏架构 ===
初始化游戏架构...
核心服务注册完成

=== 安装功能模块 ===
安装模块: PlayerModule v1.0.0
玩家模型初始化: Player
玩家系统初始化完成
等级系统: 玩家达到 1 级
重新计算 1 级的属性
模块 PlayerModule 安装完成

安装模块: InventoryModule v1.0.0
库存模型初始化完成
库存系统初始化完成
模块 InventoryModule 安装完成

安装模块: CombatModule v1.0.0
战斗系统初始化完成
技能系统初始化完成
伤害计算系统初始化完成
模块 CombatModule 安装完成

安装模块: QuestModule v1.0.0
任务模型初始化完成
任务系统初始化完成
模块 QuestModule 安装完成

=== 所有模块安装完成 ===

=== 架构初始化完成 ===

--- 测试玩家系统 ---
玩家移动到 (10, 0, 5)
玩家位置: (10, 0, 5)
当前生命值: 70/100
玩家恢复 20 点生命值
治疗后生命值: 90/100
玩家升级到 2 级
等级系统: 玩家达到 2 级
重新计算 2 级的属性

--- 测试库存系统 ---
添加物品: 生命药水 x5
添加物品: 铁剑 x1

当前库存 (2/50):
  - 生命药水 x5 (Consumable)
  - 铁剑 x1 (Weapon)

使用物品: 生命药水
消耗物品: 生命药水
移除物品: 生命药水 x1

--- 测试任务系统 ---
接受任务: 击败史莱姆

活动任务 (1):
  - 击败史莱姆: 击败 10 只史莱姆

完成任务: 击败史莱姆

=== 任务奖励 ===
玩家升级到 3 级
等级系统: 玩家达到 3 级
重新计算 3 级的属性
获得经验: 100
获得金币: 50
=================

--- 测试模块协作 ---

玩家状态:
  等级: 3
  经验: 50
  生命值: 110/110
  金币: 50
  库存物品: 2

玩家状态: 存活

=== 测试完成 ===

验证步骤:

  1. 架构正确初始化,所有模块按顺序加载
  2. 各模块功能正常工作
  3. 模块间依赖关系正确
  4. 事件系统正常触发
  5. 数据在模块间正确共享

下一步

恭喜!你已经掌握了大型项目的组织方法。接下来可以学习:

相关文档