ECS 与 OOP 对比示例

ECS 与 OOP 对比示例

原文:https://medium.com/hackernoon/ecs-vs-oop-by-example-daa712b24869

昨天我写了一篇博文解释,什么时候不用 ECS(实体组件系统)。很多人告诉我,尽管这个帖子很有趣,但它非常理论化。所以今天我决定在一个例子上比较用 OOP 风格和 ECS 风格写东西的思维过程。

作为一个例子,我想采取一个登录过程——在你的游戏/应用程序开始之前,用户必须输入用户名和密码,我们将它发送到后端验证,只有这样才可以开始玩/使用应用程序。

首先让我们考虑我在 SDK 团队中,我需要编写一个“模块”,我公司的其他开发人员,甚至其他公司的人都会购买和使用它。在这种情况下,我需要创建一个简单易懂的抽象,它隐藏了复杂性/实现细节。在这种情况下,最好遵循典型的自顶向下的 OOP 方法。我引入了一个LogIn类,它是用户的主界面。在最好的情况下,作为用户,我将实例化LogIn类,在某个时候,它将告诉我用户已成功登录。对我来说,它是一个黑匣子,它将接管 UI、网络、持久数据,并可能给我一些可能性来根据一些特殊需求配置它,但除此之外,它几乎是不透明的。

现在让我们把我当成一名应用程序开发人员。登录过程只是我需要实现的功能之一。在这种情况下,我宁愿遵循 ECS 自下而上的方法,在这种方法中,我开始考虑我将需要的数据。不要忘记,数据不仅仅是应用程序状态,它还是事件和依赖关系。

因此,根据目前的需求,我们可以假设我们将拥有:

  • 用户名
  • 密码
  • 发送凭据事件
  • 用户令牌,我们从后端获取
  • 登录表单呈现器

现在我们可以考虑联网,如果我们已经有了一些联网的基础设施,我们可以重用它。如果没有,我们可以考虑让它成为登录过程系统的一部分,或者构建一个期望联网请求组件的联网系统。这同样适用于持久性。

从逻辑上讲,我们可以有这样的东西:

  • 在系统中显示日志
  • 发送登录系统
  • 持久令牌系统
  • 加载令牌系统
  • 要求检查凭证系统
  • 通知登录成功的系统

由于我们是自下而上地构建这个系统,我们可以灵活地构建它,并且可以测试,绕过登录过程,或者只测试这个过程的一小部分是很容易的。我们不隐藏状态,我们不把抽象的容易理解的东西放在第一位。我们把问题分解成最小的部分,让它在全局状态下工作。然而,这意味着很难找到通用的解决方案。我们可以说:

嗯,我们只是将那些组件和类定义放入一个单独的/可重用的模块中。

但这并不总是那么简单——特别是如果我们的应用程序中有共享的网络组件和系统。此外,它只是一个东西的集合,形成大的东西,用户将需要理解那些小的东西。我们也可以把类似于 OOP LogIn类的东西放在上面,它将聚集/隐藏组件和系统。然后我们有一个面向对象的方法,在它的下面有 ECS。这感觉就像一个科学怪人。我想在某些情况下这样做是可以的,但是我相信坚持一种范式是更好的选择。

说到这里,我才想起自己也曾建造过这样一个弗兰肯斯坦怪物。当我们共享代码进行后端验证时,我们构建了一个无状态的 worker,它接收游戏状态、配置、用户事件,并返回新的游戏状态或一个错误,如果事件不可信,我们认为玩家在作弊。这个无状态的工人是我们后端的一个纯粹的功能。在内部,它基于组件和系统对游戏进行了一次小规模的重新模拟。所以 FP 在外面,ECS 在里面。

这段简短的自我反省强调了我之前的更理论化的博客文章的结论。这完全是一个思考过程。在 FP 中,我会专注于不可变状态和转换它的函数。在 OOP 中,我专注于抽象,定义封装状态和暴露方法的类。在 ECS 中,我专注于解决给定问题所需的组件和系统,将数据表示提升为解决问题的关键,而不是代码。


本站为非盈利网站,作品由网友提供上传,如无意中有侵犯您的版权,请联系删除