[Chromium中文文档]跨平台开发的约定与模式

2024-06-08 18:18

本文主要是介绍[Chromium中文文档]跨平台开发的约定与模式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

跨平台开发的约定与模式

转载请注明出处:https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//General_Architecture/Conventions_and_patterns_for_multi-platform_development.html

全书地址

Chromium中文文档 for https://www.chromium.org/developers/design-documents
持续更新ing,欢迎star
gitbook地址:https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//
github地址: https://github.com/ahangchen/Chromium_doc_zh

Chromium是一个巨大而复杂的跨平台产品。我们试图在不同平台间共享尽可能多的代码,同时为每个平台用最合适的方式实现UI和操作系统集成。这提供了一个更好的用户体验,但它给代码增加了额外的复杂度。这个文档描述了保持这种跨平台代码简洁性的推荐实践。

我们使用大量不同带后缀的文件来表示一个文件应该被使用的时机:

  • Mac文件中,低层级文件使用_mac后缀,Cocoa(Mac UI)文件使用_cocoa后缀。
  • iOS文件使用_ios后缀(尽快iOS使用一些特定的_mac文件)。
  • Linux文件中,低层级文件使用_linux后缀,GTK相关文件使用_gtk后缀,X Windows(不使用GTK)特定文件使用_x后缀。
  • Windows文件使用_win后缀。
  • Mac,iOS和Linux共享的Posix文件使用_posix后缀。
  • Chrome view UI相关布局系统文件(在Windows和实验室环境GTK上)使用_views后缀。

独立的浏览器后端文件放在他们自己的目录里:

  • Mac Cocoa: chrome/browser/ui/cocoa
  • Linux GTK: chrome/browser/ui/gtk
  • Windows Views (和实验室GTK-views): chrome/browser/ui/views

编码风格 页面列出一些风格上影响平台相关定义的规则。

如何隔离平台相关代码

小的平台差异: #ifdefs

当你有一个有着许多共享函数或数据成员和些许不同之处的类,在平台相关的部分使用#ifdefs。如果没有显著的差异,这会让每个人将每件事隔离开更加容易。

小的平台差异在头文件处理,大的差异在实现中处理:片段实现

可能有这样的情况,头文件几乎没有差别,部分实现有巨大的实现差异。例如base/waitable_event.h定义了一个通用的有着大量平台差异的API。

有着显著的实现差异,实现文件可以被隔离出来。这可以避免你陷入一个必须在include必要文件中为每个平台写一大堆#ifdef,并且使得追踪源码更容易(三个版本的函数集的代码放在同一个文件里可能令人困惑)。每个平台可以有不同的.cc文件,正如base/waitable_event_posix.cc中实现posix相关函数。如果在这个类里有跨平台的函数,他们应该被丢到一个名为base/waitable_event.cc的函数。

全平台实现和调用器:隔离实现

当抽象层面没有东西实现,就要在每个单独的文件里分别实现类。

如果所有的实现都在跨平台目录中,比如base,他们应该用平台的名字命名,比如base/foo_bar_win.h中的FooBarWin。这种例子通常很少,因为这些跨平台的文件通常设计用于跨平台代码,独立的头文件使得这种例子变得不可能。在一些地方,我们已经在不同的文件里定义了一个普通命名的类,所以PlatformDevice定义在skia/ext/platform_device_win.h, skia/ext/platform_device_linux.h, and skia/ext/platform_device_mac.h。如果你真的需要在跨平台代码里引用这个类,这是OK的。但通常,这种例子会变得遵循下面的这种规则。

如果实现存在于平台相关目录,比如chrome/browser/ui/cocoa或chrome/browser/ui/views,这个类就没有机会用于跨平台代码了。这种情况下,这个类和文件名应该忽略平台的名字,因为它是多余的。所以FooBar是在chrome/browser/ui/cocoa/foo_bar.h中实现的。

不要为每个平台创建不同的类,又把它们用typedef定义为同一个名字。我们曾经在PlatformCanvas上使用这种套路,根据平台,它被typedef为PlatformCanvasMac, PlatformCanvasLinux, 或 PlatformCanvasWin。这样就不可能提前声明这个类,而这是一个减小依赖的重要工具。

什么时候使用抽象的接口

通常,抽象接口与工厂不应该作为隔离平台差异的唯一目的。相反的,它应该用于将接口与优化代码设计的实现隔离开来。这最经常出现在从model中抽离view的实现中,比如TabContentsView或者RenderWidgetHostView。在这些例子里,model不依赖view的实现是有必要的。在许多情况下,多个平台的view只有一个实现,但为将来的开发提供了更干净的隔离与更多的可扩展性。

在有些地方,像TabContentsView,抽象层没有非抽象的、在平台间共享的函数。避免这种写法。如果不同view之间的代码总是一样,它可能首先就不应该在view中。

实现平台相关的UI

