Closed GreyElaina closed 3 years ago
甚至 name
都用的 Metadata...
Protocol
就是各种底层东西的实现,像是 launchEntry, parseMsg, serializeMsg, getRelationship 这些方法全部都由 Protcol 提供,还有一个给 Relationship 用的执行入口 ensureExecution
,用 singledispatch
就可以很好的解决问题了。
a logical realization with seamless migration between platforms, universal development, strong abstraction.
我觉得是时候公开下这个早已为人所知的秘密了。 当 mirai-api-http 更新了 v2 版本后,我因为学业原因迟迟未对 Application 作出适配,但也因此,我也有足够的时间去设计一个新的抽象架构,我对她的期望是 ”能够抽象,统一化所有类型的机器人的开发,且实现平台间的无缝迁移“。
其实这个目标,应该来说,
nonebot
已经完成了,但nonebot
基于的是一种叫session
的抽象(这种抽象甚至只用于一些高级功能),这种抽象仍只能局限于一部分操作(像是accept
,reject
这种感觉像 JS 的 Promise 的奇怪设计),并且若要实现某些特定平台的功能好像只能通过call_api
来解决(如果把协议交给用户,把实现的基类作为type hint
, 就没有提示了),这不是我理想中的架构。不过,
nonebot
仍然是一个优秀的框架,这点不会改变。简述设计
略过思考回路里的一堆关于我怎么想到这个设计的过程,我们现在来看看
Relationship(关系)
。 Avilla 内,这个抽象用于描述个体与个体间的关系,实在义如其名。个体(
Entity
),在一个协议实现中应该有且仅有一个可被用String
类型表示的,可具有多个 元数据(Metadata
) 的抽象,可以用于表示Friend
,Member
及其基类Contact
。群组(
Group
),用于描述多个个体之间共有的一种关系,同样在设计中被视作完整的个体。通常,Relationship 只描述机器人账号与另外一个个体的关系,此时该个体在 Relationship 内被视作 ”主体“,字段名是
ctx
。Relationship 所描述,抽象的关系,是可以操作的,我们将这些操作称为
Execution(执行)
。执行一般分为以下几种,这些种类为执行所具有的主要类型(
Main Type
):Rs
: 对关系本身的操作,也就是包括 ”增加“,”删除“,”更新“ 与 ”获取“,完全就只是 CRUD 操作。RsCtx
: 对主体的操作,这个比较特殊,我还没有很好的概括对主体的操作,现在这个操作应该包括:Mute
: 禁言,但更广泛,因为本质上是拒绝该成员的后继操作,这个操作是可以被限制在一定范围内的,比如可以拒绝他的发言操作,也可以拒绝他的特权操作等。Remove
: 移除,将该主体在群组内的资料被注销。Modify
: 设置一些主体在群组里特有的东西,这个算特权操作,并且这个设计还没定下来。RsMember
: 这个用于在关系内的个体类型为群组时对成员进行操作,这个应该和上面那个有所重合,但仍然有必要,因为确实会出现这种事件。Self
: 对自身的操作,没什么可说的。执行都是实体类,所以可以被实例化。
通常的,执行通过 Relationship 传达到
Protocol
—— 这个部分我们后面再说 ——,除此之外,执行也有这些混入类型(Mixin Type),用于提供特殊的支持(比如 type hint):Result[T]
: 标志该执行会具有个返回值。我先写到这,等会回来谈谈
Protocol
相关。