组件如何进行多继承实现?

刚才楼上说到rust,其实就是这个概念,粘合代码就是本身的不属于其他接口的实现内容。
struct A {}
impl comp1 for A {组件1}
impl comp2 for A {组件2}
impl A {粘合代码与复合接口}
另外说到rust,mixin其实也是类似的trait实现的概念,只是其他语言里面实现起来需要泛化比较麻烦。

trait我怎么感觉就其他语言的接口类

是的,但是rust 有高效的trait 逻辑继承机制,就是 #[derive(XXX)],一般有需要组合的mixin,都会弄个宏来组合。trait本身也可以有一些方法实现。

mixin
class AwithBwithC_Component extends A<B<C< Component >>>>
rust
#[derive(A,B,C,Component)]
struct AwithBwithC_Component {}

不同组件就是用来实现不同功能的。如果fish2是另一种swim,一般是通过fish2的一些property来区分的,例如速度、角度之类,这会导致swim使用的参数不同,运动的曲线就不同。像你说的swim和swim2这种实现方式实际开发中很少遇到,如果有这种情况,可以对具体的业务继续细化拆分。

面向接口编程,组合优于继承。

PlayerController也做成组件啊,其他的组件实例作为输入

经典!哈哈哈809F731586D11EDDD60FFD0B640E982E

多年前的你,现在已是大神

这样好像也可以理解为组合了,只是实现了接口

只是实现这个功能其实我都会,毕竟多继承这个东西算是开发的基础。
我不懂的是,在cocos的框架下,怎么去优美的实现多继承。

另外,组件化其实我也懂,只是组件化+多继承组合使用,会让我觉得有点奇怪。

怪的点就在于,我是组件A+组件B,但是实际上,这两者并不是互相独立,如果不独立则意味着要进行互动要么会有代码耦合,要么就压根儿不能方便的将这些逻辑抽离为单独的组件

多继承这个不算开发基础吧,这个算语言特性吧,ts是不支持多继承的,而且多继承并不是什么好东西,即便c++支持多继承,也不推荐用,我就只在一个烂项目里见过一次多继承。

参考一下引擎源码里的 eventify,不过还是不建议这么用。


实际上直接声明三个组件,一个出口、一个开关、一个触发器,出口声明依赖触发器和开关组件。
这是最优雅的,不存在拆不开这种情况,就没见过拆不开的。


如果实在想要合并为一个组件,也可以考虑用组件代替 Node(Entity),这样就变成

class Portal extends Component {
  trigger: new Trigger();
  switcher: new Switcher(); 
}

效果也是一样的。


如果你说有其它地方需要单独对开关和触发器进行操作,并且这些操作都要支持炮台。可以声明两个 interface,如

interface SwitcherProvider {
  switcher: Switcher
}
interface TriggerProvider {
  trigger: Trigger
}

然后出口组件

class Portal extends Component implements SwitcherProvider, TriggerProvider {
  trigger: new Trigger();
  switcher: new Switcher(); 
}

然后其他地方对开关和触发器的操作改成对 SwitcherProvider 和 TriggerProvider 的操作。


如果你觉得用 provider 多此一举,直接在组件初始化时将内部的 trigger 和 switcher 往其它地方一注册或者传递也不是不行……


总之这些才是开发的基础,自己灵活处理,Rust 连继承都没有不也用得好好的…… C# 和 Java 都没多继承…… C 这么简陋的语言都能实现 Python 这么灵活的虚拟机…… 别中面向对象的毒太深了

2赞

对,代码层面就像前面说的,在现在组件框架下就是做成组件,但是逻辑概念上又不是组件。所以在逻辑概念层面是不太好的。
其实纯组件框架在概念层面本身就存在一些问题,我们用OOA(面向对象分析)的时候,领域模型里面抽象出来都是实体概念,例如玩家,敌人,子弹,障碍物等。但是在纯组件框架里面实际代码又不是按照这个实体概念组织,而是按照功能拆分。这时候在分析和实现之间就会多一道拆分步骤。而那个PlayerController不仅是粘合,还有提供实体概念的接口的功能。
所以说,实体概念类+功能组合组件。就像UE的那种Actor,是比纯组件框架好的逻辑框架划分。

别中面向对象的毒太深了

事实上,面向对象是一整套完整的链条,从需求分析,领域模型构建,方案设计,代码实现,是一整套完整的流程。也有UML等一套完整的工具。组件式只不过是把继承改成了功能组合,属于面向对象中代码实现的内容,不需要把两者对立起来,也不存在中毒这种说法。
刚才也是说纯组件框架在概念上的问题,也就是领域模型中实体分析和实现上的组件拆分中间有一道(概念->功能)转换,也是需要注意的,会让整个流程稍微别扭,也需要一个实体概念的假组件来包含这个概念,就例如你代码里面那个出口组件。

中毒太深指的是,手中只有锤子,看到什么都觉得是钉子。
并不是说看到钉子不能用锤子。
面向对象的初学者最容易出现的状况就是,什么东西都要抽象成类,但是在复杂的非功能需求面前,往往最后迷失在“到底怎么建模”。

按照实体建模跟按照功能建模,都是开发范式而已,不存在哪个比较别扭的说法。只不过在遇到“多继承”这种常规语言无法支持的特性时,应该灵活处理或者说转换思路罢了。例如在处理大规模数据流时可能会倾向于使用函数式编程,在高度交互的前端应用中使用响应式编程。

如果说到假组件,这只是思路不同而已,单说假不假的话,实际上 OO 里面的三个有继承关系的类跟 EC 里面三个没有继承关系的组件,并没有数量上的差异,自然也不存在真假了。

这个别扭其实体现在从需求到实现上,例如在游戏上,我们看到策划案里面,会写上玩家,敌人,子弹这些内容。按照领域建模来说,策划是领域专家,文档中的这些概念就是实体。一般的OO方法是根据这些实体进行类建模和关系映射。
组件就是你还要去提取实体的共性进行功能拆分,多了一步。组件本身的类,和领域内的概念不是一一对应的。如果完全没有对应概念的组件,假如策划用领域语言再描述一个use case案例,那么不对应的概念会造成一些实现上的考虑,所以需要一个和实体概念对应的组件,就例如PlayerController,Portal这样的概念组件。

编辑:感觉我这几个帖子都是翻来覆去说同一个事情,接下来就不发这个了,重复太多了。