通常,从已有的平台相关的用户界面元素构建其他平台相关的用户界面元素。例如,view相关的类BrowserView负责构建许多浏览器对话框盒子。一种方法是,在一个平台无关的接口里包装UI元素,然后通过一个工厂,从一个model构造出它来。这是相当不必要的,因为它让迷乱了归属关系:大多数工厂构造的例子里,UI元素最后归属于创建它的model。然而在许多例子里,UI元素最容易由它所属的UI框架管理。例如,一个views::View归属于它的view层级,并且在包含它的window被销毁时,会自动被销毁。如果有一个对话框 views::View实现了一个平台无关的接口,然后被另一个对象拥有,那么views::View实例现在需要显式地告诉它的view层级不要去干涉它的生命周期。

e.g. 推荐这种写法:

// browser.cc:Browser::ExecuteCommand(..) {...case IDC_COMMAND_EDIT_FOO:window()->ShowFooDialog();break;...
}// browser_window.h:class BrowserWindow {
...virtual void ShowFooDialog() = 0;
...
};// browser_view.cc:BrowserView::ShowFooDialog() {views::Widget::CreateWindow(new FooDialogView)->Show();
}// foo_dialog_view.cc:// FooDialogView和FooDialogController在window被关闭的时候会被自动清理
class FooDialogView : public views::View {...private:scoped_ptr<FooDialogController> controller_; // 跨平台状态控制逻辑...
}

不推荐这种


// browser.cc:Browser::ExecuteCommand(..) {...case IDC_COMMAND_EDIT_FOO: {FooDialogController::instance()->ShowUI();break;}...
}// foo_dialog_controller.h:class FooDialog {public:static FooDialog* CreateFooDialog(FooDialogController* controller);virtual void Show() = 0;virtual void Bar() = 0;
};class FooDialogController {public:...static FooDialogController* instance() {static FooDialogController* instance = NULL;if (!instance)instance = Singleton<FooDialogController>::get();return instance;}...private:...void ShowUI() {if (!dialog_.get())dialog_.reset(FooDialog::CreateFooDialog(this));dialog_->Show();}// 为什么要把FooDialog或者甚至FooDialogController放在外面?// 大多数dialog起始很少被用到scoped_ptr<FooDialog> dialog_;
};// foo_dialog_win.cc:class FooDialogView : public views::View,public FooDialogController {public:...explicit FooDialogView(FooDialogController* controller) {set_parent_owned(false); // Now necessary due to scoped_ptr in FooDialogController.}...
};FooDialog* FooDialog::CreateFooDialog(FooDialogController* controller) {return new FooDialogView(controller);
}

有时候后一种模式是必要的,但这些情况很稀少,并且非常容易被前端的团队所理解。移植的时候,如果UI元素有时候像dialog box一样简单的话,考虑把后一种模式转为前一种。

这篇关于[Chromium中文文档]跨平台开发的约定与模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1042943

相关文章

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

C#实现一键批量合并PDF文档

《C#实现一键批量合并PDF文档》这篇文章主要为大家详细介绍了如何使用C#实现一键批量合并PDF文档功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言效果展示功能实现1、添加文件2、文件分组(书签)3、定义页码范围4、自定义显示5、定义页面尺寸6、PDF批量合并7、其他方法

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

使用Python实现Word文档的自动化对比方案

《使用Python实现Word文档的自动化对比方案》我们经常需要比较两个Word文档的版本差异,无论是合同修订、论文修改还是代码文档更新,人工比对不仅效率低下,还容易遗漏关键改动,下面通过一个实际案例... 目录引言一、使用python-docx库解析文档结构二、使用difflib进行差异比对三、高级对比方

Python自动化处理PDF文档的操作完整指南

《Python自动化处理PDF文档的操作完整指南》在办公自动化中,PDF文档处理是一项常见需求,本文将介绍如何使用Python实现PDF文档的自动化处理,感兴趣的小伙伴可以跟随小编一起学习一下... 目录使用pymupdf读写PDF文件基本概念安装pymupdf提取文本内容提取图像添加水印使用pdfplum

Python从Word文档中提取图片并生成PPT的操作代码

《Python从Word文档中提取图片并生成PPT的操作代码》在日常办公场景中,我们经常需要从Word文档中提取图片,并将这些图片整理到PowerPoint幻灯片中,手动完成这一任务既耗时又容易出错,... 目录引言背景与需求解决方案概述代码解析代码核心逻辑说明总结引言在日常办公场景中,我们经常需要从 W

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

基于Java开发一个极简版敏感词检测工具

《基于Java开发一个极简版敏感词检测工具》这篇文章主要为大家详细介绍了如何基于Java开发一个极简版敏感词检测工具,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录你是否还在为敏感词检测头疼一、极简版Java敏感词检测工具的3大核心优势1.1 优势1:DFA算法驱动,效率提升10