开发思想-(数据驱动+组合模式)VS 继承

利用一个需求对比两者,并说明什么是数据驱动?为什么在某些场景下组合优于继承?

一、需求例子

设计消除类游戏的方块,

方块可能有普通方块、不可被移动方块、不可被消除方块、既不能被移动也不能被消除方块、相邻方块消除后消除自己的方块、自己消除后会发射火箭的方块等等,。

二、用接口、继承、多态那一套来做是怎么样

  1. 接口用来规范行为,定义能力

比如:

cs 复制代码
public interface IMovable
{
    bool canMove();
}

那么继承这个接口,实现方法,方法内容是判断方块是否可以被移动。

  1. 实现一个抽象类,实现共享的公共方法和属性
cs 复制代码
public abstract class BaseBlock : IMovable,...其他接口
{
    // 公共属性
    // 比如位置信息、配置信息等等。

    // 实现ICanNotMove方法
    public virtual bool CanMove()
    {
    }

    // ... 其他接口的方法
}
  1. 实现具体的类型方块,通过继承BaseBlock,多态

    public class NormalBlock : BaseBlock
    {
    // 子类自己的特别属性

    复制代码
     //实现自己的逻辑
     public override bool CanMove()
     {
         return true;
     }

    }

    public class CanNotMoveBlock : BaseBlock
    {
    // 子类自己的特别属性

    复制代码
     //实现自己的逻辑
     public override bool CanMove()
     {
         return false;
     }

    }

每需要一个新方块几乎都要创建一个新的子类,子类爆炸。

  1. 移动管理模块,访问方块BaseBlock或者ICanNotMove,判断是否可以移动

    // 移动管理模块
    // 通过方块管理类拿到这个Block
    BaseBlock block = BlockManager.instance.GetBlock(pos);
    bool blockCanMove = block.CanMove();
    if(blockCanMove)
    {
    // 移动逻辑
    }

  2. 阶段总结

我们发现这种开发模式的一个特点,那就是每需要一个新的方块,就需要开发者用代码开发出一个新的方块类,开发新的接口。

也就是说创建新方块类型的操作在程序员这里。

三、利用数据驱动思想,将创建方块的操作从程序员代码创建移交给策划。

  1. 定义配置文件,配置就是数据
cs 复制代码
public class BlockType:ScriptableObject
{
    public int id;
    public string Desc;
    // 基础属性
    public bool canMove = true;
    public bool canClear = true;
    
    // 为了防止属性过多,将大块属性分到各个模块
    public List<BaseBehaviour> behaviours;
}

public abstract class BaseBehaviour : ScriptableObject
{
    // 当被消除调用
    public virtual void OnClearBlock()
    {
    }
}

public class FireRocketBehaviour : BaseBehaviour
{
    public int FireCount = 2;
    // .. 其他属性
    
    public override void  OnClearBlock()
    {
        // 火箭管理系统发射火箭
        FireRocketManager.Fire();
    }
}
  1. 创建一个方块的操作,就交给了和程序无关的人

直接创建这个Scriptobject,填写信息、勾选基础能力、添加模块能力,就组合出了一个新的方块。

方块可以同时拥有配置中的多种能力,这些能力任由策划配置驱使。

  1. 开发做什么?

开发要在游戏逻辑中,实现每个能力的效果和先后顺序。

针对配置的canMove 字段,就要在移动阶段判断,然后做相应操作。

针对配置的canClear字段,就要在消除阶段判断,然后判断是否能将其删除。

程序从既要用代码创建模块还要实现能力->转变为专注地实现能力,创建交给配置和数据。

继承是"类型决定能力",组合是"能力拼出类型"。

有 N 种能力,就能组合出 2^N 种玩法,而不需要创建 2^N 个类。

相关推荐
沉默金鱼7 小时前
Unity实用技能-GM命令
unity·游戏引擎
chillxiaohan8 小时前
unity粗糙、高光、光泽度调节shader记录
unity·游戏引擎
星夜泊客9 小时前
Unity UI 渲染与 Rebuild 机制简易解析
unity·游戏引擎
qiminixi21 小时前
Unity 6000下载
unity·unity 6000·unity 6000下载
CreasyChan1 天前
Unity Shader 入门指南
unity·c#·游戏引擎·shader
漂视数字孪生世界1 天前
Unity团结引擎的前世今生
unity·游戏引擎·数字孪生
仅此,1 天前
Java请求进入Python FastAPI 后,请求体为空,参数不合法
java·spring boot·python·组合模式·fastapi
心前阳光1 天前
Unity通过ScriptableObject学习访问者模式
学习·unity·访问者模式
fcm191 天前
unity之重新导入TMP
unity
心疼你的一切1 天前
【技术创作的璀璨盛宴——2025年CSDN博客之星总评选深度总结】
microsoft·unity·游戏引擎·游戏程序·csdn·博客之星