在阅读Chromium源码过程中,主要看的是公司自研的部分,不能对外分享。在自研部分中,用到了很多设计模式。
比如:js注册监听函数,底层发现登录状态发生变化,产生登录或退登事件,事件从底层传到js层,就主要用到了观察者模式、代理模式、桥接模式、命令模式等。
下面内容是通过询问AI生成的文本,在此做个记录。
一、创建型设计模式
-
工厂模式(Factory Method)
- 用途:定义一个创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
- 场景:在Chromium中,工厂模式常用于创建特定环境下的浏览器组件,如不同操作系统上的窗口管理器。例如,
BrowserView
类就是一个工厂,它根据当前运行的操作系统实例化相应的BrowserView
子类。
-
抽象工厂模式(Abstract Factory)
- 用途:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
- 场景:在渲染引擎的构建中,可能需要一组相关的资源,如字体、图像解码器等,抽象工厂模式可以创建这些资源的一致集合。
-
单例模式(Singleton)
- 用途:保证一个类只有一个实例,并提供一个全局访问点。
- 场景:Chromium中的
CommandLine
类是一个典型的单例模式应用,它在整个程序运行期间只存在一个实例,用于获取和解析命令行参数。
-
原型模式(Prototype)
- 用途:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。
- 场景:在DOM操作中,某些元素可能需要大量复制,使用原型模式可以避免重复创建相同的对象属性和方法,提高效率。
-
建造者模式(Builder)
- 用途:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
- 场景:在构建复杂的Web页面时,可以使用建造者模式逐步构造页面的各个部分,如HTML结构、CSS样式和JavaScript脚本。
-
依赖注入(Dependency Injection)
- 用途:不是在类内部创建依赖对象,而是将依赖作为参数传递给类,这样可以增加代码的测试性和灵活性。
- 场景:在Chromium的模块间通信中,依赖注入模式被用来在运行时动态配置服务和接口,比如网络请求模块可以注入不同的HTTP客户端实现。
二、结构型设计模式
-
适配器模式(Adapter)
- 用途:允许不兼容的接口之间可以协同工作,通常是将一个类的接口转换成客户端期望的另一个接口。
- 场景:在Chromium中,为了跨平台兼容,会使用适配器模式来封装不同操作系统API的调用,如文件系统访问、窗口绘制等,确保高层代码可以统一调用而不关心底层实现差异。
-
桥接模式(Bridge)
- 用途:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
- 场景:在渲染引擎中,桥接模式用于隔离渲染逻辑与具体渲染平台的实现,如Skia图形库与OpenGL、DirectX等图形API之间的桥接,使得渲染逻辑可以在不同的图形硬件上运行。
-
组合模式(Composite)
- 用途:将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户可以一致地处理个体对象和组合对象。
- 场景:DOM(Document Object Model)树的实现就是组合模式的一个典型例子,在Chromium中,DOM节点可以是单独的元素节点,也可以是包含多个子节点的复合节点,这种结构便于遍历和操作整个文档。
-
装饰器模式(Decorator)
- 用途:动态地给一个对象添加一些额外的职责,提供比继承更有弹性的替代方案。
- 场景:在Chromium的网络请求模块中,可以通过装饰器模式为请求添加额外的功能,如缓存、日志记录、错误重试等,而不改变原有请求对象的核心行为。
-
外观模式(Facade)
- 用途:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
- 场景:Chromium的BrowserContext提供了对浏览器上下文的一系列操作的统一接口,如管理缓存、Cookie、历史记录等,简化了上层应用对这些功能的调用。
-
享元模式(Flyweight)
- 用途:运用共享技术有效地支持大量细粒度的对象。
- 场景:在渲染大量相似但又略有不同的元素时(如多个按钮),享元模式可以用于存储共享状态(如字体、颜色),减少内存消耗,提高渲染性能。
-
代理模式(Proxy)
- 用途:为其他对象提供一种代理以控制对这个对象的访问。
- 场景:在Chromium的远程过程调用(RPC)中,代理模式用于在网络两端提供本地对象的代理,使得远程对象可以像本地对象一样被调用,隐藏了网络通信的复杂性。
三、行为型设计模式
-
策略模式(Strategy)
- 用途:定义一系列的算法,把它们一个个封装起来,并且使它们可互换。
- 场景:在Chromium的渲染引擎中,不同的渲染策略可以根据设备特性或用户需求动态切换,例如,选择不同的图像压缩算法或布局计算方法,策略模式使得算法可以在运行时选择和替换。
-
模板方法模式(Template Method)
- 用途:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。
- 场景:在Chromium的浏览器生命周期管理中,主循环(Main Loop)的流程框架由基类定义,但具体事件处理逻辑留给派生类实现,这样既保持了流程的统一性,也允许不同类型的浏览器(如Chrome、Chromium)自定义行为。
-
观察者模式(Observer)
- 用途:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
- 场景:DOM事件处理机制就是观察者模式的典型应用,DOM元素作为主题,事件监听器作为观察者,当DOM元素状态变化(如点击事件)时,所有注册的监听器都会被调用。
-
命令模式(Command)
- 用途:将一个请求封装为一个对象,从而使你可用不同的请求把客户端参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
- 场景:在Chromium的编辑操作中,如撤销/重做功能,命令模式将每个编辑动作封装为命令对象,可以存储和恢复,支持复杂操作的历史记录和回滚。
-
迭代器模式(Iterator)
- 用途:提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示。
- 场景:在遍历DOM树或其他容器数据结构时,迭代器模式提供了一种统一的访问方式,而无需了解容器的具体实现细节,这有助于代码的维护和扩展。
-
备忘录模式(Memento)
- 用途:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢复到原先保存的状态。
- 场景:在Chromium的网页导航历史管理中,每个网页的状态(包括URL、标题、表单数据等)都被保存为备忘录对象,当用户前进或后退时,可以从备忘录中恢复网页状态。
-
解释器模式(Interpreter)
- 用途:给定一门语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
- 场景:虽然在现代浏览器中,JavaScript的解析和执行通常由高度优化的虚拟机(如V8)完成,但在某些情况下,如处理特定的配置文件或简单的脚本语言时,解释器模式仍然有用武之地。
-
责任链模式(Chain of Responsibility)
- 用途:使多个处理者对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
- 场景:在Chromium的事件分发机制中,事件从根节点向下传递直到找到匹配的处理者,形成了一个责任链,这样可以灵活地处理事件优先级和捕获/冒泡阶段。
-
状态模式(State)
- 用途:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
- 场景:在Chromium的浏览器标签页(Tab)管理中,一个标签页可能处于加载中、暂停、完成或错误等多种状态。状态模式可以用于封装这些状态及其行为,如响应用户交互、更新UI显示等,使得状态的转换和行为的管理更加清晰和独立。
-
访问者模式(Visitor)
- 用途:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
- 场景:在Chromium的DOM树遍历中,访问者模式可以用于定义多种不同的遍历行为,如查找特定元素、计算布局信息、执行事件处理等,而无需修改DOM元素的原始类。这样可以保持DOM元素类的纯净,同时方便扩展新的遍历逻辑。
- 中介者模式(Mediator)
- 用途:用一个中介对象来封装一系列的对象交互,中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
- 场景:在Chromium的多进程架构中,不同进程间的通信和协调是一个关键问题。中介者模式可以用于封装进程间的通信协议和状态管理,例如,Browser Process作为中介者,管理着Render Process、GPU Process等之间的消息传递和资源共享,减少了进程间的直接依赖,提高了系统的可扩展性和可维护性。
转载请注明来源:https://www.cnblogs.com/bugutian/