# mythos **Repository Path**: NullPE/mythos ## Basic Information - **Project Name**: mythos - **Description**: 在古希腊语中:Mythos = 叙述 / 讲述出来的故事,是“虚构故事”的意思。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-24 - **Last Updated**: 2026-07-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # mythos — 软件作为可叙事化生成的结构语言 > 在古希腊语中,Mythos(μῦθος)意为"叙述、讲述出来的故事"。 ## mythos 是什么,不是什么 **mythos 不是** 框架、工具库、代码生成器、运行时、或设计模式目录。 **mythos 不是** 一套"世界本体论" —— 它不描述"现实是什么"。Realm 和 Zone 是软件模块的组织概念,不是关于世界的哲学断言。 **mythos 是** 一种**结构语言** —— 它把软件系统的构造和组织方式重写为"可被叙事化生成"的语法。 > 区别:给现有的东西换一套名字,叫**重命名**。让整个系统按一种新的语法被组织出来,叫**结构语言**。 ## 从"命名"到"生成" 传统架构术语是**描述性的** —— 它告诉你某个东西"是什么": - 这是个接口 → 所以它叫 `UserService` - 这是个实现 → 所以它叫 `UserServiceImpl` - 这是个配置 → 所以它叫 `application.yml` - 这是个启动类 → 所以它叫 `Application.java` 这些词只回答了"这是什么",不告诉你"它应该怎么被产生"、"它和其他东西是什么关系"。 mythos 的术语是**生成性的** —— 它不描述"某物是什么",它定义"为了构造一个系统,你需要按什么顺序、什么结构、生成哪些角色": ``` 你从 Canon 开始(定义应当如此的东西)。 你为每个 Canon 创建 Interpretation(解释它)。 你把 Interpretation 通过 Translation 转译成目标 IoC 语言。 你通过 Discourse 点火生成可运行的整体/局部现实。 ``` 这不是"把接口改叫 Canon"。这是**把"先有接口再有实现"这个实践,编码为一种强制性的生成语法**。传统做法允许任何模块在任何位置写任何东西;mythos 的四层结构定义了**模块应该按什么叙事序列被组织出来**。 ## 核心哲学:软件构造的可叙事化 传统软件工程讲究**结构**——分层、模块、依赖。这些结构是**静力学**的:它描述搭建完毕的系统长什么样。 mythos 讲究**叙事**——正典、解释、转译、表达。这是**生成力学**的:它描述一个系统应该按照什么**叙事序列**被构造出来。 | 叙事行动 | 软件构造动作 | 生成的问题 | |---------|------------|----------| | 订立正典 | 定义契约接口 | 应该有什么? | | 解释正典 | 实现接口 | 它怎么做? | | 转译成方言 | 适配到目标 IoC | 它如何被实例化? | | 传道叙事 | 启动运行 | 哪些现实被点燃烧? | 你按照这个叙事序列一步步走,系统就被"讲"了出来。言出法随。 > 注意:这里的"叙事"不是描述世界本体——不是说"现实就是故事"。而是说:**软件系统的构造过程,可以被组织为一种叙事结构的生成过程**。这是方法论的比喻,不是本体论的断言。 --- ## 四层架构 ### Canon(正典)—— 应当如此 定义"是什么"的纯粹契约层。 ``` interface IdGenerator { T generate() } ``` - 只依赖 JDK / Kotlin / Jakarta 等基础技术 - 绝不依赖 Spring、Micronaut 等框架 - 是依赖关系的**最底层**,没有任何模块可以依赖它 - 类比:**创世记**——世界在存在之前,先有法则 ### Interpretation(解释)—— 原来如此 对正典的具体演绎。 ``` class SnowflakeIdGenerator : IdGenerator { override fun generate(): Long { ... } } ``` - **原子性**:可依赖 Apache Commons 级别库,但绝不被 IoC 框架污染 - 一个 Canon 可以有多个 Interpretation(比如 SnowflakeIdGenerator 和 UuidGenerator 都是 IdGenerator 的解释) - 解释本身不关心"谁在用我",它只关心"如何实现正典的要求" - 类比:**解经书**——正典的字句需要被诠释才能被理解 ### Translation(转译)—— 如是我说 将 Interpretation 适配到具体的 IoC 语言。 ``` @Configuration class IdGeneratorTranslation { @Bean fun idGenerator(@Value("\${snowflake.worker-id}") workerId: Long): IdGenerator { return SnowflakeIdGenerator(workerId) } } ``` - 只做胶水工作:Bean 注册、`application.yml` 读取、数据转换 - **不包含任何业务逻辑** - 承担那些"无法写抽象"的基础设施对接(如读取配置文件) - 类比:**翻译圣经**——原文不变,但不同民族用不同语言阅读 ### Discourse(表达)—— 言出法随 决定"用哪个 IoC 语言讲这个故事"的最高层。 ``` // 在 Spring 生态中:引入 Spring Boot Starter // 在 Micronaut 生态中:引入 Micronaut 模块 // 同一个 Canon + Interpretation,用不同"语言"表达 ``` - 通常对应一个**组织或一条业务线** - 一个组织内部一般使用统一的 IoC 语言(Spring 团队用 Spring,Micronaut 团队用 Micronaut) - 表达层决定了一组现实的整体技术选型 - 类比:**传道**——用听众能懂的语言讲述故事,故事才真正存在 ### 依赖原则 四层之间**只能单向依赖**: ``` Canon ← Interpretation ← Translation ← Discourse ``` 允许跨越(Discourse 可以直接依赖 Canon),但不允许逆向。 --- ## 现实的嵌套 ### Realm(整体现实) 多个 Zone 组成的完整功能域。 ``` 教务管理 Realm ├── 字典管理 Zone(引入 zone-sdk-dict) ├── 课程管理 Zone └── 用户管理 Zone(引入 zone-sdk-user) ``` ### Zone(局部现实) 最细粒度的功能模块。 - **一个 Zone 只属于一个 Realm** - Zone 内部可以引入 zone-sdk(预制模块),通过 SPI 注入上下文信息 - Zone 是真正的"写代码的地方" ### Application Starter(点火器) 将一个 Realm 的 Zone 集合点火启动。 ``` 教务管理 Realm ├── HttpApplicationStarter → 对外提供 REST API └── PulseApplicationStarter → 消费消息队列 / 执行定时任务 ``` - **一个 Realm 可以有多个点火器**,每个点火器只加载自己需要的 Zone - 点火器自行决定加载哪些 Zone;如果 Zone 粒度设计不当,甚至可以在启动后丢弃不需要的 Bean - 类比:**讲道者**——同一个经卷,不同的讲道者侧重不同的段落 --- ## zone-sdk:通用经验的打包 ### 不是"层",而是"预制件" zone-sdk 是游走在 Discourse 和 Realm 之间的概念。它不是 Canon,也不是 Interpretation——它是**可跨 Realm 复用的完整功能预制模块**。 ``` zone-sdk-dict/ // 字典管理 ├── spi/ // SPI 接口(留出上下文注入点) │ └── TenantProvider ├── model/ // 数据模型 ├── repository/ // 数据库访问 └── service/ // 业务逻辑 系统管理 Realm ────────► zone-sdk-dict 实现 TenantProvider(从 SecurityContext 提取租户) ``` - zone-sdk 是**有完整技术栈的**(DB 访问、Repository、Service) - 通过 SPI 留出上下文注入点(当前租户、当前用户等) - 多个 Realm 都可以引入同一个 zone-sdk,各自提供不同的 SPI 实现 --- ## 完整示例:雪花序列生成器 ### Canon(正典模块) ```kotlin // canon-id-generator/src/main/kotlin/com/example/canon/IdGenerator.kt interface IdGenerator { fun generate(): T } ``` ### Interpretation(解释模块) ```kotlin // interpretation-snowflake/src/main/kotlin/com/example/interpretation/SnowflakeIdGenerator.kt class SnowflakeIdGenerator( private val workerId: Long, private val datacenterId: Long = 0 ) : IdGenerator { override fun generate(): Long { /* 雪花算法实现 */ } } ``` ### Translation(转译模块) ```kotlin // translation-spring-boot3/src/main/kotlin/com/example/translation/IdGeneratorTranslation.kt @Configuration class IdGeneratorTranslation { @Bean fun snowflakeIdGenerator( @Value("\${snowflake.worker-id}") workerId: Long, @Value("\${snowflake.datacenter-id:0}") datacenterId: Long ): IdGenerator = SnowflakeIdGenerator(workerId, datacenterId) } ``` ### Discourse(表达 / 点火) ```kotlin // discourse-campus/src/main/kotlin/com/example/CampusApplication.kt @SpringBootApplication class CampusApplication fun main() { SpringApplication.run(CampusApplication::class.java) } ``` > 注意:Translation 和 Discourse 与具体 IoC 语言绑定。上例展示的是 Spring Boot 3 场景;换成 Micronaut 时,Translation 层用 Micronaut 注解重写即可,Canon 和 Interpretation 完全不变。 --- ## 如何开始 ### 新项目 按四层结构组织模块: ``` my-project/ ├── canon/ # 纯接口 ├── interpretation/ # 纯实现(无 IoC) ├── translation/ # IoC 适配 └── discourse/ # 启动入口 ``` ### 现有项目 将核心接口抽取为 Canon 模块,将无框架依赖的实现抽为 Interpretation 模块。 ### 团队协作 在对话中使用 mythos 术语: - "这个 Canon 在教务 Realm 里被哪个 Interpretation 解释了?" - "把 Translation 层切到 Micronaut,Canon 和 Interpretation 一行不用改。" - "zone-sdk-dict 缺个 TenantProvider 的 SPI,谁来实现?" --- ## 常见迷思 | 迷思 | 正解 | |------|------| | "Canon 就是接口模块" | Canon 是"应当如此"的哲学概念,接口是它的载体 | | "Interpretation 可以依赖 Spring" | 不可以。Interpretation 必须保持原子性 | | "zone-sdk 是 Canon" | 不是。zone-sdk 是包含实现的预制件,Canon 是纯契约 | | "修改现实 = 配置热更新" | 不。修改现实 = 改源码,重新创世 | | "mythos 有运行时" | 没有。mythos 不提供任何运行时库 | | "mythos 就是给软件换一套名字" | 不是。mythos 定义的是生成性语法——系统按 Canon → Interpretation → Translation → Discourse 的叙事序列被结构性地生成,而非给已有组件贴新标签 | | "mythos 描述世界本体" | 不是。Realm/Zone 是软件模块的组织概念,不构成对"现实本质"的哲学断言 | --- ## 术语速查 | Mythos 术语 | 传统类比 | 本质 | |------------|---------|------| | **Canon**(正典) | 接口 / 契约 | 定义"应该是什么" | | **Interpretation**(解释) | 实现 | 原子性演绎正典 | | **Translation**(转译) | IoC 配置 / 适配层 | 胶水,不含业务 | | **Discourse**(表达) | 应用 / 项目 | 决定用哪个 IoC 语言 | | **Realm**(整体现实) | 业务域 / Bounded Context | Zone 集合 | | **Zone**(局部现实) | 功能模块 | 最小单元,依附于 Realm | | **Application Starter**(点火器) | Main 类 / Runner | 加载 Zone,点火 | | **zone-sdk** | 可复用预制模块 | 含完整实现,SPI 留上下文 | --- > 当你用叙事的概念命名软件,你不再写代码——你在**书写创世记**。