gpt4 book ai didi

面向数据设计中的接口(interface)

转载 作者:行者123 更新时间:2023-12-04 01:49:21 26 4
gpt4 key购买 nike

谚语是这样的:

“编程到接口(interface)/抽象,而不是实现”。

我们都知道接口(interface)是面向对象编程中解耦的一种手段。就像某个对象履行的契约(Contract)一样。

但我无法理解的是:

如何在面向数据的设计中对接口(interface)/抽象进行编程?

就像调用一些“Drawable”一样,但我现在不知道它是矩形还是圆形,但它实现了接口(interface)“Drawable”。

谢谢

最佳答案

这是一个很好的问题。我相信您要问的是如何使用面向数据的设计(DOD)实现多态性?

简短回答:你不用接口(interface)来做。这是一种实现多态性的面向对象编程 (OOP) 方式。在 DOD 中,可以使用实体组件系统 (ECS) 模式来实现多态性。

长答案(带有示例):

以下是 OOP 中的多态性示例:

public interface Drawable
{
void Draw();
}

public class Circle: Drawable
{
public float posX, posY;
public float radius;

public void Draw() { /* Draw Circle */ }
}

public class Rectangle: Drawable
{
public float posX, posY;
public float width, height;

public void Draw() { /* Draw Rectangle */ }
}

以下是使用 DOD 和 ECS(伪代码)实现多态性的方法:
public struct Position { public float x, y; }
public struct Circle { public float radius; }
public struct Rectangle { public float width, height; }

public class DrawCirlceSystem
{
public void OnUpdate()
{
ComponentQuery
.SelectReadOnly(typeof(Position), typeof(Circle))
.ForEachEntity((Entity entity, Position position, Circle circle) => {
/* Draw Circle */
});
}
}

public class DrawRectangleSystem
{
public void OnUpdate()
{
ComponentQuery
.SelectReadOnly(typeof(Position), typeof(Rectangle))
.ForEachEntity((Entity entity, Position position, Rectangle rectangle) => {
/* Draw Rectangle */
});
}
}

因此,如果您有以下数据布局:
Entity 1: [Position, Circle]
Entity 2: [Position, Circle]
Entity 3: [Position, Rectangle]
DrawCircleSystem只会在实体 1 和 2 上执行,而 DrawRectangleSystem只会在实体 3 上执行。因此,多态性是通过这些系统的可查询性实现的。

以这种方式编程比 OOP 更高效。但除此之外,它还使我们的代码更具可扩展性和可优化性。例如,如果您想实现剔除以便仅实际呈现 View 内的实体,我们可以轻松地做到这一点,只需很少的重构工作。我们需要做的就是引入一个新系统,通过添加或删除一个名为 Visible 的新组件来处理剔除。对于我们要绘制的实体:
public struct Visible { }

public class CircleCullingSystem
{
public void OnUpdate()
{
// Give me all Circle entities that are NOT Visible
ComponentQuery
.SelectReadOnly(typeof(Position), typeof(Ciricle))
.Exclude(typeof(Visible))
.ForEachEntity((Entity entity, Position position, Circle circle) => {
// Add 'Visible' component to entity if it's within view range
});

// Give me all Circle entities that are Visible
ComponentQuery
.SelectReadOnly(typeof(Position), typeof(Ciricle))
.FilterBy(typeof(Visible))
.ForEachEntity((Entity entity, Position position, Circle circle) => {
// Remove 'Visible' component from entity if it's out of view range
});

}
}

然后我们只需更新 DrawCirlceSystem 中的查询以便它按 Visible 过滤零件:
public class DrawCirlceSystem
{
public void OnUpdate()
{
// Process all visible circle entities
ComponentQuery
.SelectReadOnly(typeof(Position), typeof(Circle))
.FilterBy(typeof(Visible))
.ForEachEntity((Entity entity, Position position, Circle circle) => {
/* Draw Circle */
});
}
}

当然,我们需要创建一个 RectangleCullingSystem类似于我们的 CircleCullingSystem因为矩形的剔除行为与圆形不同。

关于面向数据设计中的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53977182/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com