手写解析器、渲染器、主题样式、自定义弹窗和精细的撤销/恢复机制等。
📌整体总结
YtyMark-java 项目,从用户输入到用户查看到实时渲染结果的全过程

-
监听文本区域内容是否发生变化
-
解析和渲染:"原始文本的块裁剪"→"块级元素解析" → "行内元素解析" → "渲染" 四大阶段
-
将渲染结果重新刷新展示出来
从UI界面到核心的解析渲染,通过一系列设计模式串联各模块,实现了高度的模块化和可扩展性。
构建者模式
用于构造解析器(ParserBuilder
)和渲染器(RendererBuilder
),将复杂对象的组装过程与表示分离,使客户端只需按需配置各组件即可得到完整的解析/渲染器实例。
先从核心模块的这四个阶段来看设计模式的使用情况。
📦1. 原始文本的块裁剪阶段
此阶段为"块级元素预处理"阶段,将普通文本按照块级元素进行裁剪。
状态模式
主要设计模式为状态模式:
在"块级元素预处理"阶段,根据当前处理状态(如普通文本、列表、引用块等)动态切换处理逻辑,将不同类型的文本裁剪成块级元素,避免了大量的条件分支。
通过状态模式实现类似状态机的机制,当状态(语法)匹配时,自动流转到专门处理这个语法的程序,处理完之后分割成一个"块"(这个块就是一个块元素),再回到默认状态,然后继续处理后续的文本。具体代码位于:org.ytymark.parser.block.state
包。

📦2. 块级元素解析阶段
责任链模式
构建一条解析"流水线",不同的责任对象按优先级 依次尝试处理当前文本块或嵌套结构,直到有对象成功解析为止,极大提升了解析流程的灵活性。
组合模式
将解析结果组织成一棵 AST(抽象语法树)块级元素节点树 ,节点既可作为叶子,也可包含子节点,这个阶段标题、段落和水平分割线只能是叶子节点,统一对外提供相同的接口,便于树形结构的构建与遍历。
整个处理流程,如图:

关于涉及的相关代码,可以查看专门简述核心功能那篇文章。
🗂3. 行级元素的解析阶段
策略模式
动态选择不同的行内元素解析策略(例如链接、加粗、斜体等)以及界面的主题渲染策略(浅色/暗黑主题),通过统一接口切换算法或样式实现。
组合模式+迭代器模式
通过迭代器结合递归来遍历节点树 ,为 AST 提供统一的遍历方式。在解析阶段 ,用于遍历块级元素进行行内元素解析;在渲染阶段,遍历节点树完成渲染操作。
使用迭代器完成兄弟节点的遍历(广度遍历),再结合递归完成子节点遍历(深度遍历)。
🧩4. 渲染阶段
中介者模式思想
在 AST、解析器、渲染器之间引入中介逻辑,解耦它们的直接依赖,使得解析和渲染两者可以灵活组合,支持输出到不同类型的文档。

访问者模式
将节点数据结构与渲染行为分离,在块级和行级元素解析和渲染时,访问者对象负责执行相应操作,以解决嵌套调用的复杂性并提高扩展性。在渲染的过程中,组合模式+迭代器模式 起到非常关键的作用,在渲染阶段,使用迭代器完成兄弟节点的遍历(广度遍历),再结合递归完成子节点遍历(深度遍历),完成节点树的渲染操作。

后面介绍以工具界面、操作相关的功能。
📍5. 样式相关功能
工厂模式
在渲染器中,根据不同场景创建对应的样式或渲染器实例,如PDF 等输出的字体、颜色工厂。
观察者模式和单例模式
监听主题(暗黑/浅色)变化或 JavaFX 属性变化,触发重新渲染文本内容,保持 UI 与主题状态同步。主题监听器将有主题管理类 来统一管理,并结合单例模式 ,使得主题管理器全局唯一,并提供统一访问入口ThemeManager.getInstance()
。
🎯6. 自定义弹框
自定义通用弹框,在此基础上根据不同场景进行不同的装饰
装饰模式
对基础弹框组件进行功能性扩展,在不同场景下动态增加或修改对话框行为和样式,而无需改动原有组件代码。
📝7. 编辑操作
命令模式和备忘录模式
将菜单项、工具栏按钮、快捷键等操作封装为命令对象,支持撤销/重做、宏命令等功能的统一管理。以单次输入为粒度保存编辑历史,实现精细化的撤销与重做,支持一千步的撤销/重做,并预留撤销/重做的开启或关闭。
📸8. 界面截图预览
白天模式的截图:

夜间模式的截图:

✏️9. 总结
以上即为 YtyMark-java 项目所用的主要设计模式及其在各个功能模块中的应用场景,既展现了设计模式的实战价值,也为后续扩展与维护打下了坚实基础。
🙌我的开源项目地址
欢迎提交 PR、Issue、Star ⭐️!
如果需要单独学习这些设计模式,可以在微信公众号回复:设计模式,来获取《掌握设计模式:23种经典模式实践、选择、价值与思想》pdf手册。

查看往期设计模式文章的:设计模式